chore: run format and fix sandbox browser timeouts

This commit is contained in:
Peter Steinberger
2026-01-16 09:18:53 +00:00
parent 7c34883267
commit 4965727f39
32 changed files with 17548 additions and 15412 deletions

View File

@@ -15,9 +15,7 @@ describe("cdp.helpers", () => {
it("adds basic auth headers when credentials are present", () => {
const headers = getHeadersWithAuth("https://user:pass@example.com");
expect(headers.Authorization).toBe(
`Basic ${Buffer.from("user:pass").toString("base64")}`,
);
expect(headers.Authorization).toBe(`Basic ${Buffer.from("user:pass").toString("base64")}`);
});
it("keeps preexisting authorization headers", () => {

View File

@@ -28,15 +28,10 @@ export function isLoopbackHost(host: string) {
);
}
export function getHeadersWithAuth(
url: string,
headers: Record<string, string> = {},
) {
export function getHeadersWithAuth(url: string, headers: Record<string, string> = {}) {
try {
const parsed = new URL(url);
const hasAuthHeader = Object.keys(headers).some(
(key) => key.toLowerCase() === "authorization",
);
const hasAuthHeader = Object.keys(headers).some((key) => key.toLowerCase() === "authorization");
if (hasAuthHeader) return headers;
if (parsed.username || parsed.password) {
const auth = Buffer.from(`${parsed.username}:${parsed.password}`).toString("base64");
@@ -103,18 +98,11 @@ function createCdpSender(ws: WebSocket) {
return { send, closeWithError };
}
export async function fetchJson<T>(
url: string,
timeoutMs = 1500,
init?: RequestInit,
): Promise<T> {
export async function fetchJson<T>(url: string, timeoutMs = 1500, init?: RequestInit): Promise<T> {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const headers = getHeadersWithAuth(
url,
(init?.headers as Record<string, string>) || {},
);
const headers = getHeadersWithAuth(url, (init?.headers as Record<string, string>) || {});
const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return (await res.json()) as T;
@@ -123,18 +111,11 @@ export async function fetchJson<T>(
}
}
export async function fetchOk(
url: string,
timeoutMs = 1500,
init?: RequestInit,
): Promise<void> {
export async function fetchOk(url: string, timeoutMs = 1500, init?: RequestInit): Promise<void> {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const headers = getHeadersWithAuth(
url,
(init?.headers as Record<string, string>) || {},
);
const headers = getHeadersWithAuth(url, (init?.headers as Record<string, string>) || {});
const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
} finally {

View File

@@ -1,9 +1,4 @@
import {
appendCdpPath,
fetchJson,
isLoopbackHost,
withCdpSocket,
} from "./cdp.helpers.js";
import { appendCdpPath, fetchJson, isLoopbackHost, withCdpSocket } from "./cdp.helpers.js";
export { appendCdpPath, fetchJson, fetchOk, getHeadersWithAuth } from "./cdp.helpers.js";

View File

@@ -25,7 +25,9 @@ describe("browser default executable detection", () => {
vi.mocked(execFileSync).mockImplementation((cmd, args) => {
const argsStr = Array.isArray(args) ? args.join(" ") : "";
if (cmd === "/usr/bin/plutil" && argsStr.includes("LSHandlers")) {
return JSON.stringify([{ LSHandlerURLScheme: "http", LSHandlerRoleAll: "com.google.Chrome" }]);
return JSON.stringify([
{ LSHandlerURLScheme: "http", LSHandlerRoleAll: "com.google.Chrome" },
]);
}
if (cmd === "/usr/bin/osascript" && argsStr.includes("path to application id")) {
return "/Applications/Google Chrome.app";
@@ -55,7 +57,9 @@ describe("browser default executable detection", () => {
vi.mocked(execFileSync).mockImplementation((cmd, args) => {
const argsStr = Array.isArray(args) ? args.join(" ") : "";
if (cmd === "/usr/bin/plutil" && argsStr.includes("LSHandlers")) {
return JSON.stringify([{ LSHandlerURLScheme: "http", LSHandlerRoleAll: "com.apple.Safari" }]);
return JSON.stringify([
{ LSHandlerURLScheme: "http", LSHandlerRoleAll: "com.apple.Safari" },
]);
}
return "";
});

View File

@@ -119,7 +119,12 @@ function inferKindFromIdentifier(identifier: string): BrowserExecutable["kind"]
if (id.includes("edge")) return "edge";
if (id.includes("chromium")) return "chromium";
if (id.includes("canary")) return "canary";
if (id.includes("opera") || id.includes("vivaldi") || id.includes("yandex") || id.includes("thebrowser")) {
if (
id.includes("opera") ||
id.includes("vivaldi") ||
id.includes("yandex") ||
id.includes("thebrowser")
) {
return "chromium";
}
return "chrome";
@@ -131,13 +136,12 @@ function inferKindFromExecutableName(name: string): BrowserExecutable["kind"] {
if (lower.includes("edge") || lower.includes("msedge")) return "edge";
if (lower.includes("chromium")) return "chromium";
if (lower.includes("canary") || lower.includes("sxs")) return "canary";
if (lower.includes("opera") || lower.includes("vivaldi") || lower.includes("yandex")) return "chromium";
if (lower.includes("opera") || lower.includes("vivaldi") || lower.includes("yandex"))
return "chromium";
return "chrome";
}
function detectDefaultChromiumExecutable(
platform: NodeJS.Platform,
): BrowserExecutable | null {
function detectDefaultChromiumExecutable(platform: NodeJS.Platform): BrowserExecutable | null {
if (platform === "darwin") return detectDefaultChromiumExecutableMac();
if (platform === "linux") return detectDefaultChromiumExecutableLinux();
if (platform === "win32") return detectDefaultChromiumExecutableWindows();
@@ -227,8 +231,7 @@ function detectDefaultChromiumExecutableLinux(): BrowserExecutable | null {
function detectDefaultChromiumExecutableWindows(): BrowserExecutable | null {
const progId = readWindowsProgId();
const command =
(progId ? readWindowsCommandForProgId(progId) : null) ||
readWindowsCommandForProgId("http");
(progId ? readWindowsCommandForProgId(progId) : null) || readWindowsCommandForProgId("http");
if (!command) return null;
const expanded = expandWindowsEnvVars(command);
const exePath = extractWindowsExecutablePath(expanded);
@@ -285,7 +288,7 @@ function splitExecLine(line: string): string[] {
let quoteChar = "";
for (let i = 0; i < line.length; i += 1) {
const ch = line[i];
if ((ch === "\"" || ch === "'") && (!inQuotes || ch === quoteChar)) {
if ((ch === '"' || ch === "'") && (!inQuotes || ch === quoteChar)) {
if (inQuotes) {
inQuotes = false;
quoteChar = "";
@@ -342,7 +345,7 @@ function readWindowsCommandForProgId(progId: string): string | null {
function expandWindowsEnvVars(value: string): string {
return value.replace(/%([^%]+)%/g, (_match, name) => {
const key = String(name ?? "").trim();
return key ? process.env[key] ?? `%${key}%` : _match;
return key ? (process.env[key] ?? `%${key}%`) : _match;
});
}

View File

@@ -267,9 +267,7 @@ async function connectBrowser(cdpUrl: string): Promise<ConnectedBrowser> {
for (let attempt = 0; attempt < 3; attempt += 1) {
try {
const timeout = 5000 + attempt * 2000;
const wsUrl = await getChromeWebSocketUrl(normalized, timeout).catch(
() => null,
);
const wsUrl = await getChromeWebSocketUrl(normalized, timeout).catch(() => null);
const endpoint = wsUrl ?? normalized;
const headers = getHeadersWithAuth(endpoint);
const browser = await chromium.connectOverCDP(endpoint, { timeout, headers });

View File

@@ -1,11 +1,6 @@
import fs from "node:fs";
import {
appendCdpPath,
createTargetViaCdp,
getHeadersWithAuth,
normalizeCdpWsUrl,
} from "./cdp.js";
import { appendCdpPath, createTargetViaCdp, getHeadersWithAuth, normalizeCdpWsUrl } from "./cdp.js";
import {
isChromeCdpReady,
isChromeReachable,
@@ -55,10 +50,7 @@ async function fetchJson<T>(url: string, timeoutMs = 1500, init?: RequestInit):
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const headers = getHeadersWithAuth(
url,
(init?.headers as Record<string, string>) || {},
);
const headers = getHeadersWithAuth(url, (init?.headers as Record<string, string>) || {});
const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return (await res.json()) as T;
@@ -71,10 +63,7 @@ async function fetchOk(url: string, timeoutMs = 1500, init?: RequestInit): Promi
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), timeoutMs);
try {
const headers = getHeadersWithAuth(
url,
(init?.headers as Record<string, string>) || {},
);
const headers = getHeadersWithAuth(url, (init?.headers as Record<string, string>) || {});
const res = await fetch(url, { ...init, headers, signal: ctrl.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
} finally {