All nine findings taken. Two budgets I had lowered are restored as named exceptions rather than folded into the shared value. cli's e2e child timer goes back to 15s and the two tests that spawn it get E2E_SPAWN_MS = 25s, so the bound carrying the diagnostic still wins without taking load tolerance off the one suite that spawns a real process. App.test.tsx's three-modal sequence keeps THREE_MODAL_SEQUENCE_MS = 20s — a value chosen against an observed failure, which the shared ceiling would have replaced with a general one. Three real false-positive paths in the guard are closed. It now discovers every Vitest config under clients/ and fails on one it is not configured to check — without which "a project with no row is an error" was vacuous, since an undiscovered config yields no project to reject. It strips comments before looking for configure() and requires the exact expected value, so neither a commented-out call nor asyncUtilTimeout: 1 passes. And it compares each resolved project's setupFiles against the site it claims to configure, so deleting a setupFiles entry can no longer leave both projects reported as configured while Testing Library silently reverts to 1000ms. Each has a test, and the setupFiles check was observed to fire against a real deletion. Three stale comments the change had invalidated: main.yml still counted four durable guards, PreviewAnnotations.stories.tsx still said the storybook project had no setupFiles, and the new AGENTS.md rule read as though no Group F row had been settled when this PR settles F6. browser-timeouts.test.mjs gains the purpose header this repo's files carry. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PsmUAZ6aLUAFqenjJKSSRp Signed-off-by: cliffhall <cliff@futurescale.com>
40 lines
1.8 KiB
JavaScript
40 lines
1.8 KiB
JavaScript
/**
|
|
* Pins the invariants of `browser-timeouts.mjs` — a constants module, so what
|
|
* is testable about it is the shape of the values rather than any logic.
|
|
*
|
|
* Worth pinning anyway, because the values are the module's whole contract and
|
|
* a smoke cannot report a bad one. A budget that arrived as `undefined` or a
|
|
* string reaches Playwright as "no timeout" or NaN and a smoke then hangs
|
|
* against the job's own ceiling rather than failing with a cause. And the
|
|
* ordering below IS the semantics documented on each key: the names say what
|
|
* each budget has to absorb, so a `nested` wait outliving its enclosing
|
|
* `roundTrip` one would mean the names had stopped describing the values.
|
|
*/
|
|
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { BROWSER_TIMEOUTS } from "./browser-timeouts.mjs";
|
|
|
|
test("every budget is a positive finite number of milliseconds", () => {
|
|
const entries = Object.entries(BROWSER_TIMEOUTS);
|
|
assert.ok(entries.length > 0);
|
|
for (const [name, ms] of entries) {
|
|
assert.equal(typeof ms, "number", `${name} is not a number`);
|
|
assert.ok(Number.isFinite(ms) && ms > 0, `${name} is not a usable budget`);
|
|
}
|
|
});
|
|
|
|
test("the object is frozen, so a smoke cannot mutate a shared budget", () => {
|
|
assert.ok(Object.isFrozen(BROWSER_TIMEOUTS));
|
|
});
|
|
|
|
test("the budgets are ordered by what each one has to absorb", () => {
|
|
// Not decoration: the ordering IS the semantics documented on each key. A
|
|
// `nested` wait that outlived its enclosing `roundTrip` one, or a
|
|
// `bestEffort` wait long enough to be felt on every passing run, would mean
|
|
// the names had stopped describing the values.
|
|
assert.ok(BROWSER_TIMEOUTS.bestEffort < BROWSER_TIMEOUTS.nested);
|
|
assert.ok(BROWSER_TIMEOUTS.nested < BROWSER_TIMEOUTS.ui);
|
|
assert.ok(BROWSER_TIMEOUTS.ui < BROWSER_TIMEOUTS.roundTrip);
|
|
});
|