Repository navigation
fix(web-shell): Replace undefined mock in split rerender tests (#11404) - #11406
Conversation
The two "does not rerender App for other split sessions" tests referenced mockUseDaemonActivePromptBridge, which is not defined anywhere in App.test.tsx — a deterministic ReferenceError that failed the main-branch CI Test job at 70cf363. The intended render spy is mockUseDaemonSessionActivityBridge: App calls useDaemonSessionActivityBridge on every render, and this file already uses that mock as the render-call witness elsewhere. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
E2E / Verification Report — Issue #11404SummaryMain-branch CI failed at Root causeCommit FixPoint the three references at the intended, existing render spy Mutation probeTemporarily changed App.tsx so every pending-panes report forces a rerender ( Environment noteThe sandbox has no GitHub credentials, so the CI run logs for run 34257817936 could not be fetched; the failure was reproduced locally at the exact failing commit ( Verification
中文说明E2E / 验证报告 — Issue #11404摘要主分支 CI 在提交 根因提交 修复将这三处引用指向本来就打算使用的、已存在的渲染探针 变异探针临时修改 App.tsx,让每次 pending-panes 上报都强制触发 rerender( 环境说明沙箱内没有 GitHub 凭据,无法拉取 run 34257817936 的 CI 日志;改为在出问题的确切提交( 验证
🧠 Handled by Qwen Code · model/模型 |
) The "does not rerender App for other split sessions" tests asserted mockUseDaemonSessionActivityBridge toHaveBeenCalled() after rerender(), but nothing cleared the spy since the top-level beforeEach mockReset(), so it already held setup-time calls from renderApp()/flush()/the split click and the assertion passed whether or not the rerender rendered App. Clearing it immediately before rerender() makes the guard measure that render only; the trailing mockClear() stays to isolate the loop below. Mutation-verified: with the clear in place, deleting rerender() or the useDaemonSessionActivityBridge() call in App.tsx turns both parameterized cases red at the guard (both previously stayed green). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
🤖 Addressed the latest review feedback (round 1/10). What changed, and what I pushed back on: · 已处理最新评审反馈(第 1/10 轮)。改动内容与我反驳保留之处如下: Address review round — PR #11406Feedback dispositions[rc:3962062547] — [Suggestion] Vacuous
|
|
@qwen-code /triage |
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round — no action requiredFeedback triageEvery item in this round's feedback was classified; none is actionable:
Prior inline finding re-verified against the current headThe PR's only inline comment, [rc:3962062547] (Suggestion, from the previous evaluation window), was addressed by commit
The previously landed fix therefore provably holds: the positive guard now measures the rerender alone, and the three OutcomeNo commit was made; the working tree is unchanged. The round contains no verified finding, no failing check, and no maintainer request — nothing to implement, decline, defer, or escalate. Verification
中文说明Autofix 本轮——无需改动反馈分诊本轮反馈中的每一项都已分类;均不具备可执行性:
针对当前 head 复核了此前的行内发现本 PR 唯一的行内评论 [rc:3962062547](Suggestion,来自上一个评估窗口)已由提交
因此,此前落地的修复可被证明仍然有效:正向守卫现在只度量本次 rerender,循环中的三个 结论本轮未创建任何提交;工作树保持不变。本轮没有已验证的发现、没有失败的检查、也没有维护者的要求——没有需要实现、拒绝、推迟或升级处理的事项。 验证
Base-conflict check · 基分支冲突检查: no conflict with main. · 与 main 无冲突。 🧠 Handled by Qwen Code · model/模型 |
Maintainer verification — local build + real test executionVerified on a dedicated worktree at the PR head Verdict: recommend merge. The fix is correct, minimal, and — with the second commit — non-vacuous. Two documentation nits below, neither blocking. 1. The failure reproduces exactly, and it is the whole failureRestoring only Running the whole web-shell suite at that content gives numbers byte-identical to CI job
This closes the PR's own "not validated" caveat: the red run contained no other failures — the two It is also still live. Five other open PRs currently have a red 2. PR head is green3. The assertions bite — 7 mutants, all behaving as predicted
Instrumenting the spy confirms the mechanism numerically. Before commit 2 the guard was reading 6–7 accumulated setup-time calls; after it, exactly the 1 call made by the render it claims to observe: 4. Post-merge safety
5. How this reached
|
CI @ 70cf363395 |
本地同内容 | 本地 PR head | |
|---|---|---|---|
| Test Files | 1 failed | 287 passed (288) | 1 failed | 287 passed (288) | 288 passed (288) |
| Tests | 2 failed | 6710 passed (6712) | 2 failed | 6710 passed (6712) | 6712 passed (6712) |
这填补了 PR 自述的"未验证"缺口:那次红色运行中没有其他失败——两个 does not rerender App for other split sessions 用例是唯一红色 job 里唯一红色套件中唯一红色的测试。Fixes #11404 是精确的,不是近似的。
问题目前仍在扩散:另有 5 个其他开放 PR(#11397、#11396、#11392、#11369、#11360)的 Test (ubuntu-latest, Node 22.x) 正因同一个 ReferenceError 变红。它阻塞的是全仓库的合并信号,而不只是 main 自己的车道。
2. PR head 全绿
两个目标测试通过;整套 web-shell 套件 288/288 文件、6712/6712 测试通过(见上方第二张截图)。
3. 断言确实有效 —— 7 个变异体,全部如预期
| 变异体 | 结果 | 变红位置 | 说明 |
|---|---|---|---|
| (对照) PR head 未变异 | 2 passed | — | 基线 |
删除 rerender() |
2 failed | toHaveBeenCalled() 守卫 |
守卫现在确实度量该次渲染——第 1 轮评审提出的验收标准已满足 |
删除 rerender(),仅在第 1 个提交上 |
1 failed / 1 passed | 循环处,守卫仍绿 | 复现第 1 轮的发现:没有第 2 个提交,守卫不可能失败 |
| 仅第 1 个提交,未变异 | 2 passed | — | 仅靠第 1 个提交即可消除红色;第 2 个提交是严格性修复,而非正确性前提 |
删除后置的 mockClear() |
2 failed | 循环处 | 后置清空是承重的,并非冗余 |
新增的清空改为 mockReset() |
2 failed | TypeError: Cannot destructure property 'hasActivePrompt' |
必须是 mockClear,绝不能是 mockReset |
生产代码: 从 App 渲染体中移除 useDaemonSessionActivityBridge(...) |
2 failed | 守卫处 | 守卫绑定的是 App 真正调用的 hook,而非测试脚手架 |
生产代码: 让每次 pending-panes 上报都翻转 outerSplitPanePending |
2 failed | 循环处 | 负向断言确实能检测到 App 的重渲染 |
对 spy 的插桩计数从数值上印证了机制:第 2 个提交之前,守卫读到的是 6–7 次挂载期累积调用;加入之后,恰好只有它声称观察的那次渲染所产生的 1 次调用(见上方第四张截图)。
4. 合并后的安全性
本 PR 的 base 与当前 main(1f890086f1)之间,packages/web-shell 没有任何改动;合并无冲突;合并树中 App.test.tsx 的 blob 哈希与我实测的文件完全一致——因此上面的本地绿色结果就是合并后的状态,而不是对它的近似。
5. 它是怎么进入 main 的(背景信息,非本 PR 的缺陷)
值得记录,因为 PR 确实说明了它自己的沙箱无法判定这一点:
- feat(web-shell): Improve split-view session navigation #11250 的分支本身是绿色且正确的:在其 head
52484fecf3上,该 mock 已声明、已接入模块 mock,名字是mockUseDaemonActivePromptBridge。 - 51 分钟后 fix(web-shell): show session active work #11267 合入
main,把该 hook 及其 mock 重命名为useDaemonSessionActivityBridge/mockUseDaemonSessionActivityBridge。 - squash 合并同时采纳了
main的重命名和 feat(web-shell): Improve split-view session navigation #11250 新增的三行。文本上无冲突,语义上已损坏——典型的语义冲突。 - 没有任何静态门禁能发现它:
packages/web-shell/tsconfig.json排除了client/**/*.test.tsx,因此npm run typecheck在损坏文件上退出码为 0,eslint同样为 0(该文件的no-undef被显式关闭——已用eslint --print-config核实)。只有真正运行测试才能捕获。 ci.yml没有push触发器,且据其文件头注释合并队列亦未启用,因此没有任何环节复验 squash 后的树——最先发现的是事后的主干失败监测(Main CI failed: Qwen Code CI on 70cf3633950b #11404)。
系统性修复(启用合并队列,或把测试文件纳入类型检查)不属于本 PR 范围;本 PR 是正确的即时修复。
6. squash 前的两条非阻塞小问题
- 描述相对第 2 个提交已经过时。 正文仍写着"仅三行、仅测试文件的改动",并把修复完整描述为"重新指向三处断言";而实际 diff 是 +5/−3,且新增的
mockClear()——真正让守卫具备失败能力的那处改动——在正文中完全没有提及。由于这会 squash 成单条提交信息,正文值得补一句。 - "未验证 / 超出范围"那一条可以删掉。 它写的是"红色运行中是否还包含无关 flaky 失败,从这里无法判定"。是可以判定的:没有——见上文第 1 节。
|
🤖 Reviewed the latest feedback — no changes needed. Why, point by point: · 已审阅最新反馈——无需改动。逐点说明原因如下: Autofix round — no code changeTriaged all feedback newer than the last evaluation. There is exactly one new Feedback disposition
|
… (#11406) * fix(web-shell): Replace undefined mock in split rerender tests (#11404) The two "does not rerender App for other split sessions" tests referenced mockUseDaemonActivePromptBridge, which is not defined anywhere in App.test.tsx — a deterministic ReferenceError that failed the main-branch CI Test job at 70cf363. The intended render spy is mockUseDaemonSessionActivityBridge: App calls useDaemonSessionActivityBridge on every render, and this file already uses that mock as the render-call witness elsewhere. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(web-shell): Clear spy before rerender so the guard can fail (#11406) The "does not rerender App for other split sessions" tests asserted mockUseDaemonSessionActivityBridge toHaveBeenCalled() after rerender(), but nothing cleared the spy since the top-level beforeEach mockReset(), so it already held setup-time calls from renderApp()/flush()/the split click and the assertion passed whether or not the rerender rendered App. Clearing it immediately before rerender() makes the guard measure that render only; the trailing mockClear() stays to isolate the loop below. Mutation-verified: with the clear in place, deleting rerender() or the useDaemonSessionActivityBridge() call in App.tsx turns both parameterized cases red at the guard (both previously stayed green). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…#11276) * feat(web-shell): add web previews with saved delivery history * fix(serve): register saved preview telemetry route * test(cli): update telemetry route drift count * fix(web-shell): reclaim snapshot files and address preview findings (QwenLM#11276) * fix(web-shell): Replace undefined mock in split rerender tests (QwenLM#11404) (QwenLM#11406) * fix(web-shell): Replace undefined mock in split rerender tests (QwenLM#11404) The two "does not rerender App for other split sessions" tests referenced mockUseDaemonActivePromptBridge, which is not defined anywhere in App.test.tsx — a deterministic ReferenceError that failed the main-branch CI Test job at 70cf363. The intended render spy is mockUseDaemonSessionActivityBridge: App calls useDaemonSessionActivityBridge on every render, and this file already uses that mock as the render-call witness elsewhere. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(web-shell): Clear spy before rerender so the guard can fail (QwenLM#11406) The "does not rerender App for other split sessions" tests asserted mockUseDaemonSessionActivityBridge toHaveBeenCalled() after rerender(), but nothing cleared the spy since the top-level beforeEach mockReset(), so it already held setup-time calls from renderApp()/flush()/the split click and the assertion passed whether or not the rerender rendered App. Clearing it immediately before rerender() makes the guard measure that render only; the trailing mockClear() stays to isolate the loop below. Mutation-verified: with the clear in place, deleting rerender() or the useDaemonSessionActivityBridge() call in App.tsx turns both parameterized cases red at the guard (both previously stayed green). Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> --------- Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * test(cli): complete worktree ACP config fixture * fix(acp-bridge): keep restored saved-webpage records when snapshot retain fails (QwenLM#11276) * test(cli): make dangling-include screen test host-independent (QwenLM#11276) The test asserts runOneMutant's detail names vitest, which only holds when findVitestBin throws "not found" from the bare fixture — but Node resolution walks up from the probe tree, so a node_modules above the runner's TMPDIR (observed on self-hosted CI, where jobs share one /tmp) resolves a vitest, the probe then runs for real, and the detail carries no 'vitest'. Plant a shadow vitest that declares no bin in the fixture: the innermost node_modules wins resolution on every host, so the throw is deterministic. Same pattern as the runControlMutant shadow in this file. * test(web-shell): align branding fixtures with workspace and sidebar behavior * fix(acp): preserve non-strict ingestion on snapshot reference errors --------- Co-authored-by: qwen-code-ci-bot <qwen-code-ci-bot@users.noreply.github.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> Co-authored-by: qwen-code-dev-bot <qwen-code-dev-bot@users.noreply.github.com>






What this PR does
Repairs two Web Shell unit tests that fail on every run. The split-view navigation change (#11250) added two
does not rerender App for other split sessionstest variants whose assertions reference a mock identifier that does not exist anywhere in the test file, so both tests throw aReferenceErrorbefore completing. The fix points those assertions at the render spy the file already defines and wires into its module mock — the hook the App component calls on every render — restoring the intended "foreign split sessions must not rerender App" coverage with a three-line, test-only edit.Why it's needed
This is the cause of the main-branch CI failure tracked in #11404: the
Test (ubuntu-latest, Node 22.x)job fails inRun tests and generate reportsat commit70cf363395because the web-shell vitest suite fails deterministically. The failure reproduces on every run and every retry, so CI's test-retry setting cannot absorb it, and every subsequentmainrun stays red until the reference is fixed.Reviewer Test Plan
How to verify
On the base commit, run the web-shell suite and observe the failure; on this branch, observe it pass:
cd packages/web-shell && npx vitest run --config vitest.config.ts App.test.tsx -t "does not rerender App for other split sessions"ReferenceError: mockUseDaemonActivePromptBridge is not definedatApp.test.tsx:28940.The test intent is unchanged: after an initial pending-panes report, reports containing only other sessions' ids must not rerender App. A mutation probe confirms the assertions still bite — forcing a rerender on every report makes both tests fail again.
Evidence (Before & After)
N/A (test-only change, no UI behavior affected)
Tested on
Environment (optional)
N/A — vitest unit tests only (Node 22, same as the failing CI lane).
Risk & Scope
Linked Issues
Fixes #11404
中文说明
本 PR 做了什么
修复两个必定失败的 Web Shell 单元测试。split-view 导航改动(#11250)新增了两个
does not rerender App for other split sessions测试变体,其断言引用了一个在整个测试文件中根本不存在的 mock 标识符,导致两个测试在完成前抛出ReferenceError。本次修复把这些断言指向该文件早已定义并接入模块 mock 的渲染探针——即 App 组件每次渲染都会调用的那个 hook——仅用三行、仅测试文件的改动恢复了"外部 split 会话不应触发 App rerender"这一原有覆盖意图。为什么需要
这正是 #11404 跟踪的主分支 CI 失败原因:
Test (ubuntu-latest, Node 22.x)任务在提交70cf363395上的Run tests and generate reports步骤失败,因为 web-shell 的 vitest 套件确定性失败。该失败每次运行、每次重试都会复现,CI 的测试重试设置无法吸收;在修复该引用之前,后续每次main运行都会保持红色。评审验证计划
如何验证
在基线提交上运行 web-shell 套件可观察到失败;切到本分支后可观察到通过:
cd packages/web-shell && npx vitest run --config vitest.config.ts App.test.tsx -t "does not rerender App for other split sessions"ReferenceError: mockUseDaemonActivePromptBridge is not defined,位置在App.test.tsx:28940。测试意图不变:在首次 pending-panes 上报之后,仅包含其他会话 id 的上报不应触发 App rerender。变异探针确认断言仍然有效——强制每次上报都 rerender 会让这两个测试再次失败。
前后对比证据
N/A(仅测试改动,不影响任何 UI 行为)
已测试平台
环境(可选)
N/A —— 仅 vitest 单元测试(Node 22,与失败的 CI 车道一致)。
风险与范围
关联 Issue
修复 #11404