Commit graph inspector/scripts/run-engine-smokes.test.mjs
Author SHA1 Message Date
cliffhall
86c143fd0d docs(smoke): point each smoke's on-demand example at its own command
smoke-web-elicitation.mjs told the reader to run
`SMOKE_BROWSER=webkit npm run smoke:web:app` -- the App smoke, not the
elicitation smoke the file documents. Following it exercises a different
path entirely, and it does not fail while doing so: a real smoke runs and
passes, so nothing signals that you never tested what you were reading
about.

This is a direct cost of my own decision two rounds ago to make the two
App headers word-for-word identical so they could not drift. The shared
PROSE should be identical; the example command is the one line that must
not be, and copy-paste does not distinguish them. Both headers now name
their own smoke, and both point at npm run smoke:web:webkit for all three.

Guarded, since the class is invisible at runtime by construction:
run-engine-smokes.test.mjs now asserts no smoke header tells the reader to
run a sibling's command, and that every `npm run` it does name is a real
script. Both mutation-verified -- restoring the exact bug fails the first,
and naming a nonexistent script fails the second.

Addresses the suppressed comment on Copilot review 5031065042 of #2133.

Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-26 11:00:51 -04:00
cliffhall
93bc7df360 fix(smoke): assert the requested engine is the one launched; fix the remedy
Three findings, all from Copilot's suppressed block.

1. The tests never checked that loadBrowser launches the engine it was
   asked for. The failure-path stand-in rejects identically for every
   engine, so loadBrowser(root, "firefox") could have called
   chromium.launch() and still produced a correctly Firefox-labelled
   error. The smokes could not catch it either: the Firefox gate runs
   after Chromium is already installed, so a mis-dispatched launch would
   SUCCEED and report Firefox coverage that never happened.

   Added a success-path test with distinct per-engine spies asserting the
   requested engine is invoked, that nothing else is, and that its handle
   is what comes back. Mutation-verified: hard-coding playwright.chromium
   fails it.

2. The launch-failure message told the reader to run
   `npx playwright install --with-deps <engine>`, which is wrong now that
   the npm scripts run from the repo root rather than clients/web -- I
   introduced that when I removed the `cd`. Playwright is pinned in
   clients/web, so a bare root-level npx can fetch a different version and
   install a browser revision the pinned one still cannot launch. It now
   points at `npm run smoke:web:<engine>` first, and scopes the raw
   command to clients/web with the reason.

   That message named smoke:web:webkit, which did not exist -- only the
   chromium and firefox scripts did. Added it, and a test asserting every
   supported engine has one, since a remedy nobody can run is worse than
   no remedy. Mutation-verified.

3. AGENTS.md said npm run ci "mirrors" the workflow and then, two
   sentences later, that it is "a superset, not a mirror". It now leads
   with strict superset, which is the topology this PR is documenting.

The README and AGENTS.md remediation wording is corrected the same way as
the runtime message, so a reader gets the same advice wherever they find
it.

Addresses Copilot review 5030668906 on #2133.

Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-26 09:33:21 -04:00
cliffhall
1cebe71761 fix(smoke): route the Chromium tier through ENGINE_SMOKES too
I claimed ENGINE_SMOKES was the single home for "which smokes are
engine-sensitive". It was not: npm run smoke still hard-coded the same
three, so a fourth entry would have reached the Firefox and on-demand runs
and silently skipped the DEFAULT Chromium run -- which is the one GitHub
CI executes. The exact drift the list was introduced to remove, left in
the one tier that matters most.

npm run smoke now ends in smoke:web:chromium, which goes through the
runner like the other two tiers.

Two things fall out of that:

- The Chromium tier passes its engine as a literal argument, so an
  ambient SMOKE_BROWSER can no longer redirect it. Without that,
  SMOKE_BROWSER=firefox npm run ci would have run Firefox twice and never
  exercised Chromium at all -- a gate silently testing something other
  than what it claims.

- run-engine-smokes.test.mjs now asserts that no tier names an individual
  smoke, that both gated tiers name their engine explicitly, and that the
  on-demand entry point is the one that follows the environment. This is
  the durable half: a tier running fewer smokes is invisible at runtime,
  because it still passes. Mutation-verified -- restoring the old hard-
  coded chain fails the test.

Docs updated to state the wider claim rather than the one that was true
of only two tiers.

Addresses the suppressed comment on Copilot review 5026921914 of #2133.

Signed-off-by: cliffhall <cliff@futurescale.com>
2026-08-26 08:55:51 -04:00
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