feat(briefwechsel): thumbnail rows with summary quote and bilateral distribution bar (#305) #311

Merged
marcel merged 30 commits from feat/issue-305-briefwechsel-thumbnail-rows into main 2026-04-23 21:38:57 +02:00
Showing only changes of commit 22a4e49794 - Show all commits

View File

@@ -0,0 +1,43 @@
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
});
});
}
}
});
});