import { screen, waitFor, within } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { useClock } from "../src/clock/clock"; import { debugInfo } from "../src/screens/AboutSettings"; import { fakeApi, renderApp, samplePlayerState } from "./render"; describe("about and debug info (Step 10K.10)", () => { it("shows the version and copies debug info with every field", async () => { const writeText = vi.fn(() => Promise.resolve()); Object.defineProperty(navigator, "clipboard", { value: { writeText }, configurable: true }); renderApp(fakeApi({ getPlayerState: () => samplePlayerState({ tutorial: null }) }), "/fleet"); await userEvent.click(await screen.findByRole("link", { name: "Settings" })); const about = await screen.findByRole("region", { name: "About" }); // vitest.config.ts stands in for the build-time version and commit. expect(within(about).getByLabelText("Version")).toHaveTextContent("0.0.0-test ยท build test"); await userEvent.click(within(about).getByRole("button", { name: "Copy debug info" })); await waitFor(() => expect(writeText).toHaveBeenCalledTimes(1)); const text = (writeText.mock.calls[0] as unknown as [string])[0]; expect(text).toContain("Version: 0.0.0-test"); expect(text).toContain("Build: test"); // CR-014: the save, its format version and where it is stored; no player id. expect(text).toContain("Save: player-1"); expect(text).toContain("Save version: 10"); expect(text).toContain("Storage: unknown"); expect(text).not.toContain("Player:"); expect(text).toMatch(/Game time: \d{4}-\d{2}-\d{2}T/); // The app syncs its own clock, so expect whatever offset it holds now. expect(text).toContain(`Clock offset: ${Math.round(useClock.getState().offsetMs)} ms`); expect(text).toContain("Screen: /fleet"); }); it("names the device's save storage", () => { expect(debugInfo("save-1", "indexeddb")).toContain("Storage: indexeddb"); }); });