import { test, expect } from '@playwright/test' import { loginAsAdmin } from '../helpers/auth.js' const viewports = { desktop: { width: 1280, height: 720 }, mobile: { width: 375, height: 667 }, } const publicPages = [ { name: 'home', path: '/' }, { name: 'join', path: '/join' }, { name: 'events', path: '/events' }, { name: 'coming-soon', path: '/coming-soon' }, ] const authenticatedPages = [ { name: 'member-dashboard', path: '/member/dashboard' }, { name: 'member-profile', path: '/member/profile' }, { name: 'admin-members', path: '/admin/members' }, { name: 'admin-events-create', path: '/admin/events/create' }, ] // Wait for fonts and images to load before taking screenshots async function waitForStable(page) { await page.waitForLoadState('networkidle') // Wait for web fonts to load await page.evaluate(() => document.fonts.ready) } test.describe('visual regression — public pages', () => { for (const { name, path } of publicPages) { for (const [viewportName, viewport] of Object.entries(viewports)) { test(`${name} — ${viewportName}`, async ({ page }) => { await page.setViewportSize(viewport) await page.goto(path) await waitForStable(page) await expect(page).toHaveScreenshot(`${name}-${viewportName}.png`, { maxDiffPixelRatio: 0.01, mask: [ // Mask dynamic content like dates and counts page.locator('.event-date'), page.locator('.event-count'), page.locator('time'), ], }) }) } } }) test.describe('visual regression — authenticated pages', () => { test.beforeEach(async ({ page }) => { await loginAsAdmin(page) }) for (const { name, path } of authenticatedPages) { test(`${name} — desktop`, async ({ page }) => { await page.setViewportSize(viewports.desktop) await page.goto(path) await waitForStable(page) await expect(page).toHaveScreenshot(`${name}-desktop.png`, { maxDiffPixelRatio: 0.01, mask: [ page.locator('.event-date'), page.locator('time'), page.locator('.member-since'), ], }) }) } })