diff --git a/ui/src/ui/navigation.browser.test.ts b/ui/src/ui/navigation.browser.test.ts index 9620c5b2bae..ec5148a65f2 100644 --- a/ui/src/ui/navigation.browser.test.ts +++ b/ui/src/ui/navigation.browser.test.ts @@ -75,10 +75,13 @@ describe("control UI routing", () => { expect(window.location.pathname).toBe("/openclaw/sessions"); }); - it("updates the URL when clicking nav items", async () => { + it("keeps chat navigation links visible and updates the URL when clicked", async () => { const app = mountApp("/chat"); await app.updateComplete; + const dreamsLink = app.querySelector('a.nav-item[href="/dreaming"]'); + expect(dreamsLink).not.toBeNull(); + const link = app.querySelector('a.nav-item[href="/channels"]'); expect(link).not.toBeNull(); link?.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true, button: 0 })); @@ -88,14 +91,6 @@ describe("control UI routing", () => { expect(window.location.pathname).toBe("/channels"); }); - it("keeps dreams navigation visible even when dreaming is disabled", async () => { - const app = mountApp("/chat"); - await app.updateComplete; - - const dreamsLink = app.querySelector('a.nav-item[href="/dreaming"]'); - expect(dreamsLink).not.toBeNull(); - }); - it("renders the dreaming view on the /dreaming route", async () => { const app = mountApp("/dreaming"); app.dreamingStatus = { @@ -410,11 +405,12 @@ describe("control UI routing", () => { expect(container.scrollTop).toBe(targetScrollTop); }); - it("hydrates token from query params and strips them", async () => { - const app = mountApp("/ui/overview?token=abc123"); + it("hydrates safe query params and strips unsafe credentials from the URL", async () => { + const app = mountApp("/ui/overview?token=abc123&password=sekret"); await app.updateComplete; expect(app.settings.token).toBe("abc123"); + expect(app.password).toBe(""); expect(JSON.parse(localStorage.getItem("openclaw.control.settings.v1") ?? "{}").token).toBe( undefined, ); @@ -422,15 +418,6 @@ describe("control UI routing", () => { expect(window.location.search).toBe(""); }); - it("strips password URL params without importing them", async () => { - const app = mountApp("/ui/overview?password=sekret"); - await app.updateComplete; - - expect(app.password).toBe(""); - expect(window.location.pathname).toBe("/ui/overview"); - expect(window.location.search).toBe(""); - }); - it("hydrates token from URL hash when settings already set", async () => { localStorage.setItem( "openclaw.control.settings.v1", @@ -450,7 +437,7 @@ describe("control UI routing", () => { expect(window.location.hash).toBe(""); }); - it("hydrates token from URL hash and strips it", async () => { + it("hydrates token from URL hash, strips it, and clears it after gateway changes", async () => { const app = mountApp("/ui/overview#token=abc123"); await app.updateComplete; @@ -460,11 +447,6 @@ describe("control UI routing", () => { ); expect(window.location.pathname).toBe("/ui/overview"); expect(window.location.hash).toBe(""); - }); - - it("clears the current token when the gateway URL changes", async () => { - const app = mountApp("/ui/overview#token=abc123"); - await app.updateComplete; const gatewayUrlInput = app.querySelector( 'input[placeholder="ws://100.x.y.z:18789"]',