From f0c6b102bec1f9e1f7142872e493eb0547ad4b3a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 17 Apr 2026 18:54:46 +0100 Subject: [PATCH] test: trim duplicate navigation and cron cases --- ui/src/ui/navigation.browser.test.ts | 36 ----------- ui/src/ui/views/cron.test.ts | 97 +++++++++------------------- 2 files changed, 29 insertions(+), 104 deletions(-) diff --git a/ui/src/ui/navigation.browser.test.ts b/ui/src/ui/navigation.browser.test.ts index 7ff06be9f70..a25bfa101f4 100644 --- a/ui/src/ui/navigation.browser.test.ts +++ b/ui/src/ui/navigation.browser.test.ts @@ -39,42 +39,6 @@ function expectConfirmedGatewayChange(app: ReturnType) { } describe("control UI routing", () => { - it("hydrates the tab from the location", async () => { - const app = mountApp("/sessions"); - await app.updateComplete; - - expect(app.tab).toBe("sessions"); - expect(window.location.pathname).toBe("/sessions"); - }); - - it("respects /ui base paths", async () => { - const app = mountApp("/ui/cron"); - await app.updateComplete; - - expect(app.basePath).toBe("/ui"); - expect(app.tab).toBe("cron"); - expect(window.location.pathname).toBe("/ui/cron"); - }); - - it("infers nested base paths", async () => { - const app = mountApp("/apps/openclaw/cron"); - await app.updateComplete; - - expect(app.basePath).toBe("/apps/openclaw"); - expect(app.tab).toBe("cron"); - expect(window.location.pathname).toBe("/apps/openclaw/cron"); - }); - - it("honors explicit base path overrides", async () => { - window.__OPENCLAW_CONTROL_UI_BASE_PATH__ = "/openclaw"; - const app = mountApp("/openclaw/sessions"); - await app.updateComplete; - - expect(app.basePath).toBe("/openclaw"); - expect(app.tab).toBe("sessions"); - expect(window.location.pathname).toBe("/openclaw/sessions"); - }); - it("keeps chat navigation links visible and updates the URL when clicked", async () => { const app = mountApp("/chat"); await app.updateComplete; diff --git a/ui/src/ui/views/cron.test.ts b/ui/src/ui/views/cron.test.ts index 1e772798aa9..4e9b80d8d00 100644 --- a/ui/src/ui/views/cron.test.ts +++ b/ui/src/ui/views/cron.test.ts @@ -109,28 +109,7 @@ describe("cron view", () => { expect(onRunsFiltersChange).toHaveBeenCalledWith({ cronRunsStatuses: ["ok"] }); }); - it("loads run history when clicking a job row", () => { - const container = document.createElement("div"); - const onLoadRuns = vi.fn(); - const job = createJob("job-1"); - render( - renderCron( - createProps({ - jobs: [job], - onLoadRuns, - }), - ), - container, - ); - - const row = container.querySelector(".list-item-clickable"); - expect(row).not.toBeNull(); - row?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - - expect(onLoadRuns).toHaveBeenCalledWith("job-1"); - }); - - it("marks the selected job and keeps History button to a single call", () => { + it("marks the selected job and routes row/history clicks to run history", () => { const container = document.createElement("div"); const onLoadRuns = vi.fn(); const job = createJob("job-1"); @@ -149,14 +128,20 @@ describe("cron view", () => { const selected = container.querySelector(".list-item-selected"); expect(selected).not.toBeNull(); + const row = container.querySelector(".list-item-clickable"); + expect(row).not.toBeNull(); + row?.dispatchEvent(new MouseEvent("click", { bubbles: true })); + expect(onLoadRuns).toHaveBeenCalledWith("job-1"); + const historyButton = Array.from(container.querySelectorAll("button")).find( (btn) => btn.textContent?.trim() === "History", ); expect(historyButton).not.toBeUndefined(); historyButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - expect(onLoadRuns).toHaveBeenCalledTimes(1); - expect(onLoadRuns).toHaveBeenCalledWith("job-1"); + expect(onLoadRuns).toHaveBeenCalledTimes(2); + expect(onLoadRuns).toHaveBeenNthCalledWith(1, "job-1"); + expect(onLoadRuns).toHaveBeenNthCalledWith(2, "job-1"); }); it("shows selected job run history sorted newest first with chat links", () => { @@ -528,25 +513,6 @@ describe("cron view", () => { it("wires job row actions and selects the row before acting", () => { const container = document.createElement("div"); const onClone = vi.fn(); - const onLoadRuns = vi.fn(); - const job = createJob("job-clone"); - render( - renderCron( - createProps({ - jobs: [job], - onClone, - onLoadRuns, - }), - ), - container, - ); - - const cloneButton = getButtonByText(container, "Clone"); - expect(cloneButton).not.toBeUndefined(); - cloneButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - expect(onClone).toHaveBeenCalledWith(job); - expect(onLoadRuns).toHaveBeenCalledWith("job-clone"); - const onToggle = vi.fn(); const onRun = vi.fn(); const onRemove = vi.fn(); @@ -556,6 +522,7 @@ describe("cron view", () => { renderCron( createProps({ jobs: [actionJob], + onClone, onToggle, onRun, onRemove, @@ -565,6 +532,10 @@ describe("cron view", () => { container, ); + const cloneButton = getButtonByText(container, "Clone"); + expect(cloneButton).not.toBeUndefined(); + cloneButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); + const enableButton = getButtonByText(container, "Disable"); expect(enableButton).not.toBeUndefined(); enableButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); @@ -573,35 +544,25 @@ describe("cron view", () => { expect(runButton).not.toBeUndefined(); runButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - const removeButton = getButtonByText(container, "Remove"); - expect(removeButton).not.toBeUndefined(); - removeButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - - expect(onToggle).toHaveBeenCalledWith(actionJob, false); - expect(onRun).toHaveBeenCalledWith(actionJob, "force"); - expect(onRemove).toHaveBeenCalledWith(actionJob); - expect(actionLoadRuns).toHaveBeenCalledTimes(3); - expect(actionLoadRuns).toHaveBeenNthCalledWith(1, "job-actions"); - expect(actionLoadRuns).toHaveBeenNthCalledWith(2, "job-actions"); - expect(actionLoadRuns).toHaveBeenNthCalledWith(3, "job-actions"); - - const onRunDue = vi.fn(); - const dueJob = createJob("job-due"); - render( - renderCron( - createProps({ - jobs: [dueJob], - onRun: onRunDue, - }), - ), - container, - ); - const runDueButton = getButtonByText(container, "Run if due"); expect(runDueButton).not.toBeUndefined(); runDueButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); - expect(onRunDue).toHaveBeenCalledWith(dueJob, "due"); + const removeButton = getButtonByText(container, "Remove"); + expect(removeButton).not.toBeUndefined(); + removeButton?.dispatchEvent(new MouseEvent("click", { bubbles: true })); + + expect(onClone).toHaveBeenCalledWith(actionJob); + expect(onToggle).toHaveBeenCalledWith(actionJob, false); + expect(onRun).toHaveBeenNthCalledWith(1, actionJob, "force"); + expect(onRun).toHaveBeenNthCalledWith(2, actionJob, "due"); + expect(onRemove).toHaveBeenCalledWith(actionJob); + expect(actionLoadRuns).toHaveBeenCalledTimes(5); + expect(actionLoadRuns).toHaveBeenNthCalledWith(1, "job-actions"); + expect(actionLoadRuns).toHaveBeenNthCalledWith(2, "job-actions"); + expect(actionLoadRuns).toHaveBeenNthCalledWith(3, "job-actions"); + expect(actionLoadRuns).toHaveBeenNthCalledWith(4, "job-actions"); + expect(actionLoadRuns).toHaveBeenNthCalledWith(5, "job-actions"); }); it("renders suggestion datalists for agent/model/thinking/timezone", () => {