Skip to content

fix(frontend): the reduced-motion preference reaches the page - #1151

Merged
ExtraToast merged 3 commits into
mainfrom
fix/playwright-reduced-motion
Sep 5, 2026
Merged

fix(frontend): the reduced-motion preference reaches the page#1151
ExtraToast merged 3 commits into
mainfrom
fix/playwright-reduced-motion

Conversation

@ExtraToast

@ExtraToast ExtraToast commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Why

playwright.config.ts asks every project but the motion one to run as a visitor who asked for
reduced motion, and says so in a comment. That never happened. The option was ignored by the
runner-managed context, so the reduced-motion path had never been exercised by an end-to-end
test, in any project, and the suites that were meant to be deterministic ran with the full
choreography playing.

closes #852

What this achieves

The preference reaches the page, so the comment is true and the reduced-motion path is exercised
by every test rather than by none. The suite also runs in roughly half the time, which is the
choreography no longer playing.

How

An upgrade, not a workaround. The bug is upstream and long-standing rather than a regression:
probed across releases, the preference fails to reach the page on 1.55.1, 1.56.1, 1.57.0, 1.58.2,
1.59.1, 1.60.0, 1.61.1 and 1.62.1, and works on 1.63.0 — microsoft/playwright#42001, closed on
30 July, milestone v1.63. Emulating it ourselves would have put a workaround in every spec for a
bug the vendor has already fixed, and left the config's comment still lying.

The dependabot hold at >= 1.61 goes with it. It cited Yarn PnP, which this package left for the
node-modules linker.

Not in scope

The system tests pin com.microsoft.playwright:playwright separately, with their own driver and
browsers, and never set this option — untouched. CI installs browsers from the lockfile, so there
is no second version to bump.

Worth a reviewer's attention

#1148 landed first, and had to. With that change reverted and this upgrade in
place, boards-swipe.motion.spec.ts:176 fails 3 times out of 3 on Received: 0 — the newer
Chromium exposes a pre-existing race in a test helper, which #1148 fixed on its own terms.

Two emulateMedia calls went; four stayed, and their comments were wrong. The four in the
motion project carried comments saying they should be deleted once this issue was fixed. Doing
that would have deleted the coverage: that project asks for no preference on purpose, so a
reduced-motion case living there has to set the preference itself. Their comments now give that
reason. The two that genuinely were working around this bug — in esports-season-on-show and
membership — are gone.

A handful of other #852 mentions elsewhere in the specs are now stale, including one that
repeats the same wrong instruction. Left alone here rather than widened into unrelated files; worth
a follow-up.

Nothing else broke. Making the preference real changes the whole suite's behaviour at once, so
the fallout was measured rather than assumed: 820 passed before, 820 passed after, zero specs
needed changing.

Verification

Full yarn test:e2e with #1148 in place: exit 0, 820 passed, 0 failed, 36 skipped, down from 4.7
minutes to 2.8. yarn typecheck, yarn lint and yarn test:unit (1540 tests) all exit 0.

Confirmed after the upgrade that testInfo.project.use.reducedMotion and the page now agree:
resolved=reduce inPage=true, in both chromium and mobile-chrome.


Diff breakdown added removed, scaled to the largest row.

frontend                                           +60    -61    9
  e2e tests          █████████████░░░░░░░░░░░░░    +59    -60    8
  build & config     █░                             +1     -1    1
  generated          ███░░░░░░░░░                  +15    -38    1  ~

ci                                                  +0     -8    1
  build & config     ░░                             +0     -8    1

──────────────────────────────────────────────────────────────────
production                                          +0     -0
tests                                              +59    -60
total (hand-written)                               +60    -69  10 files
~ generated (excluded)                             +15    -38  1 file

`use.reducedMotion` was ignored by the runner-managed context on every
Playwright from 1.55 to 1.62, so every project but the motion one believed
it ran as a visitor who asked for reduced motion and in fact ran with the
full choreography playing. Upstream fixed it in 1.63
(microsoft/playwright#42001), so the fix is the upgrade rather than
emulating the preference ourselves.

The dependabot hold on `>= 1.61` cited Yarn PnP, which this package left
for the node-modules linker, so it goes with it.

Two specs emulated the preference by hand because of this and no longer
need to. The four in the motion project keep theirs: that project asks for
no preference on purpose, so a reduced-motion test living there has to say
so, and their comments now give that reason rather than pointing at #852.

Closes #852
With the preference finally reaching the page, the pass a visitor who asked
for less motion gets is the clamped one: the two stops are on the page
together for 116ms rather than 850ms. The band's landing was watched after
the click and after a round trip for `data-swipe`, which on a runner with
eight workers on four vCPUs costs more than the whole pass — so the sample
landed after the stop leaving had gone and the band answered with one panel
for a pass that did happen.

The claim is unchanged: the slice being read is open in the frame the
arriving season is first drawn in, with the pass still on. What changes is
when it is watched. `landingFrom` installs the watch on the page before the
change is asked for, the way `framesOf` and `heightsHeldFrom` already do,
and answers with the frame the arriving stop is first drawn in. The motion
spec makes the same claim about the long pass and watches it the same way.
Five comments explained themselves by pointing at #852, and each said something
that is no longer true now the preference reaches the page.

Two in the boards spec blamed the loose depth on the suite running with full
motion. The looseness is right for a different reason: the dissolve is eased
under the reduced ceiling too, so a depth read a moment after a press is still
wherever it had got to.

The drag spec said its emulated preference goes once #852 is fixed. It does not:
the motion project asks for no preference on purpose, so a reduced-motion case
living there has to set it itself.

And the season-on-show header said the deterministic projects only mean to
emulate the preference. They do now, which shortens the pass rather than removing
it — the reason the landing is watched for from before the season is asked for.
@ExtraToast
ExtraToast merged commit acd8b44 into main Sep 5, 2026
25 checks passed
@ExtraToast
ExtraToast deleted the fix/playwright-reduced-motion branch September 5, 2026 22:35
@github-actions github-actions Bot mentioned this pull request Sep 5, 2026
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.

Playwright ignores the reducedMotion context option, so no e2e test has ever run with the preference set

1 participant