diff --git a/canvas/src/components/tabs/__tests__/DisplayTab.test.tsx b/canvas/src/components/tabs/__tests__/DisplayTab.test.tsx index 918efac12..a452a976e 100644 --- a/canvas/src/components/tabs/__tests__/DisplayTab.test.tsx +++ b/canvas/src/components/tabs/__tests__/DisplayTab.test.tsx @@ -162,6 +162,11 @@ describe("DisplayTab", () => { controller: "user", ttl_seconds: 300, }); + // Defensive: the noVNC constructor is async (dynamic import), so wait + // for it to be called before asserting arguments (prevents flake in CI). + await waitFor(() => { + expect(mockRFBConstructor).toHaveBeenCalled(); + }); expect(mockRFBConstructor).toHaveBeenCalledWith( expect.any(HTMLElement), expect.stringContaining("/workspaces/ws-display/display/session/websockify"), diff --git a/canvas/src/store/__tests__/canvas.test.ts b/canvas/src/store/__tests__/canvas.test.ts index e3410b147..d7bc343e5 100644 --- a/canvas/src/store/__tests__/canvas.test.ts +++ b/canvas/src/store/__tests__/canvas.test.ts @@ -162,6 +162,27 @@ describe("hydrate", () => { useCanvasStore.getState().hydrate([ws]); expect(useCanvasStore.getState().nodes[0].data.currentTask).toBe(""); }); + + it("preserves in-flight turn status after refresh (issue #2391)", () => { + // Simulates a page refresh: the canvas re-hydrates from GET /workspaces + // while the agent has an active in-flight turn. The store must reflect + // "working" immediately — no dependence on a subsequent TASK_UPDATED + // socket event. This prevents the "stuck idle" UX after reload. + const ws = makeWS({ + id: "ws-1", + status: "online", + current_task: "Analyzing data", + active_tasks: 2, + }); + useCanvasStore.getState().hydrate([ws]); + const node = useCanvasStore.getState().nodes[0]; + expect(node.data.currentTask).toBe("Analyzing data"); + expect(node.data.activeTasks).toBe(2); + expect(node.data.status).toBe("online"); + // Defensive: the node must be considered "working" for any UI that + // gates on currentTask (e.g. ChatTab thinking indicator). + expect(!!node.data.currentTask).toBe(true); + }); }); describe("summarizeWorkspaceCapabilities", () => {