diff --git a/web/src/components/dashboard/customizer/sections/__tests__/TemplateGallerySection.test.tsx b/web/src/components/dashboard/customizer/sections/__tests__/TemplateGallerySection.test.tsx index b3e448921e..875bc7aa80 100644 --- a/web/src/components/dashboard/customizer/sections/__tests__/TemplateGallerySection.test.tsx +++ b/web/src/components/dashboard/customizer/sections/__tests__/TemplateGallerySection.test.tsx @@ -11,8 +11,8 @@ vi.mock('react-i18next', () => ({ })) vi.mock('lucide-react', () => ({ - Check: (props: Record) => , - Search: (props: Record) => , + Check: () => , + Search: () => , })) vi.mock('../../../../../lib/formatCardTitle', () => ({ @@ -20,7 +20,7 @@ vi.mock('../../../../../lib/formatCardTitle', () => ({ })) vi.mock('../../../../../lib/icons', () => ({ - getIcon: () => (props: Record) => , + getIcon: () => () => , })) vi.mock('../../../templates', () => ({ diff --git a/web/src/hooks/useMissions.provider.tsx b/web/src/hooks/useMissions.provider.tsx index ffae53abc3..5156a9c991 100644 --- a/web/src/hooks/useMissions.provider.tsx +++ b/web/src/hooks/useMissions.provider.tsx @@ -399,7 +399,7 @@ export function useMissions() { const context = useContext(MissionContext) if (!context) { if (import.meta.env.DEV) { - logger.warn('useMissions was called outside MissionProvider — returning safe fallback') + console.warn('useMissions was called outside MissionProvider — returning safe fallback') } return MISSIONS_FALLBACK } diff --git a/web/src/test/setup.ts b/web/src/test/setup.ts index 639630a4d2..0ec51be87d 100644 --- a/web/src/test/setup.ts +++ b/web/src/test/setup.ts @@ -226,6 +226,7 @@ afterEach(() => { window.sessionStorage?.clear() } vi.unstubAllEnvs() + vi.restoreAllMocks() // Restore mocks but preserve global stubs (e.g., localStorage) (#20007) vi.clearAllMocks() }) @@ -233,9 +234,8 @@ afterEach(() => { // In vitest 4.x with pool:'forks'/isolate:false and maxWorkers:1 (CI), all test // files in a shard share one worker process, so vi.stubGlobal() calls in one // file's beforeAll leak into subsequent files. -// afterAll in setupFiles runs once per worker (end of shard), not once per file, -// so this only partially mitigates contamination — see issue #20256 for the -// full architectural fix (pool:'forks', isolate:true). +// afterAll in setupFiles runs once per worker (end of shard), not once per file. +// Belt-and-suspenders: primary cleanup now happens in afterEach above (#20007). afterAll(() => { vi.unstubAllGlobals() }) diff --git a/web/vite.config.ts b/web/vite.config.ts index d86d5cde26..ee95acf167 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -319,9 +319,9 @@ export default defineConfig(({ mode }) => ({ // isolate: true ensures each test file runs in its own subprocess with a clean global environment, // preventing vi.stubGlobal() cross-contamination between files (#20256) isolate: true, - // poolOptions.forks removed — deprecated in Vitest 4 (#5860). - // maxWorkers/minWorkers above handle fork limits; teardownTimeout - // above handles worker termination timeout. + // CI: use threads pool instead of forks to prevent OOM from subprocess spawn storm (#20007) + // Threads share memory, no fork overhead. Local dev uses default (forks) for stronger isolation. + pool: process.env.CI ? 'threads' : undefined, coverage: { provider: 'v8', // Disable coverage.all to prevent force-importing source files that trigger