Files
oh-my-pi/packages/coding-agent/test/tools/chromium-probe.ts
T
Christian Stewart 78a4d2ea5a test(browser): stop gating chromium tests on a top-level-await export
`bun test` fails the coding-agent native/unit job with

  ReferenceError: Cannot access 'CHROMIUM_AVAILABLE' before initialization

in test/tools/browser-attach.test.ts and browser-tab-evaluate.test.ts,
taking the job red on every pull request.

chromium-probe.ts initializes its only export with top-level await. When
a test file importing it is the first file the runner loads, the await
settles before that file evaluates and the binding reads fine. When any
other test file was loaded first, the importer's body runs while the
binding is still in its temporal dead zone, and registration throws at
the `skipIf` call. `bun test <one file>` passes and `bun test --parallel=1
<any earlier file> <that file>` fails, which is why the job fails while a
single-file run does not.

Export the memoized probe as a function and let each test file await it
during its own evaluation, which the runner sequences. The probe still
runs once per process and resolves the executable exactly as before.

Signed-off-by: Christian Stewart <christian@aperture.us>
2026-08-02 05:00:26 -07:00

40 lines
1.5 KiB
TypeScript

import { ensureChromiumExecutable } from "@oh-my-pi/pi-coding-agent/tools/browser/launch";
/**
* Whether the Chromium puppeteer resolves can actually execute on this host.
* CI runners without Chrome's system libraries (libnspr4 & co.) hold the
* downloaded binary but cannot exec it — probe with --version and skip
* instead of failing.
*/
async function chromiumCanLaunch(): Promise<boolean> {
try {
const executable = await ensureChromiumExecutable();
if (!executable) return false;
const probe = Bun.spawnSync([executable, "--version"], { stdout: "ignore", stderr: "ignore" });
return probe.exitCode === 0;
} catch {
return false;
}
}
let probe: Promise<boolean> | undefined;
/**
* Gate for tests that launch a real Chromium:
*
* const CHROMIUM_AVAILABLE = await chromiumAvailable();
* describe.skipIf(!CHROMIUM_AVAILABLE)(…);
*
* The result is a promise rather than an awaited `export const`. A module whose
* exports are initialized by top-level await hands the test runner a binding
* that is still in its temporal dead zone when a second test file in the same
* process imports it, and that file dies during registration with "Cannot
* access 'CHROMIUM_AVAILABLE' before initialization". Awaiting in the importer
* makes the wait part of that file's own evaluation, which the runner does
* sequence. The probe runs once per process.
*/
export function chromiumAvailable(): Promise<boolean> {
probe ??= chromiumCanLaunch();
return probe;
}