import { test, expect } from "@playwright/test"; const EMAIL = process.env.E2E_OWNER_EMAIL ?? ""; const PASSWORD = process.env.E2E_OWNER_PASSWORD ?? ""; test.describe("admin", () => { test.skip(!EMAIL || !PASSWORD, "E2E_OWNER_EMAIL / E2E_OWNER_PASSWORD not set"); test.beforeEach(async ({ page }) => { await page.goto("/login"); await page.getByLabel("E-mail").fill(EMAIL); await page.getByLabel("Password").fill(PASSWORD); await page.getByRole("button", { name: "Sign in", exact: true }).click(); await expect(page).toHaveURL(/\/admin/); }); test("dashboard, tools list, editor save round-trip, review queue, links, jobs, owner, audit", async ({ page }) => { await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible(); await page.goto("/admin/tools?q=duckdb"); await page.getByRole("link", { name: "DuckDB" }).click(); await expect(page.getByRole("heading", { level: 1 })).toHaveText("DuckDB"); const alias = page.getByLabel(/Aliases/); const before = await alias.inputValue(); await alias.fill(before ? before + "\nE2E Alias" : "E2E Alias"); await page.getByRole("button", { name: "Save", exact: true }).click(); await expect(page.getByText(/Saved\./)).toBeVisible(); await page.reload(); await expect(page.getByLabel(/Aliases/)).toHaveValue(/E2E Alias/); await page.getByLabel(/Aliases/).fill(before); await page.getByRole("button", { name: "Save", exact: true }).click(); await expect(page.getByText(/Saved\./)).toBeVisible(); await page.goto("/admin/review"); await expect(page.getByRole("heading", { name: "Review queue" })).toBeVisible(); await page.goto("/admin/links"); await expect(page.getByRole("heading", { name: "Link integrity" })).toBeVisible(); await page.goto("/admin/jobs"); await expect(page.getByRole("heading", { name: "Jobs & crawler" })).toBeVisible(); await page.goto("/admin/owner"); await expect(page.getByRole("heading", { name: /Owner dashboard/ })).toBeVisible(); await page.goto("/admin/audit"); await expect(page.getByText("tool.update").first()).toBeVisible(); }); test("public pages never leak owner notes", async ({ page, request }) => { const r = await request.get("/tools/claude-code"); const html = await r.text(); expect(html).not.toMatch(/Primary development agent for every project|owner_notes|deployment_urls|use_state|cluster_compat/i); }); });