Fix flaky Firefox e2e: make /new_election scroll to wizard reliable#1426
Fix flaky Firefox e2e: make /new_election scroll to wizard reliable#1426jacksonloper wants to merge 4 commits into
Conversation
The Create Election nav now targets /new_election, where the scroll to the wizard is done in JS instead of a native URL fragment. Two races made this flaky on Firefox (issue #1393): - On /new_election, scrollToElement ran once after a fixed 250ms with a smooth scroll, so it could land short when async landing-page content (carousel, images) reflowed the page after the scroll started. Now the landing page jumps instantly and re-aligns via a ResizeObserver until layout settles (2s), stopping as soon as the user scrolls on their own. - On the landing page itself, the nav click scheduled the smooth scroll 250ms later, so Playwright would validate a radio as stable and click right as the scroll kicked in, and the click missed ("Clicking the checkbox did not change its state"). The wizard is already rendered there, so the scroll now starts immediately and actionability checks wait out the movement. Also raise the toBeInViewport timeout from 2s to 10s in the test that does a full page load of /new_election: in dev mode Firefox takes ~1.5s+ just to render the page, which left no headroom. Fixes #1393 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KJ6tU9igwGYGrFGumeCA7d
✅ Deploy Preview for bettervoting ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThis change modifies Sequence Diagram(s)See diagram embedded in the hidden review stack artifact above for the wizard alignment flow. Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Keep the original feel of the wizard scroll (250ms pause, then smooth) instead of starting it immediately. The race with clicks is closed a different way: scrollToElement now takes cancelOnUserInput, which drops a still-pending scroll if the user interacts during the delay, so the scroll can never yank the page out from under a later click. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KJ6tU9igwGYGrFGumeCA7d
ArendPeter
left a comment
There was a problem hiding this comment.
Thanks for fixing this! This was a tricky one
Fixes #1393
Problem
On Firefox,
create-election.spec.tsintermittently failed after the Create Election nav was changed from the native/#wizardanchor to the/new_electionroute, where the scroll to the wizard is done in JS. Two distinct races (both rooted inscrollToElement's fixed 250ms delay + smooth scroll):/new_electionfull page load (test :45): the one-shot delayed smooth scroll could land short of the wizard when async landing-page content (carousel, images) reflowed the page, and in Firefox dev mode the page takes ~1.5s+ to render at all, leaving no headroom in the test's 2stoBeInViewportbudget.Pollradio as stable and click exactly as the scroll kicked in — the click missed (Clicking the checkbox did not change its state).Fix
This combines options 1 and 2 from the issue:
LandingPage.tsx: on/new_election, position at the wizard instantly (like the old native/#wizardanchor did) and keep re-aligning via aResizeObserverondocument.bodywhile content above the wizard loads and reflows. Re-aligning stops once layout settles (2s) or as soon as the user scrolls/interacts, so we never fight the user. This also fixes the minor UX regression where the nav could land short of the wizard on Firefox.Header.tsx/util.tsx: the in-page wizard-nav click keeps its original feel (250ms pause, then smooth scroll). The race is closed instead with a newcancelOnUserInputoption onscrollToElement: if the user (or the test) interacts during the delay, the still-pending scroll is dropped, so it can never yank the page out from under a later click.scrollToElement's defaults are unchanged for all other callers.create-election.spec.ts: raise thetoBeInViewporttimeout from 2s to 10s for the test that does a full page load of/new_election(matching the 10s timeouts already used elsewhere in the spec).Testing
Against the local dev stack:
npx playwright test tests/create-election.spec.ts --project=firefox --repeat-each=3— 15/15 pass (previously test :45 failed most runs and :118 failed ~half)npm run build -w @equal-vote/star-vote-frontendpasses; eslint reports no new issues on the touched files🤖 Generated with Claude Code
https://claude.ai/code/session_01KJ6tU9igwGYGrFGumeCA7d