





















@@ -157,10 +157,12 @@ describe("control UI routing", () => {
157157expect(app.querySelector(".dreams__lobster")).not.toBeNull();
158158});
159159160-it("renders the refreshed desktop navigation shell and collapsed state", async () => {
160+it("renders responsive navigation shell, drawer, and collapsed states", async () => {
161161const app = mountApp("/chat");
162162await app.updateComplete;
163163164+expect(window.matchMedia("(max-width: 768px)").matches).toBe(true);
165+164166expect(app.querySelector(".topnav-shell")).not.toBeNull();
165167expect(app.querySelector(".topnav-shell__content")).not.toBeNull();
166168expect(app.querySelector(".topnav-shell__actions")).not.toBeNull();
@@ -181,57 +183,13 @@ describe("control UI routing", () => {
181183const shell = app.querySelector<HTMLElement>(".shell");
182184expect(shell?.style.getPropertyValue("--shell-nav-width")).toBe("");
183185184-app.applySettings({ ...app.settings, navCollapsed: true });
185-await app.updateComplete;
186-187-expect(app.querySelector(".nav-section__label")).toBeNull();
188-expect(app.querySelector(".sidebar-brand__logo")).toBeNull();
189-190-expect(app.querySelector(".sidebar-shell__footer")).not.toBeNull();
191-expect(app.querySelector(".sidebar-utility-link")).not.toBeNull();
192-193-const item = app.querySelector<HTMLElement>(".sidebar .nav-item");
194-const header = app.querySelector<HTMLElement>(".sidebar-shell__header");
195-const sidebar = app.querySelector<HTMLElement>(".sidebar");
196-expect(item).not.toBeNull();
197-expect(header).not.toBeNull();
198-expect(sidebar).not.toBeNull();
199-if (!item || !header || !sidebar) {
200-return;
201-}
202-203-expect(sidebar.classList.contains("sidebar--collapsed")).toBe(true);
204-expect(item.querySelector(".nav-item__icon")).not.toBeNull();
205-expect(item.querySelector(".nav-item__text")).toBeNull();
206-expect(app.querySelector(".sidebar-brand__copy")).toBeNull();
207-expect(header.querySelector(".nav-collapse-toggle")).not.toBeNull();
208-});
209-210-it("preserves the active session when opening chat from sidebar navigation", async () => {
211-const app = mountApp("/sessions?session=agent:main:subagent:task-123");
212-await app.updateComplete;
213-214-const link = app.querySelector<HTMLAnchorElement>('a.nav-item[href="/chat"]');
215-expect(link).not.toBeNull();
216-link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 }));
217-218-await app.updateComplete;
219-expect(app.tab).toBe("chat");
220-expect(app.sessionKey).toBe("agent:main:subagent:task-123");
221-expect(window.location.pathname).toBe("/chat");
222-expect(window.location.search).toBe("?session=agent%3Amain%3Asubagent%3Atask-123");
223-});
224-225-it("keeps chat and nav usable on narrow viewports", async () => {
226-const app = mountApp("/chat");
227-await app.updateComplete;
228-229-expect(window.matchMedia("(max-width: 768px)").matches).toBe(true);
230-231186const split = app.querySelector(".chat-split-container");
232187expect(split).not.toBeNull();
233188if (split) {
234189expect(getComputedStyle(split).position).not.toBe("fixed");
190+split.classList.add("chat-split-container--open");
191+await app.updateComplete;
192+expect(split.classList.contains("chat-split-container--open")).toBe(true);
235193}
236194237195const chatMain = app.querySelector(".chat-main");
@@ -240,64 +198,46 @@ describe("control UI routing", () => {
240198expect(getComputedStyle(chatMain).display).not.toBe("none");
241199}
242200243-if (split) {
244-split.classList.add("chat-split-container--open");
245-await app.updateComplete;
246-expect(split.classList.contains("chat-split-container--open")).toBe(true);
247-}
248-if (chatMain) {
249-expect(chatMain).not.toBeNull();
250-}
251-});
252-253-it("keeps the narrow top navigation and drawer usable", async () => {
254-const app = mountApp("/chat");
255-await app.updateComplete;
256-257-expect(window.matchMedia("(max-width: 768px)").matches).toBe(true);
258-259-const shell = app.querySelector<HTMLElement>(".topnav-shell");
201+const topShell = app.querySelector<HTMLElement>(".topnav-shell");
260202const content = app.querySelector<HTMLElement>(".topnav-shell__content");
261-expect(shell).not.toBeNull();
203+expect(topShell).not.toBeNull();
262204expect(content).not.toBeNull();
263-if (!shell || !content) {
205+if (!topShell || !content) {
264206return;
265207}
266208267-expect(shell.classList.contains("topnav-shell")).toBe(true);
209+expect(topShell.classList.contains("topnav-shell")).toBe(true);
268210expect(content.classList.contains("topnav-shell__content")).toBe(true);
269-expect(shell.querySelector(".topbar-nav-toggle")).not.toBeNull();
270-expect(shell.children[1]).toBe(content);
271-expect(shell.querySelector(".topnav-shell__actions")).not.toBeNull();
211+expect(topShell.querySelector(".topbar-nav-toggle")).not.toBeNull();
212+expect(topShell.children[1]).toBe(content);
213+expect(topShell.querySelector(".topnav-shell__actions")).not.toBeNull();
272214273215const toggle = app.querySelector<HTMLElement>(".topbar-nav-toggle");
274216const actions = app.querySelector<HTMLElement>(".topnav-shell__actions");
275217expect(toggle).not.toBeNull();
276218expect(actions).not.toBeNull();
277-if (!toggle || !actions) {
219+if (!toggle || !actions || !shell) {
278220return;
279221}
280222281223expect(toggle.classList.contains("topbar-nav-toggle")).toBe(true);
282224expect(actions.classList.contains("topnav-shell__actions")).toBe(true);
283-expect(shell.firstElementChild).toBe(toggle);
284-expect(shell.querySelector(".topbar-nav-toggle")).toBe(toggle);
225+expect(topShell.firstElementChild).toBe(toggle);
226+expect(topShell.querySelector(".topbar-nav-toggle")).toBe(toggle);
285227expect(actions.querySelector(".topbar-search")).not.toBeNull();
286228expect(toggle.getAttribute("aria-label")).toBeTruthy();
287229288230const nav = app.querySelector<HTMLElement>(".shell-nav");
289-const appShell = app.querySelector<HTMLElement>(".shell");
290-expect(appShell).not.toBeNull();
291231expect(nav).not.toBeNull();
292-if (!appShell || !nav) {
232+if (!nav) {
293233return;
294234}
295235296-expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(false);
236+expect(shell.classList.contains("shell--nav-drawer-open")).toBe(false);
297237toggle.click();
298238await app.updateComplete;
299239300-expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(true);
240+expect(shell.classList.contains("shell--nav-drawer-open")).toBe(true);
301241expect(nav.classList.contains("shell-nav")).toBe(true);
302242expect(toggle.getAttribute("aria-expanded")).toBe("true");
303243@@ -307,7 +247,47 @@ describe("control UI routing", () => {
307247308248await app.updateComplete;
309249expect(app.tab).toBe("channels");
310-expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(false);
250+expect(shell.classList.contains("shell--nav-drawer-open")).toBe(false);
251+252+app.applySettings({ ...app.settings, navCollapsed: true });
253+await app.updateComplete;
254+255+expect(app.querySelector(".nav-section__label")).toBeNull();
256+expect(app.querySelector(".sidebar-brand__logo")).toBeNull();
257+258+expect(app.querySelector(".sidebar-shell__footer")).not.toBeNull();
259+expect(app.querySelector(".sidebar-utility-link")).not.toBeNull();
260+261+const item = app.querySelector<HTMLElement>(".sidebar .nav-item");
262+const header = app.querySelector<HTMLElement>(".sidebar-shell__header");
263+const sidebar = app.querySelector<HTMLElement>(".sidebar");
264+expect(item).not.toBeNull();
265+expect(header).not.toBeNull();
266+expect(sidebar).not.toBeNull();
267+if (!item || !header || !sidebar) {
268+return;
269+}
270+271+expect(sidebar.classList.contains("sidebar--collapsed")).toBe(true);
272+expect(item.querySelector(".nav-item__icon")).not.toBeNull();
273+expect(item.querySelector(".nav-item__text")).toBeNull();
274+expect(app.querySelector(".sidebar-brand__copy")).toBeNull();
275+expect(header.querySelector(".nav-collapse-toggle")).not.toBeNull();
276+});
277+278+it("preserves the active session when opening chat from sidebar navigation", async () => {
279+const app = mountApp("/sessions?session=agent:main:subagent:task-123");
280+await app.updateComplete;
281+282+const link = app.querySelector<HTMLAnchorElement>('a.nav-item[href="/chat"]');
283+expect(link).not.toBeNull();
284+link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 }));
285+286+await app.updateComplete;
287+expect(app.tab).toBe("chat");
288+expect(app.sessionKey).toBe("agent:main:subagent:task-123");
289+expect(window.location.pathname).toBe("/chat");
290+expect(window.location.search).toBe("?session=agent%3Amain%3Asubagent%3Atask-123");
311291});
312292313293it("auto-scrolls chat history to the latest message", async () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。