// The Connect window's browser and its launch options (release 16 slice XL). // Pure: nothing here launches a browser. // // Run with: pnpm --filter yt-dlp-transcript-common exec tsx --test social/xBrowser.test.ts import { test, after } from "node:test"; import assert from "node:assert/strict"; import { mkdtempSync } from "node:fs"; import { rm } from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { buildXBrowserLaunchOptions, describeXBrowser, findXBrowser, readXBrowserRecord, recordedXBrowser, writeXBrowserRecord, X_BROWSER_ENV, } from "./xBrowser"; const TMP = mkdtempSync(path.join(os.tmpdir(), "xl-xbrowser-")); after(() => rm(TMP, { recursive: true, force: true })); // A fake filesystem of executables. const only = (...files: string[]) => (p: string) => files.includes(p); test("the system browser: the first of chromium, google-chrome, google-chrome-stable, chrome on PATH", () => { const env = { PATH: "/opt/bin:/usr/bin" }; assert.deepEqual( findXBrowser({ env, isExecutable: only("/usr/bin/google-chrome-stable", "/usr/bin/chromium") }), { kind: "system", executablePath: "/usr/bin/chromium", from: "path" }, ); assert.deepEqual( findXBrowser({ env, isExecutable: only("/usr/bin/chrome", "/opt/bin/google-chrome") }), { kind: "system", executablePath: "/opt/bin/google-chrome", from: "path" }, ); }); test("no system browser: Playwright's bundled build", () => { assert.deepEqual(findXBrowser({ env: { PATH: "/usr/bin" }, isExecutable: only() }), { kind: "bundled", }); assert.deepEqual(findXBrowser({ env: {}, isExecutable: only("/usr/bin/chromium") }), { kind: "bundled", }); }); test("ARCHILYZER_X_BROWSER wins, as a path or a name on PATH", () => { const isExecutable = only("/srv/brave", "/usr/bin/chromium", "/usr/bin/vivaldi"); assert.deepEqual( findXBrowser({ env: { [X_BROWSER_ENV]: "/srv/brave", PATH: "/usr/bin" }, isExecutable }), { kind: "system", executablePath: "/srv/brave", from: "env" }, ); assert.deepEqual( findXBrowser({ env: { [X_BROWSER_ENV]: "vivaldi", PATH: "/usr/bin" }, isExecutable }), { kind: "system", executablePath: "/usr/bin/vivaldi", from: "env" }, ); // A blank override is no override. assert.deepEqual( findXBrowser({ env: { [X_BROWSER_ENV]: " ", PATH: "/usr/bin" }, isExecutable }), { kind: "system", executablePath: "/usr/bin/chromium", from: "path" }, ); }); test("an ARCHILYZER_X_BROWSER that is not an executable refuses — it never opens another browser", () => { const isExecutable = only("/usr/bin/chromium"); assert.throws( () => findXBrowser({ env: { [X_BROWSER_ENV]: "/nope/chrome", PATH: "/usr/bin" }, isExecutable }), /ARCHILYZER_X_BROWSER names "\/nope\/chrome", which is not an executable file\./, ); assert.throws( () => findXBrowser({ env: { [X_BROWSER_ENV]: "edge", PATH: "/usr/bin" }, isExecutable }), /not an executable file on PATH/, ); }); test("the Connect window: the system browser, headed, sandboxed, without the automation signals", () => { const opts = buildXBrowserLaunchOptions({ browser: { kind: "system", executablePath: "/usr/bin/chromium", from: "path" }, headless: false, sandbox: true, }); assert.deepEqual(opts, { headless: false, executablePath: "/usr/bin/chromium", ignoreDefaultArgs: ["--enable-automation"], args: ["--disable-blink-features=AutomationControlled", "--test-type"], chromiumSandbox: true, viewport: { width: 1280, height: 900 }, }); }); test("the bundled build: no executablePath, the same signals dropped", () => { const headed = buildXBrowserLaunchOptions({ browser: { kind: "bundled" }, headless: false, sandbox: true }); assert.equal("executablePath" in headed, false); assert.deepEqual(headed.ignoreDefaultArgs, ["--enable-automation"]); assert.deepEqual(headed.args, ["--disable-blink-features=AutomationControlled", "--test-type"]); assert.equal(headed.chromiumSandbox, true); // The headless refresh: no viewport, Playwright's default sandbox setting. const headless = buildXBrowserLaunchOptions({ browser: { kind: "bundled" }, headless: true }); assert.deepEqual(headless, { headless: true, ignoreDefaultArgs: ["--enable-automation"], args: ["--disable-blink-features=AutomationControlled", "--test-type"], }); }); test("ignoreDefaultArgs names ONLY --enable-automation (never `true`: it would drop --password-store=basic)", () => { for (const browser of [ { kind: "bundled" as const }, { kind: "system" as const, executablePath: "/usr/bin/chromium", from: "path" as const }, ]) { for (const headless of [true, false]) { const o = buildXBrowserLaunchOptions({ browser, headless, sandbox: !headless }); assert.ok(Array.isArray(o.ignoreDefaultArgs)); assert.deepEqual(o.ignoreDefaultArgs, ["--enable-automation"]); } } }); test("describeXBrowser says which browser, and how it was found", () => { assert.match(describeXBrowser({ kind: "bundled" }), /bundled Chromium/); assert.equal( describeXBrowser( { kind: "system", executablePath: "/usr/bin/chromium", from: "path" }, "Chromium 153.0.8010.47 Arch Linux", ), "Chromium 153.0.8010.47 Arch Linux at /usr/bin/chromium (found on PATH)", ); assert.match( describeXBrowser({ kind: "system", executablePath: "/srv/brave", from: "env" }), /^\/srv\/brave \(from ARCHILYZER_X_BROWSER\)$/, ); }); test("the profile records who wrote it, and the refresh's fallback reads it back", async () => { const profile = path.join(TMP, "profile"); assert.equal(await readXBrowserRecord(profile), null); await writeXBrowserRecord( profile, { kind: "system", executablePath: "/usr/bin/chromium", from: "path" }, "Chromium 153", ); const rec = await readXBrowserRecord(profile); assert.equal(rec?.executablePath, "/usr/bin/chromium"); assert.equal(rec?.version, "Chromium 153"); assert.deepEqual(recordedXBrowser(rec, only("/usr/bin/chromium")), { kind: "system", executablePath: "/usr/bin/chromium", from: "recorded", }); // The recorded executable is gone: no fallback. assert.equal(recordedXBrowser(rec, only()), undefined); await writeXBrowserRecord(profile, { kind: "bundled" }); const bundled = await readXBrowserRecord(profile); assert.equal(bundled?.executablePath, null); assert.equal(recordedXBrowser(bundled, only("/usr/bin/chromium")), undefined); });