From c2e4b47d7b8adaa8d838167738eec6d190751f23 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 17 Apr 2026 18:40:03 +0100 Subject: [PATCH] test: merge responsive navigation shell checks --- ui/src/ui/navigation.browser.test.ts | 158 ++++++++++++--------------- 1 file changed, 69 insertions(+), 89 deletions(-) diff --git a/ui/src/ui/navigation.browser.test.ts b/ui/src/ui/navigation.browser.test.ts index ec5148a65f2..110b2776ec1 100644 --- a/ui/src/ui/navigation.browser.test.ts +++ b/ui/src/ui/navigation.browser.test.ts @@ -157,10 +157,12 @@ describe("control UI routing", () => { expect(app.querySelector(".dreams__lobster")).not.toBeNull(); }); - it("renders the refreshed desktop navigation shell and collapsed state", async () => { + it("renders responsive navigation shell, drawer, and collapsed states", async () => { const app = mountApp("/chat"); await app.updateComplete; + expect(window.matchMedia("(max-width: 768px)").matches).toBe(true); + expect(app.querySelector(".topnav-shell")).not.toBeNull(); expect(app.querySelector(".topnav-shell__content")).not.toBeNull(); expect(app.querySelector(".topnav-shell__actions")).not.toBeNull(); @@ -181,6 +183,72 @@ describe("control UI routing", () => { const shell = app.querySelector(".shell"); expect(shell?.style.getPropertyValue("--shell-nav-width")).toBe(""); + const split = app.querySelector(".chat-split-container"); + expect(split).not.toBeNull(); + if (split) { + expect(getComputedStyle(split).position).not.toBe("fixed"); + split.classList.add("chat-split-container--open"); + await app.updateComplete; + expect(split.classList.contains("chat-split-container--open")).toBe(true); + } + + const chatMain = app.querySelector(".chat-main"); + expect(chatMain).not.toBeNull(); + if (chatMain) { + expect(getComputedStyle(chatMain).display).not.toBe("none"); + } + + const topShell = app.querySelector(".topnav-shell"); + const content = app.querySelector(".topnav-shell__content"); + expect(topShell).not.toBeNull(); + expect(content).not.toBeNull(); + if (!topShell || !content) { + return; + } + + expect(topShell.classList.contains("topnav-shell")).toBe(true); + expect(content.classList.contains("topnav-shell__content")).toBe(true); + expect(topShell.querySelector(".topbar-nav-toggle")).not.toBeNull(); + expect(topShell.children[1]).toBe(content); + expect(topShell.querySelector(".topnav-shell__actions")).not.toBeNull(); + + const toggle = app.querySelector(".topbar-nav-toggle"); + const actions = app.querySelector(".topnav-shell__actions"); + expect(toggle).not.toBeNull(); + expect(actions).not.toBeNull(); + if (!toggle || !actions || !shell) { + return; + } + + expect(toggle.classList.contains("topbar-nav-toggle")).toBe(true); + expect(actions.classList.contains("topnav-shell__actions")).toBe(true); + expect(topShell.firstElementChild).toBe(toggle); + expect(topShell.querySelector(".topbar-nav-toggle")).toBe(toggle); + expect(actions.querySelector(".topbar-search")).not.toBeNull(); + expect(toggle.getAttribute("aria-label")).toBeTruthy(); + + const nav = app.querySelector(".shell-nav"); + expect(nav).not.toBeNull(); + if (!nav) { + return; + } + + expect(shell.classList.contains("shell--nav-drawer-open")).toBe(false); + toggle.click(); + await app.updateComplete; + + expect(shell.classList.contains("shell--nav-drawer-open")).toBe(true); + expect(nav.classList.contains("shell-nav")).toBe(true); + expect(toggle.getAttribute("aria-expanded")).toBe("true"); + + const link = app.querySelector('a.nav-item[href="/channels"]'); + expect(link).not.toBeNull(); + link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 })); + + await app.updateComplete; + expect(app.tab).toBe("channels"); + expect(shell.classList.contains("shell--nav-drawer-open")).toBe(false); + app.applySettings({ ...app.settings, navCollapsed: true }); await app.updateComplete; @@ -222,94 +290,6 @@ describe("control UI routing", () => { expect(window.location.search).toBe("?session=agent%3Amain%3Asubagent%3Atask-123"); }); - it("keeps chat and nav usable on narrow viewports", async () => { - const app = mountApp("/chat"); - await app.updateComplete; - - expect(window.matchMedia("(max-width: 768px)").matches).toBe(true); - - const split = app.querySelector(".chat-split-container"); - expect(split).not.toBeNull(); - if (split) { - expect(getComputedStyle(split).position).not.toBe("fixed"); - } - - const chatMain = app.querySelector(".chat-main"); - expect(chatMain).not.toBeNull(); - if (chatMain) { - expect(getComputedStyle(chatMain).display).not.toBe("none"); - } - - if (split) { - split.classList.add("chat-split-container--open"); - await app.updateComplete; - expect(split.classList.contains("chat-split-container--open")).toBe(true); - } - if (chatMain) { - expect(chatMain).not.toBeNull(); - } - }); - - it("keeps the narrow top navigation and drawer usable", async () => { - const app = mountApp("/chat"); - await app.updateComplete; - - expect(window.matchMedia("(max-width: 768px)").matches).toBe(true); - - const shell = app.querySelector(".topnav-shell"); - const content = app.querySelector(".topnav-shell__content"); - expect(shell).not.toBeNull(); - expect(content).not.toBeNull(); - if (!shell || !content) { - return; - } - - expect(shell.classList.contains("topnav-shell")).toBe(true); - expect(content.classList.contains("topnav-shell__content")).toBe(true); - expect(shell.querySelector(".topbar-nav-toggle")).not.toBeNull(); - expect(shell.children[1]).toBe(content); - expect(shell.querySelector(".topnav-shell__actions")).not.toBeNull(); - - const toggle = app.querySelector(".topbar-nav-toggle"); - const actions = app.querySelector(".topnav-shell__actions"); - expect(toggle).not.toBeNull(); - expect(actions).not.toBeNull(); - if (!toggle || !actions) { - return; - } - - expect(toggle.classList.contains("topbar-nav-toggle")).toBe(true); - expect(actions.classList.contains("topnav-shell__actions")).toBe(true); - expect(shell.firstElementChild).toBe(toggle); - expect(shell.querySelector(".topbar-nav-toggle")).toBe(toggle); - expect(actions.querySelector(".topbar-search")).not.toBeNull(); - expect(toggle.getAttribute("aria-label")).toBeTruthy(); - - const nav = app.querySelector(".shell-nav"); - const appShell = app.querySelector(".shell"); - expect(appShell).not.toBeNull(); - expect(nav).not.toBeNull(); - if (!appShell || !nav) { - return; - } - - expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(false); - toggle.click(); - await app.updateComplete; - - expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(true); - expect(nav.classList.contains("shell-nav")).toBe(true); - expect(toggle.getAttribute("aria-expanded")).toBe("true"); - - const link = app.querySelector('a.nav-item[href="/channels"]'); - expect(link).not.toBeNull(); - link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 })); - - await app.updateComplete; - expect(app.tab).toBe("channels"); - expect(appShell.classList.contains("shell--nav-drawer-open")).toBe(false); - }); - it("auto-scrolls chat history to the latest message", async () => { vi.spyOn(window, "requestAnimationFrame").mockImplementation((callback) => { queueMicrotask(() => callback(performance.now()));