test(web-shell): fix brand test breakage from the compact-footer interaction - #11544
test(web-shell): fix brand test breakage from the compact-footer interaction#11544wenshao wants to merge 1 commit into
Conversation
…raction Two test-side breakages from main's recent merges: - The brand sidebar tests assert the version tooltip, which the compact footer intentionally hides below its breakpoint; render those two cases above the breakpoint. - The workspace loading test asserts the exact fetch list, but the brand fetch rides beside capabilities on its own deferred channel, so whether it lands before the assertion is scheduling-dependent (red in CI, green on a fast machine); filter it out of the assertion, keeping the "loads exactly once" pin.
|
Thanks for the PR — unbreaking main's Template looks good ✓ — all required headings, the Tested-on table, Risk & Scope, and the Chinese Problem: real and confirmed, not theoretical. I checked the base tree rather than taking the description's word for it. Direction: aligned. Test-only, restores a signal every other PR depends on, and it deliberately leaves #11470's compact-mode behaviour alone instead of re-litigating it — the right call, and the PR says so explicitly. One thing to settle before this goes further, though: #11542 is already open against the exact same two files, and it's green. It's the autofix lane's PR for #11534 — Size: not applicable. Both changed files are Approach: the sidebar half is surgical and matches how the sibling Risk: no elevated risk signals — Stage 1e matched nothing, both files are tests. Moving on to code review, with the #11542 overlap flagged for a human call. 🔍 中文说明感谢贡献 —— 修复 main 上 模板完整 ✓ —— 所有必需小节、Tested-on 表格、Risk & Scope 以及中文说明都齐全。 问题:真实且已确认,不是理论性的。 我核对的是基线代码,而不是只信 PR 描述。 方向:对齐。 纯测试改动,恢复了其他所有 PR 都依赖的信号,并且有意不去动 #11470 的 compact 模式行为 —— 这个取舍是对的,PR 里也写明了。 但有一件事需要先定:#11542 已经针对完全相同的两个文件开着,而且它是绿的。 那是 #11534 的 autofix 产出 —— 规模: 不适用。两个改动文件都是 方案: sidebar 那一半改得很精准,和同级 风险: 无升级风险信号 —— Stage 1e 未命中,两个文件都是测试。 进入代码审查,同时把 #11542 的重叠标出来交由人工定夺。 🔍 — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
Code reviewBefore reading the diff I wrote down what I'd do myself, from the two failure mechanisms alone: for the sidebar, mount above the 344px footer breakpoint in the tests that query the version tooltip, the way the sibling footer-version suite already does; for the loading test, give the fetch mock a
What it stops doing is pinning brand at all, and the part I'd actually change is one level down: the mock still has no On the overlap with #11542, which is the reason I'm not approving: that PR makes the mocking fix — Test evidenceThis is an unattended CI run, so per the gate's rules I did not build or execute anything from this branch — the evidence below is this PR's own CI, read through the API on the reviewed commit. Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 The So the remedy is a merge or rebase of Not verified: that the two suites are actually green on CI. The check that would show it hadn't reported when this review ran. The description's "full web-shell suite 300 files / 7113 tests pass" and the before/after reproduction on Sandboxed verification would settle the part CI can't: 中文说明代码审查 在读 diff 之前,我先只根据两个失败机制写下了自己的方案:sidebar 那边,在需要查询版本 tooltip 的测试里以高于 344px footer 断点的宽度挂载,就像同级的 footer-version 测试套件已有的做法;加载测试那边,给 fetch mock 补一个
它不再做的是对 brand 的任何约束。而我真正想改的地方在下一层:mock 仍然没有 关于与 #11542 的重叠,这也是我不批准的原因:那个 PR 做的正是 mock 方案 —— 测试证据 这是无人值守的 CI 运行,因此按 gate 规则我没有构建或执行本分支的任何代码 —— 下面的证据是通过 API 读取的、本 PR 自己在被审查 commit 上的 CI 结果。
未验证:这两个套件在 CI 上是否真的绿。 能说明这一点的检查在本次审查运行时还没有出结果。描述里的"web-shell 全套件 300 文件 / 7113 测试通过"以及在 沙箱验证可以补上 CI 补不了的那部分: — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
|
Confidence: 3/5 — the sidebar fix is correct and I'd merge it as written; the loading-test fix trades assertion strength for timing robustness, and #11542 already fixes both files and is green, so which one lands is a human call rather than a gate call. ⏸️ Deferring — not approving, not requesting changes. Stepping back: the problem is real and I confirmed it independently rather than accepting the framing — #11534 tracks main's red Two things keep me from approving. The first is arithmetic, not judgement: #11542 edits the same lines in the same two files and its The second is that the loading-test half leaves the nondeterminism in place. Filtering Also blocking in the mundane sense: What would move me to approve: a decision that this is the PR that lands (and #11542 closes), the rebase that clears the freshness gate, and On the escalation itself: I tried to resolve an accountable owner deterministically and there isn't one to hand — 中文说明Confidence: 3/5 —— sidebar 的修复是正确的,照原样我就会合;加载测试的修复用断言强度换了时序鲁棒性,而 #11542 已经修了同样两个文件并且是绿的,所以合哪个是人工决定,不是 gate 能定的。 ⏸️ 暂缓 —— 不批准,也不 request changes。 退一步看:问题是真实的,而且我是独立核实的,没有直接接受 PR 的叙述 —— #11534 跟踪着 main 上红灯的 有两点让我不批准。 第一点是算术问题,不是判断问题:#11542 改的是同样两个文件里同样的行,而它的 第二点是加载测试那一半把不确定性留在了原地。把 还有一个通俗意义上的阻塞: 能让我转为批准的条件:确定由本 PR 落地(并关掉 #11542)、清掉过期 gate 的 rebase,以及新 head 上 关于升级路径:我尝试确定性地解析出一个责任人,但手头没有 —— — Qwen Code · qwen3.8-max-2026-09-02 Reviewed at |
🖼️ web-shell visual previewRendered against a mock daemon (no real backend): the PR base vs this PR head Screenshots · before / after✅ No screenshot changes against the PR base. Full-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
|
Qwen Code review timed out. Qwen review timed out after 5400 seconds (of the 90-minute budget). For large PRs, retry with a longer timeout by commenting: |
Local verification report — PR #11544I built a real three-arm environment on Linux and ran the two suites this PR touches, plus instrumented and soak probes. The breakage this PR describes is real and this PR does fix it — but the same breakage was already fixed on Harness
Separate git worktrees, real 1. The problem is real, and this PR fixes itArm A fails exactly as described — 6 loading variants on the extra 2. …but
|
| mock fallthrough throws | brand retry ARMED |
brand SETTLED via 404 |
|
|---|---|---|---|
| #11544 | 9 | 6 | 0 |
#11530 (on main) |
0 | 0 | 6 |
Under this PR, all 6 loading tests drive the provider down its transport-failure branch and leave a BRAND_RETRY_DELAY_MS = 2000 timer armed, cleaned up only by the unmount. #11530's 404 fixture models an older daemon without the route — the one definitive "no brand here" answer production actually handles — and settles immediately.
In fairness: this is latent, not active. I tried to make the armed timer fire — pinned to a single core against 10 CPU hogs, the slowest loading test still ran 900 ms against the 2000 ms delay, and the retry never fired in any run. It's a fixture-fidelity difference, not a bug I can demonstrate breaking anything.
5. What merging this would actually do
WebShellSidebar.brand.test.tsxauto-merges into a double fix:main'sbeforeEachalready sets the width to360, and this PR's per-testsetItem(..., '400')layers on top of it. Both are above the 344 px breakpoint, so it's inert duplication.WorkspaceSessionProvider.loading.test.tsxis a hard conflict between the two assertions — resolving it means picking one, and §3–4 say the one onmainis the better of the two.
Recommendation
Close #11544 as superseded by #11530. The diagnosis was right, the sidebar fix is equivalent to what landed, and the loading fix is the weaker of the two on the evidence above.
Two related cleanups while you're here:
- fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11534) #11542 is in the same position and is now a strict no-op: both of its test files are byte-identical to
main. It can be closed too. - Main CI failed: Qwen Code CI on 53964ef7e272 #11534 / Main CI failed: Qwen Code CI on d8baa8730fc6 #11535 / Main CI failed: Qwen Code CI on b1ac3e297023 #11539 / Main CI failed: Qwen Code CI on 1097b9fe0af3 #11543 / Main CI failed: Qwen Code CI on b3d022b35724 #11546 / Main CI failed: Qwen Code CI on ecae0371767e #11528 all carry this signature on pre-fix commits and should close once a
mainrun on a post-2488d12d8bcommit is green.
The one thing genuinely worth a second look, independent of this PR: main's pin now encodes StrictMode's remount double (['GET /capabilities', 'GET /brand', 'GET /brand']). That's more informative than the filtered version but also more coupled to React's StrictMode behavior. If that coupling bothers you, it's a two-line follow-up on main, not a reason to keep this branch alive.
Scope of this verification: Linux only (Node 22.22.2, 16 cores). Both suites are jsdom-level and platform-independent, but I did not run the macOS or Windows lanes. Figures are terminal captures of the actual runs; the harness is reproducible from the arm commits above.
中文版
PR #11544 本地验证报告
我在 Linux 上搭建了真实的三臂环境,跑了本 PR 涉及的两个 suite,并补了插桩探针与压力 soak。本 PR 描述的破坏真实存在,本 PR 也确实修好了它 —— 但同样的破坏已经被 #11530 在 main 上修复,而 #11530 在本 PR 开启后 3.5 分钟就合入了。 我的建议是以「已被取代」关闭本 PR;同时我把两种修法真正分歧的那一处证据也列了出来,让这个取舍基于证据,而不是"谁先合入"。
环境
| commit | 说明 | |
|---|---|---|
| A | ecae037176 |
本 PR 的 merge-base,也是 main CI 失败 issue #11528 对应的提交 |
| B | ce53ba18cf |
本 PR 的 head |
| C | 424e40cc1f |
当前 origin/main(已含 #11530 = 2488d12d8b) |
独立 git worktree,用共享 lockfile(三臂完全一致)真实 npm install,并真实构建 @qwen-code/sdk/daemon 所依赖的 core → acp-bridge → sdk 链。B 臂与 C 臂的 DaemonWorkspaceProvider.tsx 中 fetchBrand() 字节相同(md5 fb602a58…),两臂只有测试 fixture 不同,因此下面的对比是同条件对照。
1. 问题真实存在,本 PR 也确实修好了
A 臂的失败与描述完全一致:6 个 loading 变体因多出的 GET /brand 失败,2 个 sidebar tooltip 断言因 expected null not to be null 失败。B 臂 16/16。对诊断和修法本身没有异议。
2. 但 main 已经是绿的
- C 臂(当前
origin/main)两个 suite 16/16,整个web-shell包 302 文件 / 7150 测试全绿。 - 所有仍开着的
Main CI failedissue —— Main CI failed: Qwen Code CI on ecae0371767e #11528、Main CI failed: Qwen Code CI on 53964ef7e272 #11534、Main CI failed: Qwen Code CI on d8baa8730fc6 #11535、Main CI failed: Qwen Code CI on b1ac3e297023 #11539、Main CI failed: Qwen Code CI on 1097b9fe0af3 #11543、Main CI failed: Qwen Code CI on b3d022b35724 #11546 —— 对应的提交都早于2488d12d8b。没有任何一个失败发生在包含该修复的提交上。 - 本 PR 上红掉的
Lint & Static并不是 lint 错误:它是 lint gate 新鲜度检查,报告.github/workflows/ci.yml在本分支上次同步 main 之后发生了变化(17990c330da8)。
这不是粗心的重复提交:本 PR 开于 07:47:43Z,#11530 合于 07:51:15Z,是一次撞车,输了四分钟。
3. loading 测试的改动理由经不起实测
这是两种修法唯一实质分歧的地方,值得用证据而不是先后顺序来定。
PR 描述称该断言"CI 调度下必红,本地快机上必绿",并据此把断言改为 calls.filter(c => c !== 'GET /brand')。实测结果:
- 在 merge-base 上、无压力、16 核机器:20/20 次全部失败,6 个变体每次都失败。brand 请求 100% 在断言之前发出。原断言不是在竞态,只是过期了。
- 把
vitest用 taskset 绑到 2 核并施加 6 个忙循环(3.8 倍墙钟减速,单轮 ~3.0 s → ~11.5 s):main 上更严格的断言['GET /capabilities', 'GET /brand']25/25 全过;本 PR 的过滤式断言同样 25/25。
也就是说,放宽后的断言并未换来可测量的稳健性,反而放弃了"/brand 确实被请求过"这一断言。
4. Fixture 保真度:两种修法并不等价
本 PR 把 GET /brand 从断言中过滤掉,却没有给 mock 加 /brand 路由 —— 于是每一次 brand 请求都落到 mock 的兜底 throw new Error(`Unexpected request: ${url.pathname}`) 上。对 mock 和 provider 同时插桩后:
| mock 兜底 throw | brand retry ARMED |
brand SETTLED via 404 |
|
|---|---|---|---|
| #11544 | 9 | 6 | 0 |
| #11530(main) | 0 | 0 | 6 |
在本 PR 下,6 个 loading 测试全部把 provider 驱入传输失败分支,并留下一个 BRAND_RETRY_DELAY_MS = 2000 的计时器,只能靠 unmount 清理。#11530 的 404 fixture 模拟的是没有该路由的旧 daemon —— 也就是生产代码真正处理的那个"确实没有 brand"的确定性答案 —— 会立即结算。
但要说公道话:这是潜在问题,不是已发生的问题。 我试图让这个计时器真的触发 —— 绑到单核、加 10 个 CPU 忙循环,最慢的 loading 测试仍只有 900 ms,远低于 2000 ms 的重试延迟,任何一轮都没有触发重试。它是 fixture 保真度差异,而不是我能证明会弄坏什么的 bug。
5. 真的合入会发生什么
WebShellSidebar.brand.test.tsx会自动合并成双重修复:main 的beforeEach已经把宽度设为360,本 PR 逐测试的setItem(..., '400')叠在上面。两者都在 344px 断点之上,属于无效重复。WorkspaceSessionProvider.loading.test.tsx是硬冲突,必须二选一;而按第 3、4 节,main 上那一版更优。
建议
以「被 #11530 取代」关闭 #11544。 诊断是对的,sidebar 的修法与已落地的等价,loading 的修法按上述证据是两者中较弱的一个。
顺带两个清理:
- fix(web-shell): realign two suites with shipped behavior to unbreak main CI (#11534) #11542 处境相同,且现在是严格意义上的空操作:它的两个测试文件与
main字节相同,可以一并关闭。 - Main CI failed: Qwen Code CI on 53964ef7e272 #11534 / Main CI failed: Qwen Code CI on d8baa8730fc6 #11535 / Main CI failed: Qwen Code CI on b1ac3e297023 #11539 / Main CI failed: Qwen Code CI on 1097b9fe0af3 #11543 / Main CI failed: Qwen Code CI on b3d022b35724 #11546 / Main CI failed: Qwen Code CI on ecae0371767e #11528 都是这个签名、且都在修复之前的提交上,等
2488d12d8b之后的 main 跑绿即可关闭。
有一件事确实值得单独再看,与本 PR 无关:main 上的断言现在把 StrictMode 的重挂载双请求写死了(['GET /capabilities', 'GET /brand', 'GET /brand'])。这比过滤版本信息量更大,但也更耦合 React StrictMode 的行为。如果介意这层耦合,那是 main 上两行的后续改动,而不是保留本分支的理由。
本次验证范围: 仅 Linux(Node 22.22.2,16 核)。两个 suite 都是 jsdom 级、与平台无关,但我没有跑 macOS 与 Windows 通道。图为实际运行的终端截图,环境可按上表的三个 commit 复现。
|
Addendum — the duplicate set is larger than I listed. The autofix pipeline filed one PR per red-main push while the fix was in flight, so there are three siblings of this PR, not one. I md5'd both touched test files in each against
Careful with the three-dot diff on these: So: #11542 and #11557 can be closed as no-ops, and this PR (#11544) closed as superseded per the report above. 中文版补充 —— 重复的 PR 不止一个。 修复在途期间,autofix 流水线为每一次 main 变红都开了一个 PR,因此本 PR 有三个兄弟而不是一个。我对每个 PR 的两个测试文件与
注意三点式 diff 在这里有陷阱: |




What this PR does
Fixes two web-shell test breakages on main: the brand sidebar tests now render at a sidebar width above the compact-foot breakpoint when they assert the version tooltip, and the workspace-session loading test no longer assumes the brand fetch's timing relative to its load assertion.
Why it's needed
Main's
Testjob fails on every PR right now. Two recent merges interact: the branding feature (#11244) added brand sidebar tests that assert the[title="<name> v<version>"]tooltip, but the compact-footer change (#11470) intentionally removes the version label below its 344px breakpoint and the default test width is 260px, so the tooltip is never rendered in those tests. The same branding change also made the workspace provider fetchGET /brandbesideGET /capabilitieson a deferred channel; the loading test's exact fetch-list assertion races with it — consistently red under CI's scheduling, consistently green on a fast local machine.Verified broken on
origin/mainlocally before this change, and verified green after: full web-shell suite 300 files / 7113 tests pass.Reviewer Test Plan
How to verify
On current main, run the two files:
cd packages/web-shell && npx vitest run client/components/sidebar/WebShellSidebar.brand.test.tsxfails 2 brand tests deterministically;npx vitest run(full suite, which adds scheduling pressure) fails the 6 workspace-loading variants. With this PR both are green.Evidence (Before & After)
N/A
Tested on
Environment (optional)
N/A
Risk & Scope
Linked Issues
Refs #11244, #11470.
中文说明
修复 main 上当前两个 web-shell 测试破坏:品牌 sidebar 测试在断言版本 tooltip 时改在 compact footer 断点以上的宽度渲染;workspace 加载测试不再假定品牌拉取与其加载断言的相对时序。
背景:#11244(品牌可配置)新增的品牌测试断言
[title="<名称> v<版本>"]tooltip,但 #11470(compact footer)在 344px 断点以下有意移除版本标签,而测试默认宽度 260px,所以 tooltip 根本不会渲染。同一品牌变更还让 workspace provider 在GET /capabilities旁异步拉取GET /brand,与加载测试的精确请求列表断言产生时序竞争 —— CI 调度下必红,本地快机上必绿。本地已在
origin/main上复现失败,修复后 web-shell 全套件 300 文件 / 7113 测试全绿。