test(desktop): fix stale windows-child-process needles (not a wiring regression) - #114
Merged
Merged
Conversation
The "desktop background child processes opt into hidden Windows consoles" contract test has been silently broken since 2026-06-12 (d62979a, an unrelated feature commit that reformatted 5 spawn/ execFileSync call sites from single-line to multi-line). node --test only ever reported 1 failure because assert throws on the first failing needle and aborts the rest of that test() body — in reality 5 of 9 needles no longer matched. Root cause is test brittleness, not a wiring regression: every affected call site (pyExe python-version probe, git spawn, the two backend.command/args spawns, the uninstall spawn) still correctly wraps its options with hiddenWindowsChildOptions(...), so windowsHide:true is still applied on Windows. No user-visible console-flash regression. Fix: match needles against whitespace-collapsed source/needle text instead of exact substrings, so the assertion tracks call-site shape (identifier adjacency) rather than incidental line-wrapping. Verified the new matcher still catches a real regression (temporarily strayed the pyExe call's hiddenWindowsChildOptions wrapping locally -> test failed as expected; reverted). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
定谳:测试 stale,不是真回归
windows-child-process.test.cjs的「hidden Windows consoles」契约测试在 origin/main(含 v0.16.11)上红,与近期桌面 PR 无交集。已复现 + 用两个历史点实测定位根因:测试断言写死了单行execFileSync(...)/spawn(...)调用格式,后来 5 处调用被(与本测试无关的)重排版改成多行,断言随之失配 —— 但实际的hiddenWindowsChildOptions(...)保护在这 5 处全部原样保留,Windows 用户不受影响。失败断言原文
即
requireHiddenChildOptions(source, 'execFileSync(pyExe')在main.cjs里source.indexOf('execFileSync(pyExe')返回-1。引入 commit
d62979a6f34f64f2ed840f159aac66e24d7cad78("feat(desktop): composer status stack, live subagent windows, editable prompts NousResearch#44630",2026-06-12)—— 与本测试完全无关的一个功能 PR,顺带把 5 处execFileSync/spawn调用从单行重排成多行:(pyExe / resolveGitBinary / 两处 backend.command,backend.args / uninstall spawn,共 5 处;
hiddenWindowsChildOptions(...)包装在每一处都原样保留,只是换行位置变了)定谳证据链
node --test electron/windows-child-process.test.cjs→ 2 pass / 1 fail,断言原文如上。d62979a6f^(重排版前一个 commit)detached checkout →node --test3/3 全绿。d62979a6f(重排版 commit 本身)detached checkout → 复现同一失败(missing call site: execFileSync(pyExe)。坐实这就是引入点。
node --test的 fail-fast 掩盖了真实范围:requireHiddenChildOptions里的assert.notEqual一失败就抛出,同一个test()内后续的 needle 检查全部不会执行。直接用String.prototype.indexOf逐条重放全部 9 个 needle 发现:实际有 5 个 needle 失配(execFileSync(pyExe、spawn(resolveGitBinary()、spawn(backend.command, backend.args、hermesProcess = spawn(backend.command, backend.args、spawn(py, [...'uninstall'...]),node --test的报错只暴露了遍历顺序里第一个。main.cjs现状,5 处失配调用全部仍然把第三参数包在hiddenWindowsChildOptions({...})里(已用Read/grep逐处核对源码行号:~1946/~2092/~7258/~7481/~9655)。hiddenWindowsChildOptions定义本身(line 246-251)未变:!IS_WINDOWS || 已显式设置 windowsHide时透传,否则补windowsHide:true。即运行时行为没有任何变化。hiddenWindowsChildOptions(...)包装剥掉,重跑测试 → 立刻红,报错变成expected execFileSync(pyExe to wrap child-process options with hiddenWindowsChildOptions;还原后确认改动干净(git status只剩测试文件的合法 diff)。修复
requireHiddenChildOptions改成对「source 和 needle 都先去除全部空白字符」后再indexOf匹配 —— 断言追的是调用点的结构(标识符相邻顺序),不再依赖行内换行这种排版细节。这样下次 prettier/重排版再把某个多参数调用改成多行也不会重新致盲。顺手把唯一硬编码了换行的'reg'needle("execFileSync(\n 'reg'")简化回普通字符串,统一用新机制,不再需要手写转义。Windows 用户可见影响评估
无影响。9 个契约调用点(pyExe / reg / git / taskkill / command,args / curl / backend.command,args ×2 / uninstall)在当前
main.cjs上全部正确包了hiddenWindowsChildOptions(...);bootstrap-runner.cjs的 PowerShell runner 调用点同样完好。这是纯测试断言脆弱性问题,不是子进程黑框闪烁的功能回归,v0.16.11 已发的桌面版本没有引入新的 Windows 控制台可见性问题。验证
node --test electron/windows-child-process.test.cjs:3/3 全绿(此前 2 pass/1 fail)。npm run test:desktop:platforms完整清单(37 个测试文件,含本文件):606 tests / 605 pass / 1 skip(与本改动无关的既有 skip)/ 0 fail。tsc --noEmit:本改动仅涉及apps/desktop/electron/*.test.cjs;apps/desktop/tsconfig.json的include只有["src", "../shared/src"]且allowJs:false,electron/目录结构性地不在 TS 项目范围内,该文件改动不可能影响 typecheck 结果(未额外跑npm install去执行一个必然无关的检查)。范围说明
排查过程中额外发现 3 处未被本测试覆盖、且当前确实没有
hiddenWindowsChildOptions包装的 Windows 可达 spawn 调用(extractBundleArchive的tar.exe解压、runBundledTool、本地 coding-agent daemon 的runLocalAgentJob)—— 这与本次红测试的根因无关(这 3 处从一开始就不在测试覆盖范围内,不是 d62979a 引入的),是否需要修复是一个独立问题,不在本 PR 范围内,已另行反馈给 PM 评估。🤖 Generated with Claude Code