Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ it.each(
],
});
}
// A daemon without the brand route (#11244): a 404 settles the
// provider's brand fetch immediately instead of arming its retry
// timer.
if (url.pathname === '/brand') {
return new Response('not found', { status: 404 });
}
if (url.pathname.endsWith('/load')) {
loadBodies.push(JSON.parse(String(init?.body)));
const n = loadBodies.length;
Expand Down Expand Up @@ -196,7 +202,13 @@ it.each(
);
root.render(strictMode ? <StrictMode>{tree}</StrictMode> : tree);
});
expect(calls).toEqual(['GET /capabilities']);
// The workspace provider fetches the brand beside capabilities
// (#11244); StrictMode's remount issues that brand fetch twice.
expect(calls).toEqual(
strictMode
? ['GET /capabilities', 'GET /brand', 'GET /brand']
: ['GET /capabilities', 'GET /brand'],
);
expect(observeLiveStateSupport).not.toHaveBeenCalled();
await act(async () => {
releaseCapabilities();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ function builtInMark(): Element | null {

beforeEach(() => {
window.localStorage.clear();
// Mount above the compact footer breakpoint (344px): below it the version
// label leaves the row (#11470), and the brand tooltip assertions query
// that label's title.
window.localStorage.setItem('qwen-code-web-shell-sidebar-width', '360');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] The new beforeEach fixture hardcodes the sidebar-width storage key as a raw literal — a fifth copy of SIDEBAR_WIDTH_STORAGE_KEY, which WebShellSidebar.tsx:149 does not export — and the two tooltip assertions that depend on it carry no assertion message. Together they make the fixture's layout precondition invisible at the point of failure.

If SIDEBAR_FOOTER_COMPACT_WIDTH (currently 344, WebShellSidebar.tsx:154) is raised above 360, if the storage key is renamed, or if the sidebar stops reading its persisted width at mount, readSidebarWidth() falls back to SIDEBAR_DEFAULT_WIDTH = 260, the version label leaves the footer row, and both treats an empty name as unset rather than blanking the brand row and names the version tooltip after the brand fail with expected null not to be null. Nothing in that output mentions the sidebar width, the storage key or the footer breakpoint, so the natural read is a branding regression and the investigation goes into brandContext and the footer version badge instead of into this fixture.

Witness:

BASE (fixture intact, PR code as committed):
 Test Files 1 passed (1)   Tests 10 passed (10)

FLIP (writes of that one localStorage key suppressed):
 x sidebar brand > treats an empty name as unset rather than blanking the brand row
   AssertionError: expected null not to be null
   at WebShellSidebar.brand.test.tsx:208:11
 x sidebar brand > names the version tooltip after the brand
   AssertionError: expected null not to be null
   at WebShellSidebar.brand.test.tsx:216:11
 Test Files 1 failed (1)   Tests 2 failed | 8 passed (10)

The two failures are exactly the two this fixture feeds, and the printed output nowhere names the width, the key or the breakpoint. The sibling suite corroborates the mechanism unmodified: WebShellSidebar.footer-version.test.tsx mounts at 260 and asserts the version badge is null, then mounts at 360 and asserts it is non-null.

The fix spans three places, so it is written out rather than offered as a one-click suggestion: declare the key and the width as named locals at module scope (mirroring WebShellSidebar.footer-version.test.tsx:127 and its mountAtWidth helper), use the local in this setItem, and attach that sibling file's diagnostic-message idiom to the two tooltip queries.

const SIDEBAR_WIDTH_STORAGE_KEY = 'qwen-code-web-shell-sidebar-width';
const ABOVE_COMPACT_FOOTER_WIDTH = 360;

// in beforeEach:
window.localStorage.setItem(
  SIDEBAR_WIDTH_STORAGE_KEY,
  String(ABOVE_COMPACT_FOOTER_WIDTH),
);

// at each of the two tooltip assertions:
expect(
  container.querySelector('[title="QiuQiu Code v1.2.3"]'),
  'version tooltip missing — sidebar mounted below the compact footer breakpoint',
).not.toBeNull();

Any width chosen here must stay above the breakpoint and inside the clamp: SIDEBAR_FOOTER_COMPACT_WIDTH = 344 (WebShellSidebar.tsx:154), clamped by Math.min(getSidebarMaxWidth(), Math.max(SIDEBAR_MIN_WIDTH, width)) (WebShellSidebar.tsx:593-594) with SIDEBAR_MIN_WIDTH = 220 / SIDEBAR_MAX_WIDTH = 420 (WebShellSidebar.tsx:151-152) — keep 360, because the 260 default does not clear 344.

中文说明

新增的 beforeEach fixture 把侧边栏宽度的 storage key 硬编码为裸字面量 —— 这是 SIDEBAR_WIDTH_STORAGE_KEY 的第五份拷贝,而 WebShellSidebar.tsx:149 并未导出该常量 —— 同时依赖它的两条 tooltip 断言都没有断言消息。两者合起来,使这个 fixture 的布局前提在失败点上完全不可见。

如果 SIDEBAR_FOOTER_COMPACT_WIDTH(当前为 344,WebShellSidebar.tsx:154)被提高到 360 以上、如果该 storage key 被重命名、或者侧边栏不再在挂载时读取持久化宽度,readSidebarWidth() 就会回退到 SIDEBAR_DEFAULT_WIDTH = 260,版本标签移出行,于是 treats an empty name as unset rather than blanking the brand rownames the version tooltip after the brand 两个用例都会以 expected null not to be null 失败。该输出中没有任何地方提到侧边栏宽度、storage key 或页脚断点,因此最自然的理解是品牌配置出现了回归,排查会走向 brandContext 和页脚版本徽章,而不是这个 fixture。

证据:

BASE(fixture 保持原样,即 PR 提交的代码):
 Test Files 1 passed (1)   Tests 10 passed (10)

FLIP(抑制该 localStorage key 的写入):
 x sidebar brand > treats an empty name as unset rather than blanking the brand row
   AssertionError: expected null not to be null
   at WebShellSidebar.brand.test.tsx:208:11
 x sidebar brand > names the version tooltip after the brand
   AssertionError: expected null not to be null
   at WebShellSidebar.brand.test.tsx:216:11
 Test Files 1 failed (1)   Tests 2 failed | 8 passed (10)

这两个失败正是该 fixture 所支撑的两个用例,而输出中完全没有出现宽度、key 或断点。姊妹测试套件在未改动的情况下印证了同一机制:WebShellSidebar.footer-version.test.tsx 在 260 下挂载并断言版本徽章为 null,在 360 下挂载并断言其非 null。

修复涉及三处,因此以代码块列出而不是一键 suggestion:在模块作用域把 key 与宽度声明为具名局部常量(参照 WebShellSidebar.footer-version.test.tsx:127 及其 mountAtWidth 辅助函数),在此 setItem 中使用该常量,并为两条 tooltip 查询加上该姊妹文件的诊断消息写法。

const SIDEBAR_WIDTH_STORAGE_KEY = 'qwen-code-web-shell-sidebar-width';
const ABOVE_COMPACT_FOOTER_WIDTH = 360;

// beforeEach 中:
window.localStorage.setItem(
  SIDEBAR_WIDTH_STORAGE_KEY,
  String(ABOVE_COMPACT_FOOTER_WIDTH),
);

// 两条 tooltip 断言处:
expect(
  container.querySelector('[title="QiuQiu Code v1.2.3"]'),
  'version tooltip missing — sidebar mounted below the compact footer breakpoint',
).not.toBeNull();

此处选择的宽度必须保持在断点之上且落在 clamp 范围内:SIDEBAR_FOOTER_COMPACT_WIDTH = 344(WebShellSidebar.tsx:154),经 Math.min(getSidebarMaxWidth(), Math.max(SIDEBAR_MIN_WIDTH, width))(WebShellSidebar.tsx:593-594)裁剪,其中 SIDEBAR_MIN_WIDTH = 220 / SIDEBAR_MAX_WIDTH = 420(WebShellSidebar.tsx:151-152)—— 请保留 360,因为默认值 260 无法越过 344

— qwen3.8-max via Qwen Code /review (v0.23.2)

container = document.createElement('div');
document.body.appendChild(container);
root = createRoot(container);
Expand Down
Loading