test(e2e): wait for the carousel's smooth scroll to settle before measuring it #153

Merged
tudor merged 1 commits from fix/nearby-journey-waits-for-smooth-scroll into main 2026-09-22 14:55:16 +00:00
Owner

Fixes the same assertion failing again on the staging run for #152.

Expected: <= 8
Received:    659       (identical on both attempts)

Verified against staging this time, not reasoned about. The previous fix
(#152) addressed a real problem — Playwright scrolling an off-screen target into
view — but it was not the one producing this number.

What is actually happening

The carousel arrows scroll with behavior: 'smooth'. The test polled for "has
it moved at all", which is satisfied 50ms in, at 13px of a 1300px journey,
then recorded offsetBefore, clicked, and recorded offsetAfter. The row was
still travelling the whole time, so the delta was the tail of the arrow's own
animation — not the effect of the selection.

Sampled on staging, one arrow press:

ms scrollLeft
0 2
50 13 ← the old poll returned here
200 449
400 1111
650 1289

659 is about half of the 1317 this school's row scrolls, which is why it was
deterministic rather than flaky.

The app is not at fault

Driving staging by hand: row at the end (1317), click the last card's
add-to-compare, offset still 1317, one button pressed. The carousel holds its
position exactly as intended. That property has still never actually been
proven by CI — this change is what makes the test capable of proving it.

The fix

settledScrollLeft() waits for two identical readings before trusting one, and
is used for both ends of the comparison and for the arrow assertion.

Verification

Run against staging both ways, locally:

  • main's version of this test fails there, reproducing CI exactly
  • this version passes, as do all three mobile reference widths

🤖 Generated with Claude Code

Fixes the same assertion failing again on the staging run for #152. ``` Expected: <= 8 Received: 659 (identical on both attempts) ``` **Verified against staging this time, not reasoned about.** The previous fix (#152) addressed a real problem — Playwright scrolling an off-screen target into view — but it was not the one producing this number. ## What is actually happening The carousel arrows scroll with `behavior: 'smooth'`. The test polled for "has it moved at all", which is satisfied **50ms in, at 13px of a 1300px journey**, then recorded `offsetBefore`, clicked, and recorded `offsetAfter`. The row was still travelling the whole time, so the delta was the tail of the arrow's own animation — not the effect of the selection. Sampled on staging, one arrow press: | ms | scrollLeft | |---|---| | 0 | 2 | | 50 | 13 ← the old poll returned here | | 200 | 449 | | 400 | 1111 | | 650 | 1289 | 659 is about half of the 1317 this school's row scrolls, which is why it was deterministic rather than flaky. ## The app is not at fault Driving staging by hand: row at the end (1317), click the last card's add-to-compare, offset still 1317, one button pressed. The carousel holds its position exactly as intended. That property has still never actually been proven by CI — this change is what makes the test capable of proving it. ## The fix `settledScrollLeft()` waits for two identical readings before trusting one, and is used for both ends of the comparison and for the arrow assertion. ## Verification Run against staging both ways, locally: - `main`'s version of this test **fails** there, reproducing CI exactly - this version **passes**, as do all three mobile reference widths 🤖 Generated with [Claude Code](https://claude.com/claude-code)
tudor added 1 commit 2026-09-22 14:13:46 +00:00
test(e2e): wait for the carousel's smooth scroll to settle before measuring it
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m12s
PR Checks / Backend Smoke (pull_request) Successful in 10s
PR Checks / Build Backend (no push) (pull_request) Successful in 18s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m18s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 11s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 32s
077aca6008
Second failure of the same assertion, and the first fix addressed a real but
different problem. This is the one that was actually producing the number.

The arrows scroll with `behavior: 'smooth'`. The test polled for "has it moved
at all" — satisfied 50ms in, at 13px of a 1300px journey — then recorded the
offset, clicked, and recorded again. The row was still travelling throughout,
so the delta it measured was the tail of the arrow's animation, not the effect
of the selection. Hence a deterministic 659, roughly half of the 1317 this
school's row scrolls.

Measured against staging rather than reasoned about: the animation runs about
700ms, and the samples are in the helper's comment.

settledScrollLeft waits for two identical readings before trusting one. The app
was never at fault — driving staging by hand, the offset holds at 1317 across
the selection, exactly as intended.

Verified against staging both ways: main's version of this test fails there,
this version passes, along with all three mobile widths.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

🤖 AI Code Review (Claude Code)

This is a test-only change to the Playwright e2e journeys spec, adding a settledScrollLeft() helper that polls until the carousel's scrollLeft value stops changing between reads, replacing direct/immediate scrollLeft reads that could catch mid-animation values. It correctly addresses the smooth-scroll flakiness described in the comment and is applied consistently at both call sites; no production, security, or deploy-relevant code is touched.

✅ No issues found.

## 🤖 AI Code Review (Claude Code) This is a test-only change to the Playwright e2e journeys spec, adding a settledScrollLeft() helper that polls until the carousel's scrollLeft value stops changing between reads, replacing direct/immediate scrollLeft reads that could catch mid-animation values. It correctly addresses the smooth-scroll flakiness described in the comment and is applied consistently at both call sites; no production, security, or deploy-relevant code is touched. ✅ No issues found.
tudor merged commit 80f405123e into main 2026-09-22 14:55:16 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tudor/school_compare#153