web: disable Mantine transitions in tests to kill post-teardown timer flake (#1760)#1761
Conversation
… flake (#1760) A Mantine `Transition`/`Modal` open/close `setTimeout` can fire after happy-dom tears down `window` at the end of a run, throwing an uncaught `ReferenceError: window is not defined` that fails the whole `coverage` job even when every assertion passed (seen on PR #1759's CI, originating in ServerRemoveConfirmModal.test.tsx). Set `env="test"` on the shared `renderWithMantine` MantineProvider so Mantine renders transitions synchronously (no timer). This removes the leak class for every test that renders through the shared wrapper (Modals, Menus, Popovers, …). Also apply it to ViewHeader's local forced-dark provider. The handful of tests that assert mid-flight transition state (ViewHeader's `data-anim="out"` crossfade checks, #1450) genuinely need real transitions, so add an opt-in `renderWithMantineTransitions` wrapper (env="default") and route those three tests through it — each already drives the transition to completion (waitFor/findBy) so it doesn't reintroduce the leak. Tests that assert only the entered state stay on the default (leak-free) wrapper. Full `npm run ci` green; unit run reports zero unhandled errors. Closes #1760 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
|
@claude review |
|
Claude finished @cliffhall's task in 1m 22s —— View job Review: PR #1761 — disable Mantine transitions in tests
Verdict: LGTM — well-targeted, correct, and thoroughly documented. No changes requested. Why the fix is soundThe root cause is a classic post-teardown timer race: a Mantine I verified the fix actually covers the reported failure:
The opt-in escape hatch is handled correctlyThe three
The JSDoc on Minor observations (non-blocking, no action needed)
Nice, surgical fix that kills the whole class of post-teardown timer flake for every test on the shared wrapper. |
Per review feedback: document that tests must render through `renderWithMantine` (env="test", transition-free) rather than a hand-rolled `MantineProvider`, and reserve `renderWithMantineTransitions` for asserting mid-flight animation state (driving the transition to completion). Keeps future tests from quietly reintroducing the post-teardown timer leak class. Refs #1760 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
|
Thanks! LGTM noted. Addressed observation #2 in |
Closes #1760
Problem
A
coverage/ CIbuildjob can fail even when all tests pass, because Vitest exits non-zero on a single unhandled error:A Mantine
Transition/Modalopen/closesetTimeoutfires after happy-dom tears downwindowat the end of the run. Seen on PR #1759's CI (which was otherwise green on re-run).Fix
Set
env="test"on the sharedrenderWithMantineMantineProvider(and ViewHeader's local forced-dark provider). Underenv="test"Mantine renders transitions synchronously — nosetTimeout— so the whole class of post-teardown timer races is eliminated for every test that renders through the shared wrapper (Modals, Menus, Popovers, …).The one wrinkle: tests that assert mid-transition state
Three ViewHeader tests (#1450) assert the exit/crossfade state (
data-anim="out"), which only exists while a transition is in flight — so they genuinely need real transitions. For them, added an opt-inrenderWithMantineTransitionswrapper (env="default") and routed those three through it. Each already drives the transition to completion (waitFor/findBy), so it doesn't reintroduce the leak. Tests that assert only the entered ("in") state stay on the default, leak-free wrapper.Verification
window is not defined.npm run cigreen (validate, ≥90 coverage gate, smoke, 456 Storybook tests).🤖 Generated with Claude Code
https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5