From c9b0e4c82772000ee4eb5f5eece6eb0065f33e72 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Tue, 14 Apr 2026 22:26:30 +0200 Subject: [PATCH] Add test for pause overlay in RunnerCanvas --- tests/unit/runner-canvas.test.tsx | 70 +++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/tests/unit/runner-canvas.test.tsx b/tests/unit/runner-canvas.test.tsx index 49419720..d4c2d134 100644 --- a/tests/unit/runner-canvas.test.tsx +++ b/tests/unit/runner-canvas.test.tsx @@ -100,6 +100,7 @@ const { MockRuntimeHost, runtimeHostInstances } = vi.hoisted(() => { setRuntimeMessageHandler: ReturnType; setFirstPersonTelemetryHandler: ReturnType; setInteractionPromptHandler: ReturnType; + setRuntimePauseStateHandler: ReturnType; setSceneLoadStateHandler: ReturnType; setSceneExitHandler: ReturnType; }> = []; @@ -114,6 +115,7 @@ const { MockRuntimeHost, runtimeHostInstances } = vi.hoisted(() => { setRuntimeMessageHandler = vi.fn(); setFirstPersonTelemetryHandler = vi.fn(); setInteractionPromptHandler = vi.fn(); + setRuntimePauseStateHandler = vi.fn(); setSceneLoadStateHandler = vi.fn(); setSceneExitHandler = vi.fn(); @@ -287,6 +289,74 @@ describe("RunnerCanvas", () => { ); }); + it("shows a centered pause overlay and hides the crosshair while paused", async () => { + const runtimeScene = buildRuntimeSceneFromDocument( + createEmptySceneDocument() + ); + + render( + + ); + + await waitFor(() => { + expect(runtimeHostInstances).toHaveLength(1); + expect( + runtimeHostInstances[0]?.setSceneLoadStateHandler + ).toHaveBeenCalledTimes(1); + expect( + runtimeHostInstances[0]?.setRuntimePauseStateHandler + ).toHaveBeenCalledTimes(1); + }); + + const publishSceneLoadState = runtimeHostInstances[0] + ?.setSceneLoadStateHandler.mock.calls[0]?.[0] as + | ((state: RuntimeSceneLoadState) => void) + | undefined; + const publishPauseState = runtimeHostInstances[0] + ?.setRuntimePauseStateHandler.mock.calls[0]?.[0] as + | ((state: { paused: boolean; source: "manual" | "control" | "mixed" | null }) => void) + | undefined; + + act(() => { + publishSceneLoadState?.({ + status: "ready", + message: null + }); + }); + + await waitFor(() => { + expect(document.querySelector(".runner-canvas__crosshair")).not.toBeNull(); + }); + + act(() => { + publishPauseState?.({ + paused: true, + source: "manual" + }); + }); + + expect(screen.getByTestId("runner-pause-overlay")).toHaveTextContent( + "Pause" + ); + expect(screen.getByTestId("runner-shell").className).toContain( + "runner-canvas--paused" + ); + expect(document.querySelector(".runner-canvas__crosshair")).toBeNull(); + }); + it("keeps the overlay visible and shows load errors from the runtime host", async () => { const runtimeScene = buildRuntimeSceneFromDocument( createEmptySceneDocument()