// vite.test.config.ts — Plan 01-11 two-bundle separation. // // Extends the production `./vite.config.ts` with the following delta knobs: // 1. `mode: 'test'` — Vite statically replaces `import.meta.env.MODE` // everywhere in the input source with the string literal `'test'`. // 2. `define: { __MOKOSH_UAT__: 'true' }` — the dedicated build-time // token gating the test-hook dynamic imports in // src/background/index.ts + src/offscreen/recorder.ts (Plan 01-11 // Task 2). With this set to `true` the `if (__MOKOSH_UAT__)` branch // becomes a live branch and Rollup KEEPS the dynamic imports; // production builds (vite.config.ts sets it `false`) tree-shake // them away (verified by the Tier-1 grep gate // `tests/background/no-test-hooks-in-prod-bundle.test.ts`). // 3. `build.outDir: 'dist-test'` + `emptyOutDir: true` — emit to a // SEPARATE directory so a `npm run build` immediately after this // build does not clobber. Puppeteer harness consumes this path via // `puppeteer.launch({ enableExtensions: [] })`. // 4. `build.modulePreload: { polyfill: false }` — CRITICAL SW FIX. // Vite's default module-preload polyfill calls // `document.getElementsByTagName` + `document.querySelector` at // module init in EVERY chunk that contains a dynamic import. The // production bundle has no dynamic imports (the test-hook gate is // dead code; tree-shaken). The test bundle HAS the dynamic // `await import('../test-hooks/sw-hooks')` — so the preload // polyfill gets included in the SW chunk. SWs have no DOM — // `document` is undefined — and the polyfill throws on the very // first await, killing the SW module init silently (no console // output, just a dead worker). Disabling the polyfill removes the // `document.*` references; modern Chrome (and our MV3 target ≥88) // supports native dynamic import without the polyfill. // Empirically verified: with the polyfill enabled, the test // bundle's SW never reaches `Service Worker initializing` log; // with it disabled, the SW initializes and chrome.runtime.onMessage // handlers respond. See Plan 01-11 PROTOTYPE research session. // // PROTOTYPE addition: the prototype harness page at // `tests/uat/prototype/extension-page-harness.html` is added as a // Rollup input so the test build emits it. Production builds do NOT // include the prototype page (vite.config.ts has no such input). // // References: // - Vite mergeConfig: https://vite.dev/guide/api-javascript.html#mergeconfig // - Vite environment variables: https://vite.dev/guide/env-and-mode.html // - Vite build.modulePreload: https://vite.dev/config/build-options.html#build-modulepreload // - Rollup multi-entry inputs: https://rollupjs.org/configuration-options/#input import { defineConfig, mergeConfig, type UserConfigExport } from 'vite'; import baseConfig from './vite.config'; const baseAsExport: UserConfigExport = baseConfig; export default defineConfig(({ command, mode }) => mergeConfig( typeof baseAsExport === 'function' ? baseAsExport({ command, mode, isPreview: false, isSsrBuild: false }) : baseAsExport, { mode: 'test', // `define` performs a static text replacement at build time. We use a // dedicated `__MOKOSH_UAT__` token (NOT `import.meta.env.MODE`) for the // hook-import gate because vitest defaults its mode to 'test' too — // gating on MODE would activate the hooks during unit tests and // overwrite their vi.fn() mocks for chrome.notifications.create etc. // The dedicated token is `false` everywhere except in this test bundle // (Plan 01-11 RESEARCH §6 augmented — keeps Vite tree-shake semantics // intact while sidestepping the vitest cross-contamination). // Reference: https://vite.dev/config/shared-options.html#define define: { __MOKOSH_UAT__: 'true', }, build: { outDir: 'dist-test', emptyOutDir: true, // CRITICAL: see file header comment §4 — disables the // document.*-using module preload polyfill that crashes SW init. modulePreload: { polyfill: false }, rollupOptions: { input: { // Add the prototype harness page so it lands in dist-test/ // and becomes reachable as // chrome-extension:///tests/uat/prototype/extension-page-harness.html prototype_harness: 'tests/uat/prototype/extension-page-harness.html', }, }, }, }, ), );