import AxeBuilder from "@axe-core/playwright"; import { expect, test } from "@playwright/test"; import type { AutoModeState } from "../src/shared/api/autonomyApi"; const projectId = "widefrog"; const envelope = (data: unknown) => ({ data, meta: { requestId: "attention-auto-e2e", timestamp: new Date().toISOString() } }); const autoModeState = (): AutoModeState => ({ version: 1, enabled: true, status: "running", autoBrainstorm: true, maxBrainstormIterations: 5, maxConsecutiveFailures: 3, leaseMinutes: 30, maxWorkItemsPerRun: 8, maxRunMinutes: 45, roadmap: { id: "roadmap-e2e", title: "E2E-roadmap", sourceMarkdown: "# E2E-roadmap\n\n## Eerste fase\n- [ ] Exact werkitem", status: "active", currentPhaseIndex: 0, importedAt: "2026-09-01T00:00:00.000Z", phases: [{ id: "phase-e2e", title: "Eerste fase", objective: "Eerste fase", status: "active", brainstormIterations: 0, brainstormConverged: false, validationFailures: 0, items: [{ id: "item-e2e", title: "Exact werkitem", status: "pending", attempts: 0 }], }], }, completedLeases: [], events: [], updatedAt: "2026-09-01T00:00:00.000Z", updatedBy: "owner", }); test("attention inbox exposes every visible item as an actionable destination", async ({ page }) => { await page.goto(`/projects/${projectId}/attention`); await expect(page.getByRole("heading", { name: "Jouw aandacht", exact: true })).toBeVisible(); await expect(page.getByText(/item\(s\) vragen jouw aandacht|Niets wacht op jou/)).toBeVisible(); const reviewAction = page.getByRole("button", { name: /Beoordelen/ }).first(); if (await reviewAction.isVisible()) { await reviewAction.click(); await expect(page).toHaveURL(/\/review-queue\?reviewItemId=/); } const accessibility = await new AxeBuilder({ page }).analyze(); expect(accessibility.violations.filter((violation) => ["serious", "critical"].includes(violation.impact ?? ""))).toEqual([]); }); test("Auto Mode distinguishes queued work from real execution and protects roadmap progress", async ({ page }) => { let state = autoModeState(); let roadmapImports = 0; await page.route(`**/api/projects/${projectId}/autonomy**`, async (route) => { const request = route.request(); const url = new URL(request.url()); if (request.method() === "GET") { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(envelope(state)) }); return; } if (request.method() === "POST" && url.pathname.endsWith("/roadmap")) { roadmapImports += 1; await route.fulfill({ status: 201, contentType: "application/json", body: JSON.stringify(envelope(state)) }); return; } await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(envelope(state)) }); }); await page.goto(`/projects/${projectId}/auto`); await expect(page.getByRole("heading", { name: "Auto Mode", exact: true })).toBeVisible(); await expect(page.getByText("Klaar voor uitvoering", { exact: true }).first()).toBeVisible(); await expect(page.getByText("Werk staat veilig in de wachtrij")).toBeVisible(); await expect(page.getByText("ProjectBrain werkt", { exact: true })).toHaveCount(0); await page.getByText("Autonomiebeleid en geavanceerde instellingen", { exact: true }).click(); await page.getByText("Geavanceerde grenzen", { exact: true }).click(); await expect(page.getByLabel("Werkitems per run")).toHaveValue("8"); await expect(page.getByLabel("Looptijd per run")).toHaveValue("45"); await expect(page.getByText("Roadmap handmatig importeren", { exact: true })).toBeVisible(); await page.getByLabel("Roadmap").fill("# Nieuwe roadmap\n\n## Nieuwe fase\n- [ ] Nieuw werk"); await page.getByRole("button", { name: "Roadmap bijwerken" }).click(); await expect(page.getByText("Bestaande roadmap en voortgang vervangen?")).toBeVisible(); expect(roadmapImports).toBe(0); await page.getByRole("button", { name: "Annuleren" }).click(); state = { ...state, activeLease: { token: "00000000-0000-4000-8000-000000000001", kind: "implement", actor: "chatgpt-agent", roadmapId: "roadmap-e2e", phaseId: "phase-e2e", itemId: "item-e2e", createdAt: new Date(Date.now() - 60_000).toISOString(), expiresAt: new Date(Date.now() + 30 * 60_000).toISOString(), }, }; await page.getByRole("button", { name: "Vernieuwen" }).click(); await expect(page.getByText("ProjectBrain werkt", { exact: true })).toBeVisible(); await expect(page.getByText("Exact werkitem", { exact: true }).first()).toBeVisible(); const accessibility = await new AxeBuilder({ page }).analyze(); expect(accessibility.violations.filter((violation) => ["serious", "critical"].includes(violation.impact ?? ""))).toEqual([]); });