import { expect, test } from "@playwright/test"; test.describe("Resources", () => { test.beforeEach(async ({ page }) => { await page.goto("/auth/signin"); await page.fill('input[type="email"]', "manager@capakraken.dev"); await page.fill('input[type="password"]', "manager123"); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/\/(dashboard|resources)/); await page.goto("/resources"); await expect(page).toHaveURL(/\/resources/); }); test("shows resources list", async ({ page }) => { await expect(page.getByRole("heading", { name: "Resources" })).toBeVisible(); await expect(page.locator("table")).toBeVisible(); }); test("can search resources", async ({ page }) => { const rows = page.locator("tbody tr"); await expect(rows.first()).toBeVisible(); const firstRowText = (await rows.first().textContent()) ?? ""; const searchTerm = firstRowText .split(/\s+/) .map((token) => token.replace(/[^A-Za-z0-9@._-]/g, "").trim()) .find((token) => token.length >= 3) ?? "EMP"; const searchInput = page.locator('input[type="search"]'); await searchInput.fill(searchTerm); await page.waitForTimeout(500); await expect(searchInput).toHaveValue(searchTerm); await expect(page.getByText(`Search: "${searchTerm}"`)).toBeVisible(); }); test("shows a not-found state for a missing resource detail page", async ({ page }) => { await page.goto("/resources/does-not-exist"); await expect(page.getByText("Resource not found.")).toBeVisible(); await expect(page.getByRole("link", { name: "Back to resources" })).toBeVisible(); }); test("shows a generic load error when the resource detail query fails", async ({ page }) => { await page.route("**/api/trpc/resource.getById**", async (route) => { await route.fulfill({ status: 500, contentType: "application/json", body: JSON.stringify({ error: { message: "boom" } }), }); }); await page.goto("/resources/test-resource-id"); await expect(page.getByText("This resource could not be loaded right now.")).toBeVisible(); await expect(page.getByRole("link", { name: "Back to resources" })).toBeVisible(); }); });