test(web): stub SvelteKit app modules suite-wide so no test loads the client runtime (#3943)
release / govulncheck (push) Successful in 32s
release / web (push) Successful in 1m25s
release / go (push) Successful in 1m41s
release / integration (push) Successful in 4m55s
release / android (push) Successful in 6m15s
release / Build signed APK (releases and dev) (push) Successful in 6m42s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 2m4s
release / Verify release artifacts (tag releases only) (push) Skipped
release / govulncheck (push) Successful in 32s
release / web (push) Successful in 1m25s
release / go (push) Successful in 1m41s
release / integration (push) Successful in 4m55s
release / android (push) Successful in 6m15s
release / Build signed APK (releases and dev) (push) Successful in 6m42s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Successful in 2m4s
release / Verify release artifacts (tag releases only) (push) Skipped
The home page reaches the real $app/navigation through AlbumCard and AlbumMenu. That loads SvelteKit's client runtime, whose $app/paths reads __SVELTEKIT_PAYLOAD__ at module load. The global is only there when the kit plugin's define reaches the module, and under vitest that is not reliable: page.test.ts failed to load on CI run 6576 and passed on its re-run. #374 was the same class of failure. vitest.setup.ts now mocks $app/navigation, $app/state and $app/paths for every test. Per-file mocks still win. A small guard test fails if the suite-wide mocks are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, test, vi } from 'vitest';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
|
||||
// Guards the suite-wide $app mocks in vitest.setup.ts (#3943). If they are
|
||||
// removed, tests that never mock $app themselves go back to loading
|
||||
// SvelteKit's client runtime, which fails at module load on some CI runs.
|
||||
describe('suite-wide SvelteKit app-module mocks', () => {
|
||||
test('$app/navigation is the mock, not the client runtime', () => {
|
||||
expect(vi.isMockFunction(goto)).toBe(true);
|
||||
});
|
||||
|
||||
test('$app/state gives a page at the root URL', () => {
|
||||
expect(page.url.pathname).toBe('/');
|
||||
});
|
||||
});
|
||||
@@ -15,6 +15,51 @@ vi.mock('@tanstack/svelte-query', async (orig) => {
|
||||
return { ...actual, useQueryClient: () => ({ invalidateQueries: vi.fn() }) };
|
||||
});
|
||||
|
||||
// Default SvelteKit app-module mocks for the whole suite (#3943). Without
|
||||
// them, any page or component that reaches $app/navigation or $app/state —
|
||||
// the home page does, through AlbumCard → AlbumMenu — loads SvelteKit's
|
||||
// client runtime, whose $app/paths reads __SVELTEKIT_PAYLOAD__ at module
|
||||
// load. That global only exists when the kit plugin's define reaches the
|
||||
// module, which it does not reliably under vitest: page.test.ts failed to
|
||||
// load on one CI run and passed on the re-run of the same commit (#374
|
||||
// was the same class). Stubbing the modules keeps every test off the
|
||||
// client bootstrap. Tests that assert on goto or need a particular URL
|
||||
// still mock per file (pageUrlModule in test-utils/mocks/appState.ts),
|
||||
// and per-file mocks win over these.
|
||||
vi.mock('$app/navigation', () => ({
|
||||
goto: vi.fn(() => Promise.resolve()),
|
||||
invalidate: vi.fn(() => Promise.resolve()),
|
||||
invalidateAll: vi.fn(() => Promise.resolve()),
|
||||
preloadData: vi.fn(() => Promise.resolve()),
|
||||
preloadCode: vi.fn(() => Promise.resolve()),
|
||||
beforeNavigate: vi.fn(),
|
||||
afterNavigate: vi.fn(),
|
||||
onNavigate: vi.fn(),
|
||||
pushState: vi.fn(),
|
||||
replaceState: vi.fn(),
|
||||
disableScrollHandling: vi.fn()
|
||||
}));
|
||||
vi.mock('$app/state', () => ({
|
||||
page: {
|
||||
url: new URL('http://localhost/'),
|
||||
params: {},
|
||||
route: { id: null },
|
||||
status: 200,
|
||||
error: null,
|
||||
data: {},
|
||||
form: null,
|
||||
state: {}
|
||||
},
|
||||
navigating: null,
|
||||
updated: { current: false, check: () => Promise.resolve(false) }
|
||||
}));
|
||||
vi.mock('$app/paths', () => ({
|
||||
base: '',
|
||||
assets: '',
|
||||
resolve: (path: string) => path,
|
||||
asset: (path: string) => path
|
||||
}));
|
||||
|
||||
// Node 25 ships a partial localStorage global that lacks getItem/setItem/clear
|
||||
// unless launched with --localstorage-file. jsdom sees Node's global and skips
|
||||
// installing its own. Replace with an in-memory Storage-compatible polyfill so
|
||||
|
||||
Reference in New Issue
Block a user