test(frontend): wait for the first poll tick before jumping the clock in the give-up test (#395) #541

Merged
claude-bot merged 1 commit from fix/395-poll-test-race into main 2026-09-06 21:23:23 +00:00
Contributor

Fixes the flake that failed the merge run for #538 (run 947, WikiDraftReview.test.jsx:491, "stops claiming the draft is generating once it has waited too long").

Root cause, not a timing margin. The test jumps Date.now() ten minutes ahead as soon as renderReview resolves. The poll's deadline is captured in a passive effect (startedAt = Date.now() inside the poll useEffect), and on a loaded runner that effect can flush after renderReview has resolved, because findByText fires on the DOM mutation while passive effects are scheduled behind it. When that ordering happens, the deadline is set at the jumped time, Date.now() - startedAt is never over three minutes, and the give-up banner cannot appear no matter how long the test waits. PR #529 widened the final wait to 20 s, which could never close that gap.

Fix. Wait for one real poll tick (the mock's call count rises) before moving the clock; that proves the interval and its deadline exist. Then the next tick sees the jump. Three consecutive local runs of the file pass; the comment in the test explains the ordering for the next reader.

Only the test file changes.

🤖 Generated with Claude Code

Fixes the flake that failed the merge run for #538 (run 947, `WikiDraftReview.test.jsx:491`, "stops claiming the draft is generating once it has waited too long"). **Root cause, not a timing margin.** The test jumps `Date.now()` ten minutes ahead as soon as `renderReview` resolves. The poll's deadline is captured in a passive effect (`startedAt = Date.now()` inside the poll `useEffect`), and on a loaded runner that effect can flush *after* `renderReview` has resolved, because `findByText` fires on the DOM mutation while passive effects are scheduled behind it. When that ordering happens, the deadline is set at the jumped time, `Date.now() - startedAt` is never over three minutes, and the give-up banner cannot appear no matter how long the test waits. PR #529 widened the final wait to 20 s, which could never close that gap. **Fix.** Wait for one real poll tick (the mock's call count rises) before moving the clock; that proves the interval and its deadline exist. Then the next tick sees the jump. Three consecutive local runs of the file pass; the comment in the test explains the ordering for the next reader. Only the test file changes. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
test(frontend): wait for the first poll tick before jumping the clock in the give-up test (#395)
All checks were successful
CI / Backend lint (ruff) (pull_request) Successful in 26s
CI / Bot/backend version sync (pull_request) Successful in 54s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m37s
CI / Bot tests and audit (pull_request) Successful in 1m46s
CI / Docker image build (pull_request) Successful in 1m24s
CI / Frontend tests, audit, and build (pull_request) Successful in 2m30s
CI / Backend migration, tests, and audit (pull_request) Successful in 10m6s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Successful in 19m36s
4df637ff70
The "stops claiming the draft is generating" test jumped Date.now() ten
minutes ahead as soon as renderReview resolved. The poll's deadline is
captured in a passive effect, which on a loaded runner can flush after that
point, so the deadline itself was set at the jumped time and the give-up
banner could never appear; widening the final wait (PR #529) could not close
that gap, and the test failed again on the merge run for #538.

Wait for one real poll tick first, which proves the deadline exists, then
move the clock. Three consecutive local runs pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude-bot scheduled this pull request to auto merge when all checks succeed 2026-09-06 21:03:25 +00:00
claude-bot deleted branch fix/395-poll-test-race 2026-09-06 21:23:23 +00:00
Sign in to join this conversation.
No description provided.