inspector/scripts/run-engine-smokes.test.mjs
cliffhall 7501dad675 ci: put the Firefox smokes in the pre-push gate instead of GitHub CI
Dropping the CI job left cross-engine checking as something you had to
remember to run, which in practice means nobody runs it. This moves it
into npm run ci, so it happens once per push, in front of a human who can
still reason about the change -- rather than once per CI run, on every
branch, to re-derive an answer we already had.

scripts/run-engine-smokes.mjs is what makes that possible cross-platform:
SMOKE_BROWSER has to reach three child processes, and a POSIX VAR=x npm
run prefix does not work under Windows cmd.exe, which npm uses there.
Setting it in the child env from Node does. smoke:web:firefox passes the
engine as an ARGUMENT rather than relying on the ambient variable, so a
stray SMOKE_BROWSER cannot silently redirect the gate to another engine
-- verified: an explicit argument beats it.

It also gives the smoke list one home. It was previously an && chain in
package.json beside a second chain in the workflow, so adding a fourth
smoke meant remembering both. ENGINE_SMOKES is now the list, with a test
pinning its contents and its order -- a smoke going missing is invisible
at runtime, because a shorter list is still a passing run.

Firefox only. WebKit fails the App smokes for unidentified reasons and
must not be in a gate.

This makes npm run ci a strict superset of GitHub CI rather than a mirror.
That was already true of smoke:tui, which self-skips on CI; Firefox is the
second such step. The direction that matters still holds: passing
npm run ci locally means CI's gates will pass.

Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-26 00:12:55 -04:00

45 lines
1.7 KiB
JavaScript

/**
* The engine-smoke runner's list (#2086).
*
* `ENGINE_SMOKES` is the single home for "which smokes are engine-sensitive",
* and the thing that can silently rot about it is a smoke going missing — the
* suite still passes, just covering less. Nothing at runtime notices, because a
* shorter list is a *successful* run.
*
* Importing the module must not spawn anything; `main()` is behind an entrypoint
* guard, and this test would catch that regressing by running three browser
* smokes the moment the suite imported it.
*/
import assert from "node:assert/strict";
import { existsSync } from "node:fs";
import { join } from "node:path";
import { describe, it } from "node:test";
import { ENGINE_SMOKES } from "./run-engine-smokes.mjs";
const scriptDir = import.meta.dirname;
describe("ENGINE_SMOKES", () => {
it("names every browser-driven smoke, and each one exists", () => {
// Deliberately spelled out rather than derived: this list IS the coverage
// claim, so a test that computed it from disk would agree with any mistake.
assert.deepEqual(ENGINE_SMOKES, [
"smoke-web-browser.mjs",
"smoke-web-app.mjs",
"smoke-web-elicitation.mjs",
]);
for (const smoke of ENGINE_SMOKES) {
assert.ok(
existsSync(join(scriptDir, smoke)),
`${smoke} is listed but missing — a rename would silently shrink the run`,
);
}
});
it("runs the cheapest smoke first", () => {
// smoke-web-browser only boots the bundle; the other two drive a whole App
// flow with 45s waits. Ordering it first is what makes "this engine cannot
// run the bundle at all" fail in seconds rather than after two timeouts.
assert.equal(ENGINE_SMOKES[0], "smoke-web-browser.mjs");
});
});