Skip to content

Fix the reduced-motion comparison test that fails on WebKit #1128

Closed

Description

@Doberjohn

Context

#1117 (for #1116) added synergy-detail-modal.spec.ts's "with reduced motion › a comparison opens and closes in place, and opens again". It fails on WebKit 3 times out of 3 in PR #1126's Full E2E (run 41708117904, job 126169069484), and master carries it since #1117 merged on 2026-11-03. Chromium, Firefox and the mobile projects pass. The test never ran on WebKit before it merged.

After BACK, the test samples card B (.focused-card-glow-offset) on each frame the card view spends in default mode and expects four frames, all at opacity 0. Under reduced motion card B hides at once, stays mounted for the exit's FLIP_DURATION (480 ms), and then unmounts. WebKit drew only 3 frames in that window, so the sampler got ['0', '0', '0']. Each of those frames was at opacity 0, which is what the test is checking; four frames was only the number the sampler stops at.

In Chromium, the failure reproduces exactly when card B's stay is shortened (FLIP_DURATION 50): ['0', '0', '0'] against the expected four.

Success: the test checks every frame card B lasts after BACK, needs at least one, and passes on every project. It still fails when leaving flies card B back instead of hiding it.

Prerequisites

  • Write access to Doberjohn/inkweave and a branch from current master
  • Node 24, pnpm 10.34.7 and pnpm install
  • Playwright's Chromium for local runs. WebKit is checked by the PR's Full E2E, which runs once when the PR opens ready for review.

Implementation Steps

Step 1: Stop the sampler when card B leaves

In sampleCardB (apps/web/e2e/tests/synergy-detail-modal.spec.ts), resolve once card B has been seen in the wanted mode and is gone, rather than waiting out the 240-frame budget:

const gone = frames.length > 0 && !cardB;
if (frames.length < 4 && left > 0 && !gone) requestAnimationFrame(sample);
else resolve(frames);

Step 2: Check every frame card B lasts after BACK

const leaving = (await frames()).map((frame) => frame.opacity);
expect(leaving.length).toBeGreaterThan(0);
expect(leaving.filter((opacity) => opacity !== '0')).toEqual([]);

Verify: pnpm --filter inkweave-web exec playwright test synergy-detail-modal --project chromium --project mobile-chrome passes.

Files Affected

Modified

File Change
apps/web/e2e/tests/synergy-detail-modal.spec.ts the sampler stops when card B leaves, and the leaving check reads every frame card B lasts

Testing / Verification

Chromium

  • With FLIP_DURATION set to 50, the current test fails with ['0', '0', '0'], as on WebKit, and the fixed test passes
  • With runExitFLIP's reduced-motion branch skipped, the fixed test fails (card B reads 1 on each frame)
  • The whole spec passes on chromium and mobile-chrome

WebKit

  • The PR's Full E2E passes the test on webkit, firefox and mobile-safari

Acceptance Criteria

  • The reduced-motion test passes on all five projects
  • It fails when leaving a comparison flies card B back instead of hiding it at once
  • It fails when no frame of card B is read after BACK
  • No app code changes

Rollback

  • Test: git revert <fix commit> restores the four-frame check, which fails on WebKit again. No app code or data is involved.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtestingTest coverage and quality

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions