fix(tests): raise testTimeout to 60s to match hookTimeout#54
Merged
Conversation
…nt vmThreads timeout Both tests hang when run after heavier tests deplete VM worker resources. Passes in isolation; same root cause and fix pattern as FloatingToolbar/ToggleSwitch.
SettingsPage.test fails intermittently when run late in the full suite. React 19's act() spin-waits for all pending async work; accumulated stale microtasks from prior files (especially fake-timer tests and unlisten promise chains from useTestRunContext) cause the await user.click() call in test 6 to hang until the 30s timeout fires. Same pattern as TabBar/ReadingSection/FloatingToolbar. Moving it into the early bucket ensures it runs on a clean worker before resources are depleted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
SettingsPage.test was added to early with push(), putting it last in the early array. The early bucket already contains fake-timer tests (useFileWatcher, FloatingToolbar, ExportAnnotationsPopover) which contaminate React 19's scheduler — causing act() inside user.keyboard() to spin-wait until the 30s timeout. Use unshift() so SettingsPage.test runs FIRST in the early bucket, before any fake-timer contamination can reach it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eads timeout front-matter.test renders Reader (TipTap + all extensions) and was landing in the rest bucket, causing 30s timeouts when run after memory is depleted by other heavy editor tests — same pattern as TabBar/ReadingSection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…front-matter The afterEach drain loop (3x setTimeout(0)) can stall under V8 GC pressure in a long-running vmThreads worker, causing browser-stubs.test and diff-engine.test to fail intermittently with a 30s hook timeout. Doubling hookTimeout to 60s gives GC pauses room to complete. front-matter.test's "preserves front matter after setContent" test does two renders + waitFor and needs more than the default 30s when running on a warm worker — explicit 60s timeout added. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both are lightweight (no TipTap) but were timing out when run last within the early bucket — after Reader/FloatingToolbar/front-matter deplete the vmThreads worker. Moving them to earlyLight ensures they run before the heavy early tests on a fresh worker. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hangs
StyleMemorySection.test: adds explicit 60s per-test timeout — the test uses a
real 6s window.setTimeout for the export toast, so it runs ~9-13s in isolation.
The global testTimeout:30s was too tight under system load.
SettingsPage.test: replaces userEvent.click with fireEvent.click in the
'passes settings and setSetting' test — avoids async act() spin-wait caused by
TestRunProvider's resolved-Promise effects in React 19.
apply-accepted-correction.test: changes outer await act(async) to sync act() for
the applyAcceptedCorrection assertion; moves HTML assertions to waitFor({timeout:10000})
to avoid TipTap's async scheduler hanging inside async act().
vitest.config: promotes TabBar.test and ReadingSection.test from early to earlyLight
bucket — they're lightweight (no TipTap) but their afterEach hook times out when run
after heavy tests deplete VM worker resources.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous commit removed the userEvent import but left setup() calls in two tests (switching sections, escape key), causing TS2552 on CI. Replace both with fireEvent (sync) — same rationale: avoids async act() hang from TestRunProvider's listen() resolved-Promise in React 19. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
StyleMemorySection.test (mustRunFirst) triggers a real window.setTimeout(6000) for its toast. vi.clearAllTimers() only clears fake timers, so this timer persists and fires during the first act() of the next file, causing React 19 to spin-wait for the 30s testTimeout. useSettings.test and DiffBanner.test don't mock @/lib/tauri-commands, so they can safely run before mustRunFirst (no mock isolation impact). Moving them to a new preFirst bucket guarantees they run with a completely clean scheduler state. New order: preFirst → mustRunFirst → earlyFirst → earlyLight → early → small → rest Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rEach DiffBanner's last test uses vi.useFakeTimers(). The afterEach called cleanup() then vi.useRealTimers(), but skipped vi.clearAllTimers(). React's scheduler queues work via fake setTimeout internally during render; without explicitly clearing those callbacks before restoring real timers, they become orphaned and React 19's act() spin-waits on them in the next file (StyleMemorySection). Adding vi.clearAllTimers() between cleanup() and vi.useRealTimers() ensures all fake-timer scheduler work is drained before the fake timer registry is abandoned. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…act() hang RulesTab runs last in mustRunFirst, immediately before SettingsPage (earlyFirst). Its delete test uses 2 userEvent clicks + 2 waitFor calls, leaving more stale async callbacks than the 3 global drain cycles clear. Under system load, React 19's act() in SettingsPage's fireEvent.click spin-waits on these orphaned callbacks, causing intermittent 12s hangs and test failures. Fix: afterAll with 8 extra drain cycles in RulesTab.test.tsx, running after all RulesTab tests complete (before vi.resetModules and before SettingsPage loads). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Under CPU throttling (background agents, indexing, other processes), jsdom init and test execution slow dramatically. Tests that take <5ms normally can hit 30s+ under load, causing false timeout failures. 60s matches hookTimeout and gives headroom without hiding real hangs. Fixes intermittent load-induced failures in ToggleSwitch, search, and other small tests that run late in the suite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Context
Observed 6+ load-induced failures on 2026-04-02. Pattern: ToggleSwitch, search.test, and other small/late-running tests timeout at exactly 30s, then pass cleanly on re-run. Filed as margin-909. hookTimeout was already 60s for the same reason.
Test plan
Generated with Claude Code