import { expect, test, type Page } from "@playwright/test"; async function signIn(page: Page) { await page.goto("/auth/signin"); await page.fill('input[type="email"]', "admin@capakraken.dev"); await page.fill('input[type="password"]', "admin123"); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/\/(dashboard|resources)/); } test.describe("Analytics / Skills Hub", () => { test.beforeEach(async ({ page }) => { await signIn(page); await page.goto("/analytics/skills"); }); test("skills hub page loads with heading", async ({ page }) => { await page.waitForLoadState("networkidle"); await expect(page.getByRole("heading", { name: "Skills Hub" })).toBeVisible({ timeout: 10000 }); }); test("tab bar is visible with expected tabs", async ({ page }) => { await page.waitForLoadState("networkidle"); for (const label of ["Overview", "Search", "Gaps", "People"]) { await expect(page.locator("button", { hasText: label })).toBeVisible({ timeout: 10000 }); } }); test("search tab renders a search form", async ({ page }) => { await page.waitForLoadState("networkidle"); await page.locator("button", { hasText: "Search" }).click(); await page.waitForTimeout(300); // Search tab should contain an input for skill / resource search await expect( page.locator('input[type="text"]').or(page.locator('input[type="search"]')).first(), ).toBeVisible({ timeout: 10000 }); }); test("people tab renders content", async ({ page }) => { await page.waitForLoadState("networkidle"); await page.locator("button", { hasText: "People" }).click(); await page.waitForTimeout(300); await expect( page.locator("table").or(page.locator("text=No results")).or(page.locator("input").first()), ).toBeVisible({ timeout: 10000 }); }); test("no JavaScript errors on page load", async ({ page }) => { const consoleErrors: string[] = []; page.on("console", (msg) => { if (msg.type() === "error") { consoleErrors.push(msg.text()); } }); await page.goto("/analytics/skills"); await page.waitForLoadState("networkidle"); // Filter out known third-party / browser-extension noise const appErrors = consoleErrors.filter( (e) => !e.includes("extension") && !e.includes("favicon"), ); expect(appErrors, `Unexpected console errors: ${appErrors.join("\n")}`).toHaveLength(0); }); }); test.describe("Analytics / Insights", () => { test.beforeEach(async ({ page }) => { await signIn(page); await page.goto("/analytics/insights"); }); test("insights page loads without errors", async ({ page }) => { await page.waitForLoadState("networkidle"); // Page should render some heading or content area — not a hard 404 await expect( page.locator("h1").or(page.locator("main")).first(), ).toBeVisible({ timeout: 10000 }); }); });