You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every frontend test file loads the entire Milkdown and Shiki stack before its first assertion, whatever it covers, and the cost surfaces as intermittent beforeEach timeouts rather than as slow tests.
The chain, verified link by link:
The global beforeEach in src/test/setup/common.ts:28 does await import("../utils/appStores").
src/test/utils/appStores.ts:17 imports useSessionStore from the @/features/session public API.
src/features/session/services/documentEditorBridge.ts:1-7 imports @/features/editor, whose index exports MilkdownEditor, pulling @milkdown/kit/* and Shiki.
The same edge affects production, not only tests. Nine modules import @/features/session, and seven of them never touch the editor otherwise: App.tsx, commands/actions/edit.ts, commands/actions/file.ts, commands/actions/view.ts, commands/hooks/useAppCommands.ts, components/layout/Shell.tsx, and components/screens/WelcomeScreen.tsx. Only commands/dispatch.ts and components/screens/DocumentScreen.tsx import the editor directly. WelcomeScreen.tsx is the clearest case: the screen shown before any document is open transitively pulls the whole editor stack.
Affected areas
src/test/setup/common.ts and src/test/utils/appStores.ts.
src/features/session/index.ts and src/features/session/services/documentEditorBridge.ts.
The nine production modules importing @/features/session listed above.
vite.config.ts, if a hookTimeout override is added.
Intended outcome
A test file that does not exercise the editor does not load Milkdown or Shiki, and @/features/session stops being an entry point into the editor module graph for consumers that only need session state. Test count and assertions stay unchanged.
Prior investigation: the measurements below were taken in an earlier session on a 12-core, 34 GB Windows machine and are recorded as reported, not re-measured here.
formatFileSize.test.ts, 16 trivial assertions with 14ms of own imports, spends 4.30s in the tests phase.
The same file drops to 1.57s when useSessionStore is deep-imported from src/features/session/stores/session, a 2.7x improvement.
Full-suite flake on one commit across three runs: 1 file failed at 12 workers, 4 files failed at 4 workers, 0 failed on the third run. The failure is always the beforeEach hook exceeding the 10s Vitest default, never an assertion.
Done when
A test file that does not exercise the editor no longer loads Milkdown or Shiki.
@/features/session no longer pulls the editor module graph into consumers that do not import the editor themselves.
Any deliberate deep import in src/test/ states why, as src/AGENTS.md requires for exceptions to the feature-root import rule.
pnpm check:frontend passes with the test count unchanged.
Notes
CI history is established rather than assumed: 100 runs since 2026-07-07 show 99 successes and one failure, and that failure was an assertion in Dialog.test.tsx > keeps dialogs open when dragging starts from the titlebar drag region, not a hook timeout. CI has never produced this failure mode.
That evidence complicates the explanation rather than confirming it. The failing CI run took 209s for 79 files and 545 tests, far slower in wall clock than local runs of about 78s for 90 files and 882 tests, and GitHub runners have fewer cores than the machine where the flake reproduces. Fewer workers made the flake worse locally, so the configuration that should be most vulnerable is the one that never fails. The trigger is therefore not simply a slow machine, and this is unexplained.
Implementation direction
Deep-importing useSessionStore from src/features/session/stores/session in appStores.ts is the cheap mitigation, and src/test/utils/tauriApi.ts already deep-imports feature internals, so the precedent exists. It fixes the test symptom while leaving the production edge in place.
Removing documentEditorBridge from the session public API addresses the cause and is the change with production value, but it moves a real API boundary and deserves its own review.
Out of scope
Raising Vitest's hookTimeout. It hides the symptom, and because the trigger is not understood, there is no basis for choosing a value that would reliably help.
Bundle-size claims. The module graph edge is confirmed, but no bundle measurement has been taken, so no claim is made about what survives tree shaking.
Summary
Every frontend test file loads the entire Milkdown and Shiki stack before its first assertion, whatever it covers, and the cost surfaces as intermittent
beforeEachtimeouts rather than as slow tests.The chain, verified link by link:
beforeEachinsrc/test/setup/common.ts:28doesawait import("../utils/appStores").src/test/utils/appStores.ts:17importsuseSessionStorefrom the@/features/sessionpublic API.src/features/session/index.ts:3re-exportsdocumentEditorBridge.src/features/session/services/documentEditorBridge.ts:1-7imports@/features/editor, whose index exportsMilkdownEditor, pulling@milkdown/kit/*and Shiki.The same edge affects production, not only tests. Nine modules import
@/features/session, and seven of them never touch the editor otherwise:App.tsx,commands/actions/edit.ts,commands/actions/file.ts,commands/actions/view.ts,commands/hooks/useAppCommands.ts,components/layout/Shell.tsx, andcomponents/screens/WelcomeScreen.tsx. Onlycommands/dispatch.tsandcomponents/screens/DocumentScreen.tsximport the editor directly.WelcomeScreen.tsxis the clearest case: the screen shown before any document is open transitively pulls the whole editor stack.Affected areas
src/test/setup/common.tsandsrc/test/utils/appStores.ts.src/features/session/index.tsandsrc/features/session/services/documentEditorBridge.ts.@/features/sessionlisted above.vite.config.ts, if ahookTimeoutoverride is added.Intended outcome
A test file that does not exercise the editor does not load Milkdown or Shiki, and
@/features/sessionstops being an entry point into the editor module graph for consumers that only need session state. Test count and assertions stay unchanged.Related context
formatFileSize.test.ts, 16 trivial assertions with 14ms of own imports, spends 4.30s in the tests phase.useSessionStoreis deep-imported fromsrc/features/session/stores/session, a 2.7x improvement.beforeEachhook exceeding the 10s Vitest default, never an assertion.Done when
@/features/sessionno longer pulls the editor module graph into consumers that do not import the editor themselves.src/test/states why, assrc/AGENTS.mdrequires for exceptions to the feature-root import rule.pnpm check:frontendpasses with the test count unchanged.Notes
CI history is established rather than assumed: 100 runs since 2026-07-07 show 99 successes and one failure, and that failure was an assertion in
Dialog.test.tsx > keeps dialogs open when dragging starts from the titlebar drag region, not a hook timeout. CI has never produced this failure mode.That evidence complicates the explanation rather than confirming it. The failing CI run took 209s for 79 files and 545 tests, far slower in wall clock than local runs of about 78s for 90 files and 882 tests, and GitHub runners have fewer cores than the machine where the flake reproduces. Fewer workers made the flake worse locally, so the configuration that should be most vulnerable is the one that never fails. The trigger is therefore not simply a slow machine, and this is unexplained.
Implementation direction
Deep-importing
useSessionStorefromsrc/features/session/stores/sessioninappStores.tsis the cheap mitigation, andsrc/test/utils/tauriApi.tsalready deep-imports feature internals, so the precedent exists. It fixes the test symptom while leaving the production edge in place.Removing
documentEditorBridgefrom the session public API addresses the cause and is the change with production value, but it moves a real API boundary and deserves its own review.Out of scope
hookTimeout. It hides the symptom, and because the trigger is not understood, there is no basis for choosing a value that would reliably help.