The acceptance matrix ran with `fullyParallel: true` and no `retries`, so the
Playwright default of 0 applied and any single transient failure took down a
whole matrix row.
That was happening regularly. Three runs in one four-minute window failed on
three different specs, one of them on master, and every failure was a timeout
rather than a failed assertion - twice specifically a `page.goto` that never
finished loading a fixture page within the 30s default:
master select-in-submenu.js:108 timeout after 35.0s
fix/issue-809 nested-triggers-autohide.js:49 page.goto timeout
fix/issue-812 menu-title-icon-alignment.js:70 page.goto timeout
Specs that normally finish in 2-6s were taking 10-23s in those runs, so the
runner was simply oversubscribed. Re-running the failed job passed 9/9 with no
code change.
Retry twice on CI only. Assertions stay exactly as strict, this just stops a
loaded runner from being reported as a broken build. Locally retries would only
mask a genuinely flaky spec, so they stay off there.
Problem
playwright.config.js sets fullyParallel: true but never sets retries, so Playwright's default of 0 applies. A single transient failure therefore takes down a whole matrix row and reports the build as broken.
This is happening regularly. Three runs in one four-minute window failed, on three different specs, one of them on master:
A different spec each time, and every failure is a timeout rather than a failed assertion. Twice it was specifically page.goto never finishing the fixture page load inside the 30s default:
The runner is simply oversubscribed: specs that normally finish in 2-6s were taking 10-23s in those runs, and other tests in the very same file, sharing the same beforeEach, passed. Re-running the failed job on #817 passed 9/9 with no code change at all.
Change
GitHub Actions sets CI=true automatically, so this is 2 on CI and 0 locally. Verified both ways, and --list still discovers all 38 tests in 12 files.
This is not loosening a tolerance. Every assertion stays exactly as strict, and a spec that genuinely fails still fails after three attempts. It only stops a loaded runner from being reported as a broken build. Retries stay off locally, where they would just mask a genuinely flaky spec.
Possible follow-up, deliberately not done here
Capping workers on CI would attack the oversubscription directly rather than absorbing it. That is a bigger tuning decision with a wall-clock cost, so it is left out of this one-line fix.
No changelog entry: internal test tooling, nothing user-facing.