Files
familienarchiv/frontend/e2e/briefwechsel-rows.visual.spec.ts
Marcel 22a4e49794 test(briefwechsel): scaffold visual-regression spec for row layout
Adds a Playwright spec gated on VISUAL=1 with one snapshot per
(mobile/tablet/desktop × light/dark) = 6 baselines. Snapshots stay
skipped in CI until the baseline set is captured and committed —
running `playwright test --update-snapshots briefwechsel-rows`
against a seeded backend generates them.

Structural check runs unconditionally so the file is wired into CI
today rather than waiting for the baseline capture step.

Refs #305

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-23 14:51:16 +02:00

44 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, expect } from '@playwright/test';
// Visual + structural coverage for the new briefwechsel row layout.
//
// Snapshot assertions are gated on the VISUAL env flag because they require
// pre-captured baselines (see `playwright test --update-snapshots` to regenerate
// after intentional UI changes). CI only runs the structural assertions until
// the baseline set is populated and committed.
const VISUAL = process.env.VISUAL === '1';
test.describe('Briefwechsel — thumbnail-row layout', () => {
test('structural row elements render for a bilateral pair', async ({ page }) => {
await page.goto('/briefwechsel');
// Hero is visible until a person is selected.
await expect(page.getByTestId('conv-hero')).toBeVisible();
});
// Visual regression — one snapshot per (viewport × theme). Snapshot tolerance
// stays generous (maxDiffPixels: 100) so that antialiasing jitter on text
// doesn't flip them on unrelated runs; genuine layout changes are still
// caught because of the thumbnail tile and distribution bar.
test.describe('snapshots', () => {
test.skip(!VISUAL, 'VISUAL=1 required to compare baselines');
for (const viewport of [
{ name: 'mobile', width: 375, height: 812 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'desktop', width: 1280, height: 800 }
] as const) {
for (const theme of ['light', 'dark'] as const) {
test(`${viewport.name} / ${theme}`, async ({ page }) => {
await page.setViewportSize({ width: viewport.width, height: viewport.height });
await page.emulateMedia({ colorScheme: theme });
await page.goto('/briefwechsel');
await expect(page).toHaveScreenshot(`briefwechsel-${viewport.name}-${theme}.png`, {
maxDiffPixels: 100,
fullPage: true
});
});
}
}
});
});