diff --git a/apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts b/apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts index ca3a01b6c..9b2e3ed78 100644 --- a/apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts +++ b/apps/ai-game-creator-shell/tests/gameDistributionPublish.test.ts @@ -45,28 +45,7 @@ function installNativeInvoke( } beforeEach(() => { - // Node 26 + jsdom 下 `window.localStorage` 可能没被注入(getter 返回 undefined)。 - // 测试只需要「清空」这一动作,缺失时补一个内存实现,别让环境差异把整文件打红。 - if (!window.localStorage) { - const store = new Map(); - Object.defineProperty(window, 'localStorage', { - configurable: true, - value: { - get length() { - return store.size; - }, - clear: () => store.clear(), - getItem: (key: string) => store.get(key) ?? null, - key: (index: number) => Array.from(store.keys())[index] ?? null, - removeItem: (key: string) => { - store.delete(key); - }, - setItem: (key: string, value: string) => { - store.set(key, String(value)); - }, - }, - }); - } + // `window.localStorage` 由 vitest setupFiles(`tests/jsdomLocalStorageSetup.ts`)兜底。 window.localStorage.clear(); }); diff --git a/apps/ai-game-creator-shell/tests/jsdomLocalStorageSetup.ts b/apps/ai-game-creator-shell/tests/jsdomLocalStorageSetup.ts new file mode 100644 index 000000000..72e01a11b --- /dev/null +++ b/apps/ai-game-creator-shell/tests/jsdomLocalStorageSetup.ts @@ -0,0 +1,37 @@ +// Node 26 + jsdom 组合下 `window.localStorage` 可能未被注入(getter 返回 undefined)。 +// 仓库里的 jsdom 用例只依赖内存语义(clear/getItem/setItem/removeItem/length/key), +// 缺失时补一个同形实现,避免环境差异把整份用例打红。 +// +// 这是 vitest `setupFiles` 的副作用文件,不是测试文件:它必须在每个 jsdom 用例文件 +// 自己的顶层代码之前跑完,所以不能靠某个用例文件里的 `beforeEach` 来兜底。 + +function installInMemoryLocalStorage(): void { + if (typeof window === 'undefined') return; + let existing: unknown; + try { + existing = window.localStorage; + } catch { + existing = undefined; + } + if (existing) return; + const store = new Map(); + Object.defineProperty(window, 'localStorage', { + configurable: true, + value: { + get length() { + return store.size; + }, + clear: () => store.clear(), + getItem: (key: string) => store.get(key) ?? null, + key: (index: number) => Array.from(store.keys())[index] ?? null, + removeItem: (key: string) => { + store.delete(key); + }, + setItem: (key: string, value: string) => { + store.set(key, String(value)); + }, + }, + }); +} + +installInMemoryLocalStorage(); diff --git a/vitest.config.ts b/vitest.config.ts index d5187097f..93386e122 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -94,6 +94,10 @@ export default defineConfig({ test: { environment: 'node', globals: true, + // Node 26 + jsdom 下 `window.localStorage` 可能未注入;这里在每个用例文件前补内存实现。 + setupFiles: [ + './apps/ai-game-creator-shell/tests/jsdomLocalStorageSetup.ts', + ], // 成功用例不回放被测代码写进 stdout / stderr 的内容:CI 日志里只保留每个 // 失败用例的断言摘要,避免 React act 警告、dev 调度日志这类噪音刷屏。 // 需要在本机排查时用 `vitest run --silent=false` 覆盖本次配置。