Files
Patrick Plate cfb38e8fc6 test: authenticated admin E2E suite + accessibility + visual regression baselines
- Global setup: authenticates as admin, saves storageState for reuse
- playwright.config.ts: 3 projects (setup, authenticated, unauthenticated)
- authenticated-admin.spec.ts: 16 admin pages tested with real auth session
- accessibility.spec.ts: axe-core scans on all admin, public, and portal pages
- visual-regression.spec.ts: dark mode baselines for key pages (toHaveScreenshot)
- @axe-core/playwright added as devDependency
- .gitignore updated: excludes .auth/ and test-results/

Full suite: 262 tests passing (setup:1, authenticated:52, unauthenticated:209)
2026-06-13 22:30:29 +02:00

90 lines
2.5 KiB
TypeScript

import { expect, test } from "@playwright/test"
/**
* Visual Regression Tests — Playwright built-in toHaveScreenshot().
*
* First run creates baseline screenshots in e2e/screenshots/baselines/.
* Subsequent runs diff against baselines.
* Uses maxDiffPixels: 200 for minor rendering differences (fonts, antialiasing).
*
* All screenshots taken in dark mode at 1280x720 viewport.
*/
const BASE = process.env.BASE_URL || "http://localhost:3000"
test.describe("Visual Regression — Admin Pages", () => {
test.use({
viewport: { width: 1280, height: 720 },
colorScheme: "dark",
})
const pages = [
{ name: "dashboard", path: "/dashboard" },
{ name: "members", path: "/members" },
{ name: "distributions", path: "/distributions" },
{ name: "stock", path: "/stock" },
{ name: "reports", path: "/reports" },
{ name: "info-board", path: "/info-board" },
{ name: "calendar", path: "/calendar" },
{ name: "forum", path: "/forum" },
]
for (const { name, path } of pages) {
test(`${name} matches baseline`, async ({ page }) => {
await page.goto(`${BASE}${path}`)
await page.waitForLoadState("domcontentloaded")
// Wait for animations and lazy content to settle
await page.waitForTimeout(3000)
await expect(page).toHaveScreenshot(`admin-${name}-dark.png`, {
maxDiffPixels: 200,
fullPage: false,
})
})
}
})
test.describe("Visual Regression — Auth Pages", () => {
test.use({
viewport: { width: 1280, height: 720 },
colorScheme: "dark",
})
test("login page matches baseline", async ({ page }) => {
await page.goto(`${BASE}/login`)
await page.waitForLoadState("domcontentloaded")
await page.waitForTimeout(2000)
await expect(page).toHaveScreenshot("auth-login-dark.png", {
maxDiffPixels: 200,
fullPage: false,
})
})
})
test.describe("Visual Regression — Portal Pages", () => {
test.use({
viewport: { width: 1280, height: 720 },
colorScheme: "dark",
})
const portalPages = [
{ name: "portal-dashboard", path: "/portal" },
{ name: "portal-history", path: "/portal/history" },
{ name: "portal-profile", path: "/portal/profile" },
]
for (const { name, path } of portalPages) {
test(`${name} matches baseline`, async ({ page }) => {
await page.goto(`${BASE}${path}`)
await page.waitForLoadState("domcontentloaded")
await page.waitForTimeout(2000)
await expect(page).toHaveScreenshot(`${name}-dark.png`, {
maxDiffPixels: 200,
fullPage: false,
})
})
}
})