Skip to content

Fix flaky Firefox e2e: make /new_election scroll to wizard reliable#1426

Open
jacksonloper wants to merge 4 commits into
mainfrom
JacksonLoper/flakytest
Open

Fix flaky Firefox e2e: make /new_election scroll to wizard reliable#1426
jacksonloper wants to merge 4 commits into
mainfrom
JacksonLoper/flakytest

Conversation

@jacksonloper

@jacksonloper jacksonloper commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1393

Problem

On Firefox, create-election.spec.ts intermittently failed after the Create Election nav was changed from the native /#wizard anchor to the /new_election route, where the scroll to the wizard is done in JS. Two distinct races (both rooted in scrollToElement's fixed 250ms delay + smooth scroll):

  1. /new_election full 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 2s toBeInViewport budget.
  2. Landing-page nav click (test :118): the click handler scheduled the scroll 250ms later, so Playwright would validate the Poll radio 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 /#wizard anchor did) and keep re-aligning via a ResizeObserver on document.body while 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 new cancelOnUserInput option on scrollToElement: 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 the toBeInViewport timeout 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)
  • Tests :6 and :118 repeated 5x each on Firefox — the wizard-scroll flakes are gone
  • Full spec on Chromium + Firefox and the full suite — all pass
  • Instrumented Firefox runs confirm the page scrolls to the wizard as soon as it renders and stays there (no snap-back)
  • npm run build -w @equal-vote/star-vote-frontend passes; eslint reports no new issues on the touched files

🤖 Generated with Claude Code

https://claude.ai/code/session_01KJ6tU9igwGYGrFGumeCA7d

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
@netlify

netlify Bot commented Jul 8, 2026

Copy link
Copy Markdown

Deploy Preview for bettervoting ready!

Name Link
🔨 Latest commit f266cc5
🔍 Latest deploy log https://app.netlify.com/projects/bettervoting/deploys/6a50531161353f0008f5be94
😎 Deploy Preview https://deploy-preview-1426--bettervoting.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This change modifies scrollToElement in util.tsx to accept configurable behavior and delay options instead of fixed defaults. Header.tsx updates its wizard navigation click handlers to pass { delay: 0 }. LandingPage.tsx replaces its one-time scroll effect for the /new_election route with a ResizeObserver-driven alignment loop that stops after a 2-second timeout or on user interaction, with corresponding cleanup. A Playwright test's viewport timeout for an election button assertion is increased from 2000ms to 10000ms.

Sequence Diagram(s)

See diagram embedded in the hidden review stack artifact above for the wizard alignment flow.

Poem

A wizard hopped, then hopped again,
Chased by resizing windows' plight,
No more waiting, delay of zero,
Align, observe, then hold on tight! 🐇
Ten seconds now for buttons true—
This rabbit's scroll bugs, bid adieu!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address the reported Firefox /new_election scrolling races and the related test timeout issue in #1393.
Out of Scope Changes check ✅ Passed The edits stay within the issue scope by adjusting scrolling behavior, supporting utility options, and hardening the affected test.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title is specific and matches the main change: fixing flaky Firefox e2e scrolling for /new_election.
Description check ✅ Passed The description covers the problem, fix, testing, and related issue, but it omits the requested screenshots/videos section.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch JacksonLoper/flakytest

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jacksonloper jacksonloper marked this pull request as draft July 8, 2026 16:50
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
@jacksonloper jacksonloper requested a review from ArendPeter July 8, 2026 18:04
@jacksonloper jacksonloper marked this pull request as ready for review July 8, 2026 18:05

@ArendPeter ArendPeter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this! This was a tricky one

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.

Flaky Firefox e2e: "Create Election" nav to /new_election doesn't reliably scroll wizard into viewport

2 participants