import { test, expect } from "@playwright/test"; // Minimal browser smoke: the dashboard shell mounts and renders live `/api/state` // into the Board. The backend is fully mocked via route fulfilment so the test // needs no coordinator, DB, or network — it asserts the read path end to end // (fetch → state → Board card), which a unit/jsdom test does not exercise. const TOPOLOGY = { trees: [{ id: "main", label: "Main", root: true }], nodes: [ { id: "plan", label: "Plan", agent: "planner", tree: "main", kind: "stage", gated: false, }, ], edges: [], }; const SMOKE_TASK = { thread_id: "t-smoke-0001", short_id: "t-smoke", task: "Playwright smoke task", current_phase: "plan", status: "active", waiting: false, waiting_since: null, }; const STATE = { ok: true, error: null, generated_at: "2026-06-24T00:00:00Z", db_path: ":memory:", stages: [ { key: "plan", label: "Plan", agent: "planner", phases: ["plan"], gated: false, role_node: true, state: "active", count: 1, tasks: [SMOKE_TASK], }, ], tasks: [SMOKE_TASK], waiting: [], question_counts: {}, summary: { active: 1, parked: 0, waiting: 0, open_questions: 0, total: 1 }, budget: { available: false }, nodes: { plan: { state: "active", count: 1 } }, }; test("dashboard Board renders live state from a mocked /api", async ({ page, }) => { await page.route("**/api/topology*", (route) => route.fulfill({ json: TOPOLOGY }), ); await page.route("**/api/state*", (route) => route.fulfill({ json: STATE })); await page.goto("/"); // App shell mounted: the Board / Pipeline tabs render. await expect(page.getByRole("tab", { name: /board/i })).toBeVisible(); // The mocked live state flowed through fetch → state → the Board column. await expect(page.getByText("Plan", { exact: true }).first()).toBeVisible(); await expect(page.getByText("Playwright smoke task")).toBeVisible(); });