Repository navigation
Description
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/inkweaveand a branch from currentmaster - 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_DURATIONset 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 reads1on 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
- Keep Escape and arrow keys in the card view's own controls, and test the card view controls #1116 and PR fix(card-view): keep Escape and arrow keys in the view's own controls (#1116) #1117, which added the test; commit 53196c3 changed the sampler
runExitFLIPandFLIP_DURATIONinapps/web/src/features/synergies/components/CardOverviewModal.tsx- PR feat(collection): a binder of your own, and the set picker's Binders tab (#1074) #1126's Full E2E: https://github.com/Doberjohn/inkweave/actions/runs/41708117904/job/126169069484
Activity
test(card-view): read card B as a comparison closes and on every fram…
test(card-view): read every frame card B lasts after leaving a compar…
test(card-view): read card B as a comparison closes and on every fram…
Merge pull request #1129 from Doberjohn/claude/project-thread-qq83j4-…