ci: run the bench Playwright suite, so the gates actually gate - #459
Merged
Conversation
…ench.spec
The bench Playwright suite is about to run on a shared runner, where a red
run is not reproducible by hand. `trace: "on-first-retry"` and
`screenshot: "only-on-failure"` cost the passing path nothing and turn a
retry into evidence; the HTML report is what the job uploads.
`bench.spec.ts` cannot take the runner's tracing. It drives
`context.tracing` itself to write the run's trace zip into `status/traces/`
as a benchmark artifact, and a second `tracing.start()` on an
already-traced context throws `Tracing has been already started` — verified
with `--trace=on`, which turned that spec red before this commit. Under
`on-first-retry` that would have made every retry of the spec a guaranteed
failure, so the retry could never recover a genuinely flaky run. The
file-level `test.use({ trace: "off" })` opts it back out, next to the
`tracing.start()` it is about.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`grep -rn bench .github/workflows/` returned nothing. `apps/bench`'s own `test` script is `vitest run --environment jsdom --passWithNoTests`, which collects `src/` — 155 tests in 15 files — and never sees `tests/`. So the 28 Playwright specs in `apps/bench/tests/` ran only when a human ran them, and they are the only proof several shipped features work at all: every eviction gate, the windowed-geometry gate, AG Grid's wrapped auto-height, the row-height-error applicability rule, and the cascade/theming paint assertions. The whole suite runs, on every PR and every push to `main`. It takes 16s at one worker, and the only numeric budget in it — the 32 MB whole-page heap ceiling in `resident-cap-memory.spec.ts` — measures ~12.7 MB, so there is no timing race worth deferring to a schedule. Nothing is excluded. The job builds and serves the bench itself rather than letting the config's `webServer` do it: that command is `preview:bench`, whose `prepreview:bench` hook runs the whole dependency + app build inside the webServer's 30s readiness budget, so a cold runner would read as "server never came up" and a broken build as a timeout rather than a compile error. It is deliberately absent from `deploy-prod`/`deploy-preview`'s `needs:`, matching `dev-smoke` and `smoke-preview`. Those lists gate the website deploy and `apps/bench` is never deployed; adding it there would only mean a browser flake on `main` skips the production deploy. Branch protection is what makes this a gate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
Vercel preview readyPreview: https://pretable-m6ocyf21t-cacheplane.vercel.app Updated automatically by the |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The browser tests that prove eviction works were run by nothing
apps/bench'stestscript isvitest run --environment jsdom, which collectssrc/, nottests/. So the 28 Playwright specs inapps/bench/tests/— the only proof several shipped features work at all, including every eviction gate, the windowed-geometry gate, the AG Grid wrapped auto-height spec and the jsdom wrapped-scale fence — ran only when a human ran them by hand.They were repeatedly described as "gates" during the eviction work. They gated nothing.
The job
bench-e2e— "Bench — Playwright (real Chromium)" — inci.yml, on PRs tomainand pushes tomain.Build the bench, serve
vite previewon 4173 with a readiness loop, runpnpm bench:e2e -- --workers=1withPRETABLE_BENCH_EXTERNAL_SERVER=1, upload the server log andplaywright-report/+test-results/on failure.It deliberately
needs:nothing, and nothing needs it. The deploy jobs'needs:lists gate the website deploy;apps/benchis private and never deployed. Putting it there would mean a browser flake onmainskips the production deploy and strands prod on an older commit — the exact failuredeploy-prod-alarmexists to catch, and one that already happened twice this week.dev-smokeandsmoke-previewsit outside those lists for the same reason.One manual step remains: the check name
Bench — Playwright (real Chromium)must be added to the required checks onmain. Until then the job runs and reports but does not block a merge.Nothing excluded, no PR/main split
The full suite is 28 tests in 16.0s at one worker. The only numeric budget in the directory is
resident-cap-memory.spec.ts's 32 MB whole-page heap ceiling, measuring 12.66 MB — 2.5× under, on heap size rather than wall time. Everything else is layout geometry, DOM structure, or metric shape (bench.spec.tsassertsexpect.any(Number), no timing budgets). Splitting would have cost coverage and bought nothing.--workers=1becauseag-grid-wrap-auto-height.spec.tspolls a 15s settle budget; two workers on a 2-core runner is the only plausible way to race it. Costs ~10s.Explicit build + external server rather than the config's
webServer:enable-pre-post-scriptsis on, soprepreview:benchruns the whole dependency build — 11.74s warm, measured — inside the webServer's 30s readiness budget. On a cold runner that reads as "server never came up", and a broken build reads as a timeout rather than a compile error.A trap found and fixed rather than excluded
Setting Playwright's
traceglobally breaksbench.spec.ts, which drivescontext.tracingby hand to write its trace zip intostatus/traces/:Under
trace: "on-first-retry"that makes every retry of that spec a guaranteed failure, so a retry could never recover a genuinely flaky run. Fixed with a file-leveltest.use({ trace: "off" })— no assertion touched — verified to override even an explicit--trace=on.The workflow also carries a warning against adding
PRETABLE_BENCH_ADAPTER/SCENARIO/SCALE/SCRIPTto the job env:resident-cap-memory.spec.tstest.skips itself when any of the four is set, so a convenience selector would silently drop a test while the job stayed green.Proof the gate actually gates
A CI job that passes because it ran nothing is worse than no job.
Count matches.
--list→Total: 28 tests in 9 files. The job's own command →Running 28 tests using 1 worker→28 passed (15.9s).It cannot pass on an empty collection.
testDirpointed at a nonexistent directory →Error: No tests found/EXIT=1.Break one assertion, then run the exact command the job runs with
CI=1:Restored →
EXIT CODE = 0,28 passed (17.8s). Retries and artifacts both produced trace zips and failure screenshots.Cost
16.0s locally at one worker; ~3–5 min in CI dominated by
pnpm install,playwright installand a cold bench build. Comparable todev-smoke, fully parallel with the other jobs, no added critical path.Adjacent hole, filed not fixed
apps/bench/tsconfig.jsonincludes only["src", "vite.config.ts"]and the lint script iseslint src, so those 9 specs are neither typechecked nor linted — Playwright transpiles with esbuild and never checks types. CI now runs them; nothing checks them.🤖 Generated with Claude Code