[Fix] Flush Tremor Tooltip timers in user_edit_view tests#25480
[Fix] Flush Tremor Tooltip timers in user_edit_view tests#25480yuneng-berri merged 1 commit intomainfrom
Conversation
Tremor's internal Tooltip component sets a setTimeout that fires after the jsdom test environment tears down, causing a ReferenceError. Add afterEach that flushes pending timers before cleanup.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR adds an Confidence Score: 5/5Safe to merge — test-only change that resolves a post-teardown warning without weakening any assertions. The single finding is P2: the fake-timer strategy may not capture pre-scheduled real timers, but the explicit No files require special attention — the
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/components/user_edit_view.test.tsx | Adds afterEach with fake-timer flush and explicit cleanup() to prevent Tremor Tooltip setTimeout from firing after jsdom teardown. Minor concern: vi.useFakeTimers() called after real timers are set may not capture those already-scheduled handles; explicit cleanup() is also redundant since testing-library auto-cleans. |
Sequence Diagram
sequenceDiagram
participant Test as Vitest Test
participant JSDOM as jsdom Environment
participant Tremor as Tremor Tooltip
participant RTL as @testing-library/react
Note over Test,RTL: Before Fix
Test->>JSDOM: render component
JSDOM->>Tremor: mount Tooltip
Tremor->>JSDOM: setTimeout(callback, N)
Test->>RTL: waitFor / assertions
JSDOM-->>Test: test passes
JSDOM->>JSDOM: teardown (window removed)
Tremor-->>JSDOM: timer fires → ReferenceError: window is not defined ❌
Note over Test,RTL: After Fix (afterEach)
Test->>RTL: waitFor / assertions
JSDOM-->>Test: test passes
Test->>JSDOM: vi.useFakeTimers()
Test->>JSDOM: vi.runAllTimers() (flushes fake queue only)
Test->>JSDOM: vi.useRealTimers()
Test->>RTL: cleanup() → unmount component while jsdom alive ✅
JSDOM->>JSDOM: teardown
Reviews (1): Last reviewed commit: "Fix unhandled "window is not defined" er..." | Re-trigger Greptile
| afterEach(() => { | ||
| // Tremor's internal Tooltip sets a setTimeout that fires after teardown, | ||
| // causing "window is not defined". Flush pending timers before cleanup. | ||
| vi.useFakeTimers(); | ||
| vi.runAllTimers(); | ||
| vi.useRealTimers(); | ||
| cleanup(); | ||
| }); |
There was a problem hiding this comment.
vi.useFakeTimers() post-hoc cannot capture already-scheduled real timers
vi.useFakeTimers() replaces the global setTimeout at the moment it's called, but any setTimeout that Tremor's Tooltip already scheduled during the test body runs against the real timer queue and is not moved into the fake queue. vi.runAllTimers() therefore only flushes timers set after useFakeTimers() was called — not the Tooltip's pre-existing handle. The fix's apparent effect is more likely coming from the explicit cleanup() call (unmounting the component while jsdom is still alive, so when the real timer fires there's no React tree to update).
A more reliable and self-documenting approach is to mock Tremor's Tooltip inside the existing @tremor/react mock block so it never schedules a timer:
vi.mock("@tremor/react", async (importOriginal) => {
const actual = await importOriginal<typeof import("@tremor/react")>();
const React = await import("react");
// Prevent Tremor's Tooltip internal setTimeout from firing after jsdom teardown
const Tooltip = ({ children }: { children?: React.ReactNode }) =>
React.createElement(React.Fragment, null, children);
Tooltip.displayName = "Tooltip";
const SelectItem = ({ value, children, title }: any) => { ... };
SelectItem.displayName = "SelectItem";
return { ...actual, Tooltip, SelectItem };
});This eliminates the root cause instead of racing against it, and the afterEach block can be removed entirely.
The explicit cleanup() call is also redundant — @testing-library/react registers an afterEach hook automatically when the module is first imported, so cleanup() already fires without this block.
Summary
Failure Path (Before Fix)
Tremor's internal Tooltip component sets a
setTimeoutthat fires after the jsdom test environment is torn down, causing aReferenceError: window is not definedduring vitest runs ofuser_edit_view.test.tsx. This produced a false-positive warning that could mask real test failures.Fix
Added an
afterEachblock that switches to fake timers, flushes all pending timers (so the Tooltip callback runs while jsdom is still alive), restores real timers, and callscleanup().Testing
npx vitest run src/components/user_edit_view.test.tsx— all 25 tests pass with no unhandled errorsType
🐛 Bug Fix
✅ Test