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>
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed Chromium-backed tests failing during suite registration when the shared availability probe was still initializing ([#7384](https://github.com/can1357/oh-my-pi/pull/7384) by [@paralin](https://github.com/paralin)).
|
||||
|
||||
## [17.2.4] - 2026-08-01
|
||||
|
||||
### Added
|
||||
|
||||
@@ -11,7 +11,9 @@ import {
|
||||
} from "@oh-my-pi/pi-coding-agent/tools/browser/registry";
|
||||
import { acquireTab, releaseTab } from "@oh-my-pi/pi-coding-agent/tools/browser/tab-supervisor";
|
||||
import type { Browser, Page, Target } from "puppeteer-core";
|
||||
import { CHROMIUM_AVAILABLE } from "./chromium-probe";
|
||||
import { chromiumAvailable } from "./chromium-probe";
|
||||
|
||||
const CHROMIUM_AVAILABLE = await chromiumAvailable();
|
||||
|
||||
interface FakePageOptions {
|
||||
url: string;
|
||||
|
||||
@@ -3,7 +3,9 @@ import { Settings } from "@oh-my-pi/pi-coding-agent/config/settings";
|
||||
import type { ToolSession } from "@oh-my-pi/pi-coding-agent/sdk";
|
||||
import { BrowserTool } from "@oh-my-pi/pi-coding-agent/tools/browser";
|
||||
import { getTabsMapForTest } from "@oh-my-pi/pi-coding-agent/tools/browser/tab-supervisor";
|
||||
import { CHROMIUM_AVAILABLE } from "./chromium-probe";
|
||||
import { chromiumAvailable } from "./chromium-probe";
|
||||
|
||||
const CHROMIUM_AVAILABLE = await chromiumAvailable();
|
||||
|
||||
function makeSession(): ToolSession {
|
||||
return {
|
||||
|
||||
@@ -17,5 +17,23 @@ async function chromiumCanLaunch(): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
|
||||
/** Gate for tests that launch a real Chromium: `describe.skipIf(!CHROMIUM_AVAILABLE)`. */
|
||||
export const CHROMIUM_AVAILABLE = await chromiumCanLaunch();
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user