Skip to content

ci: retry acceptance tests on CI to absorb runner flake - #819

Merged
bbrala merged 1 commit into
masterfrom
fix/ci-flaky-acceptance-retries
Jul 30, 2026
Merged

ci: retry acceptance tests on CI to absorb runner flake#819
bbrala merged 1 commit into
masterfrom
fix/ci-flaky-acceptance-retries

Conversation

@bbrala

@bbrala bbrala commented Jul 30, 2026

Copy link
Copy Markdown
Member

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:

Run Branch Failing spec Mode
30516706190 master select-in-submenu.js:108 timeout after 35.0s
30516766062 fix/issue-809-context-element nested-triggers-autohide.js:49 page.goto timeout
30516702187 fix/issue-812-xy-overload menu-title-icon-alignment.js:70 page.goto timeout

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:

Test timeout of 30000ms exceeded while running "beforeEach" hook.
Error: page.goto: Test timeout of 30000ms exceeded.
  - navigating to "file:///.../jquery-2.2.4/nested-triggers-autohide.html", waiting until "load"

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

retries: process.env.CI ? 2 : 0,

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.

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.
@bbrala
bbrala merged commit bd51bbd into master Jul 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant