From b7083d426cd8972530e23731b4ceb95a0a2f3ea4 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 23 Apr 2026 21:02:36 +0200 Subject: [PATCH] refactor(e2e): visual spec shares seedBilateralPair + asserts person-bar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewires briefwechsel-rows.visual.spec.ts against the shared fixture (seedBilateralPair + cleanupBilateralPair), adds afterAll cleanup, and folds the conv-person-bar visibility gate into openBilateral() so both the structural test and the snapshot block fail loudly on a hero-state regression — matching the a11y spec's safety net. Refs #305 Fixes @saraholt follow-ups 1 + 2 + 3 from PR round-2 review Co-Authored-By: Claude Sonnet 4.6 --- frontend/e2e/briefwechsel-rows.visual.spec.ts | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/frontend/e2e/briefwechsel-rows.visual.spec.ts b/frontend/e2e/briefwechsel-rows.visual.spec.ts index 8b7130f0..3b0991bb 100644 --- a/frontend/e2e/briefwechsel-rows.visual.spec.ts +++ b/frontend/e2e/briefwechsel-rows.visual.spec.ts @@ -1,8 +1,13 @@ import { test, expect } from '@playwright/test'; +import { + seedBilateralPair, + cleanupBilateralPair, + type BilateralPair +} from './fixtures/bilateral-correspondence'; // Visual + structural coverage for the new briefwechsel row layout. // -// Seeds a bilateral correspondence pair via the API (beforeAll) so the page +// Seeds a bilateral correspondence pair via the shared fixture so the page // reaches the row state. The structural test asserts that a // ConversationThumbnail tile AND the DistributionBar render — regressions // that silently drop to the hero or break the {#each} wiring fail here. @@ -12,40 +17,25 @@ import { test, expect } from '@playwright/test'; // regenerate after intentional UI changes). CI can opt in via VISUAL=1. const VISUAL = process.env.VISUAL === '1'; -let senderId: string; -let receiverId: string; +let pair: BilateralPair; test.describe('Briefwechsel — thumbnail-row layout', () => { test.beforeAll(async ({ request }) => { - const timestamp = Date.now(); - const senderRes = await request.post('/api/persons', { - data: { firstName: 'Visual', lastName: `Sender-${timestamp}` } - }); - if (!senderRes.ok()) throw new Error(`Create sender failed: ${senderRes.status()}`); - senderId = (await senderRes.json()).id; + pair = await seedBilateralPair(request, 'Visual'); + }); - const receiverRes = await request.post('/api/persons', { - data: { firstName: 'Visual', lastName: `Receiver-${timestamp}` } - }); - if (!receiverRes.ok()) throw new Error(`Create receiver failed: ${receiverRes.status()}`); - receiverId = (await receiverRes.json()).id; - - const docRes = await request.post('/api/documents', { - multipart: { - title: 'Visual Test Brief', - documentDate: '1950-06-15', - senderId, - receiverIds: receiverId - } - }); - if (!docRes.ok()) throw new Error(`Create document failed: ${docRes.status()}`); + test.afterAll(async ({ request }) => { + await cleanupBilateralPair(request, pair); }); async function openBilateral(page: import('@playwright/test').Page) { await page.goto( - `/briefwechsel?senderId=${encodeURIComponent(senderId)}&receiverId=${encodeURIComponent(receiverId)}` + `/briefwechsel?senderId=${encodeURIComponent(pair.senderId)}&receiverId=${encodeURIComponent(pair.receiverId)}` ); await page.waitForSelector('[data-hydrated]'); + // Parity with the a11y spec: fail loudly if we ever end up on the hero + // instead of the row layout. + await expect(page.getByTestId('conv-person-bar')).toBeVisible(); } test('renders a ConversationThumbnail tile and the DistributionBar', async ({ page }) => {