feat: add remote CDP browser support

This commit is contained in:
Peter Steinberger
2026-01-01 22:44:52 +01:00
parent 73d0e2cb81
commit bd8a0a9f8f
21 changed files with 400 additions and 157 deletions

View File

@@ -18,6 +18,31 @@ type CdpSendFn = (
params?: Record<string, unknown>,
) => Promise<unknown>;
function isLoopbackHost(host: string) {
const h = host.trim().toLowerCase();
return (
h === "localhost" ||
h === "127.0.0.1" ||
h === "0.0.0.0" ||
h === "[::1]" ||
h === "::1" ||
h === "[::]" ||
h === "::"
);
}
export function normalizeCdpWsUrl(wsUrl: string, cdpUrl: string): string {
const ws = new URL(wsUrl);
const cdp = new URL(cdpUrl);
if (isLoopbackHost(ws.hostname) && !isLoopbackHost(cdp.hostname)) {
ws.hostname = cdp.hostname;
const cdpPort = cdp.port || (cdp.protocol === "https:" ? "443" : "80");
if (cdpPort) ws.port = cdpPort;
ws.protocol = cdp.protocol === "https:" ? "wss:" : "ws:";
}
return ws.toString();
}
function createCdpSender(ws: WebSocket) {
let nextId = 1;
const pending = new Map<number, Pending>();
@@ -165,14 +190,16 @@ export async function captureScreenshot(opts: {
}
export async function createTargetViaCdp(opts: {
cdpPort: number;
cdpUrl: string;
url: string;
}): Promise<{ targetId: string }> {
const base = opts.cdpUrl.replace(/\/$/, "");
const version = await fetchJson<{ webSocketDebuggerUrl?: string }>(
`http://127.0.0.1:${opts.cdpPort}/json/version`,
`${base}/json/version`,
1500,
);
const wsUrl = String(version?.webSocketDebuggerUrl ?? "").trim();
const wsUrlRaw = String(version?.webSocketDebuggerUrl ?? "").trim();
const wsUrl = wsUrlRaw ? normalizeCdpWsUrl(wsUrlRaw, opts.cdpUrl) : "";
if (!wsUrl) throw new Error("CDP /json/version missing webSocketDebuggerUrl");
return await withCdpSocket(wsUrl, async (send) => {