diff --git a/frontend/e2e/dashboard-screenshots.spec.ts b/frontend/e2e/dashboard-screenshots.spec.ts index 82498796..86b745d4 100644 --- a/frontend/e2e/dashboard-screenshots.spec.ts +++ b/frontend/e2e/dashboard-screenshots.spec.ts @@ -1,3 +1,62 @@ +/** + * Dashboard proofshots — seeds the admin account with test data so every + * widget is visible, then captures 6 screenshots (3 viewports × 2 themes). + * + * Seeded data is removed in afterAll so it doesn't pollute other tests. + */ +import { test } from '@playwright/test'; +import { execSync } from 'child_process'; import { captureProofshots } from './proofshots'; -captureProofshots('/', 'dashboard'); +// A real document that exists in the dev DB (most recently updated) +const SEED_DOC_ID = '24580ce9-9765-40b1-ac59-b0ab15160ce0'; +const SEED_DOC_TITLE = 'Brief aus dem Krieg'; + +// Real comment IDs used as reference_id for deep-linking +const COMMENT_IDS = [ + '46c5171f-1721-4085-a7ed-1eef7b4effb8', + 'a09cefe4-ddf8-47fa-addc-5c582183b459' +]; + +const psql = (sql: string) => + execSync( + `docker exec archive-db psql -U archive_user family_archive_db -c "${sql.replace(/"/g, '\\"')}"` + ); + +test.beforeAll(() => { + // Insert a MENTION and a REPLY notification for the admin user so the + // notifications widget is populated in the screenshots. + psql(` + INSERT INTO notifications (recipient_id, type, document_id, reference_id, read, actor_name) + SELECT id, 'MENTION', '${SEED_DOC_ID}', '${COMMENT_IDS[0]}', false, 'Berit Hoffmann' + FROM users WHERE username = 'admin'; + + INSERT INTO notifications (recipient_id, type, document_id, reference_id, read, actor_name) + SELECT id, 'REPLY', '${SEED_DOC_ID}', '${COMMENT_IDS[1]}', false, 'Marcel Raddatz' + FROM users WHERE username = 'admin'; + `); +}); + +test.afterAll(() => { + // Remove only the seeded rows (identified by the sentinel actor names) + psql(` + DELETE FROM notifications + WHERE actor_name IN ('Berit Hoffmann', 'Marcel Raddatz') + AND recipient_id = (SELECT id FROM users WHERE username = 'admin'); + `); +}); + +captureProofshots('/', 'dashboard', { + setup: async (page) => { + // Navigate to '/' first so the browser has an origin for localStorage, + // then inject the lastVisited entry directly — no document page load needed. + await page.goto('/'); + await page.waitForLoadState('domcontentloaded'); + await page.evaluate( + ({ id, title }) => { + localStorage.setItem('familienarchiv.lastVisited', JSON.stringify({ id, title })); + }, + { id: SEED_DOC_ID, title: SEED_DOC_TITLE } + ); + } +}); diff --git a/frontend/e2e/proofshots.ts b/frontend/e2e/proofshots.ts index 44124fee..0e34abeb 100644 --- a/frontend/e2e/proofshots.ts +++ b/frontend/e2e/proofshots.ts @@ -1,14 +1,23 @@ /** * Shared proofshot helper for Playwright. * - * Usage in any spec file: + * Basic usage: * import { captureProofshots } from './proofshots'; * captureProofshots('/persons', 'persons'); * - * This registers one test per viewport × theme combination. + * With per-test setup (e.g. seed localStorage before navigation): + * captureProofshots('/persons', 'persons', { + * setup: async (page) => { + * await page.goto('/persons/some-id'); // populates any localStorage state + * } + * }); + * + * The setup callback runs before each screenshot's page.goto(url), so any + * localStorage values it writes persist into the main navigation. + * * Screenshots are saved to proofshot-artifacts/{featureName}/. */ -import { test } from '@playwright/test'; +import { type Page, test } from '@playwright/test'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; @@ -21,20 +30,38 @@ const viewports = [ { name: 'desktop', width: 1440, height: 900 } ]; +interface ProofshotOptions { + /** + * Optional async callback that runs before each screenshot's page.goto(url). + * Use it to seed localStorage, visit a prerequisite page, etc. + */ + setup?: (page: Page) => Promise; +} + /** * Registers Playwright tests that navigate to `url`, apply each theme, * and capture full-page screenshots at all standard viewports. * * @param url The path to screenshot (e.g. '/', '/persons', '/admin') * @param featureName Used as the output directory name and screenshot file prefix + * @param options Optional setup callback and other options */ -export function captureProofshots(url: string, featureName: string): void { +export function captureProofshots( + url: string, + featureName: string, + options?: ProofshotOptions +): void { const outDir = path.join(__dirname, '../../proofshot-artifacts', featureName); fs.mkdirSync(outDir, { recursive: true }); for (const vp of viewports) { for (const theme of ['light', 'dark'] as const) { test(`${featureName} – ${vp.name} – ${theme}`, async ({ page }) => { + // Run optional setup before main navigation (e.g. seed localStorage) + if (options?.setup) { + await options.setup(page); + } + await page.setViewportSize({ width: vp.width, height: vp.height }); await page.goto(url); diff --git a/proofshot-artifacts/dashboard/dashboard-desktop-dark.png b/proofshot-artifacts/dashboard/dashboard-desktop-dark.png index 961bf8a5..e8155f57 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-desktop-dark.png and b/proofshot-artifacts/dashboard/dashboard-desktop-dark.png differ diff --git a/proofshot-artifacts/dashboard/dashboard-desktop-light.png b/proofshot-artifacts/dashboard/dashboard-desktop-light.png index 87b0546b..f297bcd7 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-desktop-light.png and b/proofshot-artifacts/dashboard/dashboard-desktop-light.png differ diff --git a/proofshot-artifacts/dashboard/dashboard-mobile-dark.png b/proofshot-artifacts/dashboard/dashboard-mobile-dark.png index 7069505e..8c981fb5 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-mobile-dark.png and b/proofshot-artifacts/dashboard/dashboard-mobile-dark.png differ diff --git a/proofshot-artifacts/dashboard/dashboard-mobile-light.png b/proofshot-artifacts/dashboard/dashboard-mobile-light.png index c889ffc8..6d99dc30 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-mobile-light.png and b/proofshot-artifacts/dashboard/dashboard-mobile-light.png differ diff --git a/proofshot-artifacts/dashboard/dashboard-tablet-dark.png b/proofshot-artifacts/dashboard/dashboard-tablet-dark.png index 1c12af7f..499e6a60 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-tablet-dark.png and b/proofshot-artifacts/dashboard/dashboard-tablet-dark.png differ diff --git a/proofshot-artifacts/dashboard/dashboard-tablet-light.png b/proofshot-artifacts/dashboard/dashboard-tablet-light.png index 2cf833f7..512076d1 100644 Binary files a/proofshot-artifacts/dashboard/dashboard-tablet-light.png and b/proofshot-artifacts/dashboard/dashboard-tablet-light.png differ