From d874a13a925454877aef34a54c258d9e2c1ef030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Wed, 16 Sep 2026 22:41:54 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E8=AE=B0=20Node=2026=20=E4=B8=8B=20vi?= =?UTF-8?q?test=20jsdom=20=E7=94=A8=E4=BE=8B=E7=9A=84=20localStorage=20?= =?UTF-8?q?=E5=9D=91=20-=20pitfalls=20=E8=AE=B0=E5=BD=95=EF=BC=9ANode=2026?= =?UTF-8?q?=20=E7=9A=84=E5=AE=9E=E9=AA=8C=E6=80=A7=20globalThis.localStora?= =?UTF-8?q?ge=20=E4=BC=9A=E9=A1=B6=E6=8E=89=20jsdom=20=E7=9A=84=20Storage?= =?UTF-8?q?=EF=BC=8C=E5=AF=BC=E8=87=B4=E5=8F=AA=E5=A3=B0=E6=98=8E=20jsdom?= =?UTF-8?q?=20=E7=9A=84=E7=94=A8=E4=BE=8B=E8=AF=BB=E5=88=B0=20undefined=20?= =?UTF-8?q?-=20=E7=BB=99=E5=87=BA=E8=B7=91=E6=B3=95=EF=BC=9ANODE=5FOPTIONS?= =?UTF-8?q?=3D--localstorage-file=3D=E2=80=A6=20=E5=90=8E=20clientApi=20?= =?UTF-8?q?=E4=B8=8E=20chatPromptPolish=20=E5=85=B1=2026=20=E9=A1=B9?= =?UTF-8?q?=E8=BD=AC=E7=BB=BF=20-=20=E9=87=8C=E7=A8=8B=E7=A2=91=E8=AF=81?= =?UTF-8?q?=E6=8D=AE=E6=9B=B4=E6=96=B0=E4=B8=BA=E5=85=A8=E9=87=8F=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=EF=BC=9A125=20files=20/=201676=20passed=20/=2017=20sk?= =?UTF-8?q?ipped=EF=BC=8Ctsc=20exit=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../【里程碑】DirectProject聊天真相源收敛-2026-09-16.md | 4 ++-- docs/project-memory/shared-memory/pitfalls.md | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md b/docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md index 560d1fb8d..e04466315 100644 --- a/docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md +++ b/docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md @@ -63,7 +63,7 @@ AGC 项目开发对话的显示与恢复只依赖两项输入:**项目对话 ## 证据要求 -- 自动化(已跑):`cargo test direct_thread`(25 条)、`cargo test direct_project_history`(20 条)、`cargo test export_bindings`(生成绑定与工作区无差异)、`npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts`(468 passed / 17 skipped)、`directThreadChat.test.ts` + `directTurnPresentation.test.ts` 单测、TypeScript 类型检查、ESLint 与 `prettier`。 +- 自动化(已跑):`cargo test direct_thread`(25 条)、`cargo test direct_project_history`(20 条)、`cargo test export_bindings`(生成绑定与工作区无差异)、`NODE_OPTIONS=--localstorage-file=… npx vitest run apps/ai-game-creator-shell/tests`(125 files / 1676 passed / 17 skipped)、`npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`(exit 0)、ESLint 与 `prettier`。 - 运行时(待补):真实 app-server 会话下的新回合、杀进程重开、页面重进、分页与终止。 - 边界:订阅过期、回执竞态、不可显示切片、无 `turn.completed` 的残回合、工具输出超长截断与脱敏。 -- 已知环境缺口:本容器内 `rehype-highlight` 未安装且远端拉包被策略禁用,`ChatMarkdownMessage` / `AgentMessageContent` 与 `chatPromptPolish` / `clientApi` 的环境型失败与本里程碑改动无关。 +- 环境注意:`rehype-highlight` 已装齐后 `ChatMarkdownMessage` / `AgentMessageContent` 转绿;Node 26 下 vitest 的 jsdom 用例需要 `--localstorage-file` 才能拿到 `window.localStorage`(`clientApi.test.ts` / `chatPromptPolish.test.tsx`),已记入 `docs/project-memory/shared-memory/pitfalls.md`。 diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index 444798e15..1458cb070 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -5616,3 +5616,10 @@ Cocos Creator 根目录由 `package.json.creator.version` 与普通 `assets/` - fixture 子进程统一清除 `GIT_*` 环境,并用一次性外层 linked worktree 验证引用、索引、配置不变;原有工程检查规则保持完整,不能用逐项关闭规则修复 fixture 污染。 - Vitest 的 `toHaveBeenCalledWith` 匹配任意一次调用,失败输出会列出其它命令;应先定位相同命令的真实参数差异,不能由其它调用的序号推断时序故障。 - 存在后台轮询的 IPC mock 不应要求目标命令占据全局最后一次调用。验证刷新时先记录调用边界,再筛选该边界之后的目标命令,严格核对其最后一次参数,避免后台查询影响断言,也避免旧调用掩盖刷新未执行。 + +## 2026-09-16 Node 26 下 vitest 的 jsdom 用例拿不到 window.localStorage + +- **现象**:只声明 `@vitest-environment jsdom` 的用例里 `window.localStorage` 是 `undefined`(典型报错 `Cannot read properties of undefined (reading 'clear')`);而 `appSurface.test.ts` 里同样访问 `window.localStorage` 却一切正常。 +- **原因(已核对,不是推断)**:Node 26 在 `globalThis` 上定义了实验性 `localStorage` 访问器,不传 `--localstorage-file` 时它返回 `undefined`。vitest 0.34 的 jsdom 环境把 jsdom window 的描述符复制到全局时,不会覆盖 `globalThis` 上已存在的键,于是 jsdom 真正的 `Storage` 被 Node 的 `undefined` 顶掉。`appSurface` 之所以不受影响,是因为 `apps/ai-game-creator-shell/tests/appSurface/harness.ts` 自己用 `Object.defineProperty(window, 'localStorage', …)` 挂了内存实现。 +- **处理**:跑这类用例时给 Node 加 `--localstorage-file`,例如 `NODE_OPTIONS="--localstorage-file=/tmp/vitest-node-localstorage" npx vitest run `;`apps/ai-game-creator-shell/tests/clientApi.test.ts` 与 `chatPromptPolish.test.tsx` 加这个开关后 26 项全绿。不要改业务代码或往测试里塞假 storage 来绕过。 +- **关联**:`vitest.config.ts`(`environment: 'node'` + 用例内 docblock 切 jsdom)、`apps/ai-game-creator-shell/tests/appSurface/harness.ts` 的内存 localStorage 垫片。