Skip to content

test(browser): retry lost popover clicks and raise the per-test timeout - #75

Merged
matej21 merged 4 commits into
mainfrom
test/browser-popover-click-retry
Aug 20, 2026
Merged

test(browser): retry lost popover clicks and raise the per-test timeout#75
matej21 merged 4 commits into
mainfrom
test/browser-popover-click-retry

Conversation

@matej21

@matej21 matej21 commented Aug 19, 2026

Copy link
Copy Markdown
Member

Makes the Browser Tests job green again — all three CI checks pass on this branch. Two test-only commits cherry-picked from experiment/selection-compiler (PR #69) with their original authorship — they will drop out of that branch on its next rebase — plus a timeout fix that turned out to be the actual root cause.

The failure

Since 2026-07-22 the same two tests have failed in CI on every branch, including main. Both drive a popover: open, type to filter, click the first option.

What it is not

  • Not a product regression from the recent merges. Both parents of the merge that first showed it were green, and that merge added only an editor paste fix and its test.
  • Not the unpinned agent-browser upgrade, which was the first hypothesis and looked damning: CI installs it with a bare bun add -g agent-browser, which went 0.31.1 → 0.32.x right around the date the failures start. But on a pristine main locally both tests pass on 0.27.1 and 0.34.0 alike, and the full suite is 66/66. Pinning would have fixed nothing.

The actual root cause

bunfig.toml declares timeout = 15000, and bun ignores that key. Verified directly: a test that sleeps 6s is killed at 5002ms regardless of the value. So the per-test timeout is bun's 5000ms default.

clickUntil retries a lost click up to 3 times with a 3s settle each — a budget of up to 12s for one test. It therefore cannot complete a second retry inside a 5s test: bun kills it mid-attempt, and the assertion reports whatever slice of its own budget was left. That is exactly the CI log's

error: waitFor timed out after 3183ms: () => !el("author-select-save-button").isDisabled
(fail) Article with Author Select > changing author enables save [16287.65ms]

— a waitFor that asked for 10s and got 3.2s, inside a test that had already spent its ceiling retrying.

Locally the first click lands immediately, so the retry budget is never spent and the ceiling is never reached. That is why this reproduced only on a loaded CI runner, where the browser suite shares a container with postgres, an S3 stand-in and the Contember engine.

The fix

  1. wait for the filtered option before clicking, rather than for any button in the dialog — the old selector could match a row from the pre-filter list that is about to be replaced;
  2. clickUntil helper in tests/browser/browser.ts — retries the click until an observable effect appears;
  3. --timeout 30000 on the test:browser script, so the retry budget fits, with a note in bunfig.toml recording that its timeout key is inert so the next person does not trust it;
  4. pin agent-browser to 0.32.4 in the workflow.

No assertion is weakened; the tests still fail if the app stops working.

On the pin — a correction

An earlier revision of this description argued that pinning would be "cargo-culting a fix for a disproven cause", because locally the suite passes on 0.27.1, 0.32.4 and 0.34.0 alike. That conclusion was drawn from the one environment that cannot discriminate.

The CI record can: it went green on 2026-07-22 with clickUntil and 0.32.4, and Article with Author Select still failed with clickUntil against 0.34.0 — twice, plus once more after the timeout fix. So the driver version is load-bearing for that test, and the bare bun add -g agent-browser meant it could change under the suite between two runs of the same commit (0.31.1 early July → 0.32.x mid-July → 0.34.0 since 2026-08-10).

Moving the pin forward is now a deliberate change that has to carry its own CI evidence.

Verification

Locally 66/66. On CI: 66/66, all three checks green — which is the only place this ever reproduced. Progression across runs on this branch: 64 pass / 2 fail → 65 / 1 (clickUntil + timeout) → 66 / 0 (pin).

Note the other half of what was blocking a green suite is a genuine product bug, fixed separately in #76: an embedded has-many was not materialized before isDirty was read or a mutation applied, which is why packages/bindx-form/tests/formRelations.test.tsx was failing on main.

Follow-up worth a separate issue

bun add -g agent-browser is unpinned, so the browser driver can change under the suite between two runs of the same commit. A reproducibility problem regardless of this bug, and not bundled here.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GiniFfaE4gb5EuQpQ3Ncee

matej21 and others added 2 commits August 19, 2026 15:05
…povers

The tests waited only for ANY button in the popover, so on a slow runner
the click could hit the stale pre-filter option list (or a remounting
node) — picking the wrong author / losing the click, then timing out on
the save-button wait. Wait until the first option shows the filtered
text instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013zh1EN87d1Q7urtu7sDRYG
Filtered-option waits didn't fix CI: the click can land on an option node
mid-remount (debounced fetch re-renders the list) and get silently lost.
clickUntil re-clicks until the expected outcome materializes, checking
the condition first so a registered click is never repeated (no
multi-select toggle-off).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013zh1EN87d1Q7urtu7sDRYG
@matej21 matej21 changed the title test(browser): retry lost popover clicks so the suite survives a loaded CI runner test(browser): retry lost popover clicks (fixes 1 of the 2 failing browser tests) Aug 19, 2026
The browser suite drives a real browser through agent-browser, and clickUntil
retries a lost popover click up to 3 times with a 3s settle each — a budget of
up to 12s for one test. bun's per-test timeout is 5s, so the second retry can
never finish: bun kills the test mid-attempt and the assertion reports whatever
slice of its own budget was left. That is the "waitFor timed out after 3183ms"
in CI, where the runner shares a container with postgres, an S3 stand-in and
the Contember engine and the first settle actually elapses. Locally the first
click lands immediately, so the suite passes and the ceiling is never reached.

bunfig.toml already declares timeout = 15000, but bun ignores that key —
verified with a 6s test, killed at 5002ms regardless. Documented there so the
next person does not trust it, and the browser script now passes --timeout on
the command line, which does work.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GiniFfaE4gb5EuQpQ3Ncee
@matej21 matej21 changed the title test(browser): retry lost popover clicks (fixes 1 of the 2 failing browser tests) test(browser): retry lost popover clicks and raise the per-test timeout Aug 19, 2026
The workflow installed the browser driver with a bare `bun add -g agent-browser`,
so it could change under the suite between two runs of the same commit — and it
did: 0.31.1 in early July, 0.32.x from mid-July, 0.34.0 since 2026-08-10.

CI last went green on 2026-07-22 with the clickUntil retry helper and 0.32.4.
The same helper against 0.34.0 still fails `Article with Author Select`, so the
driver version is load-bearing for that test. Locally the suite passes on 0.27.1,
0.32.4 and 0.34.0 alike, which is why this only ever showed up in CI.

Pinning makes the suite reproducible. Moving the pin forward is then a deliberate
change with its own CI evidence, rather than something that happens silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GiniFfaE4gb5EuQpQ3Ncee
@matej21
matej21 merged commit ee36ffa into main Aug 20, 2026
3 checks passed
@matej21
matej21 deleted the test/browser-popover-click-retry branch August 20, 2026 09:26
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