diff --git a/frontend/e2e/korrespondenz.spec.ts b/frontend/e2e/korrespondenz.spec.ts new file mode 100644 index 00000000..225847cd --- /dev/null +++ b/frontend/e2e/korrespondenz.spec.ts @@ -0,0 +1,114 @@ +import { test, expect } from '@playwright/test'; + +test.describe('Korrespondenz – empty state', () => { + test('shows the search heading when no person is selected', async ({ page }) => { + await page.goto('/korrespondenz'); + await expect(page.getByText(/Korrespondenz durchsuchen/i)).toBeVisible(); + await page.screenshot({ path: 'test-results/e2e/korrespondenz-empty.png' }); + }); + + test('nav link goes to /korrespondenz', async ({ page }) => { + await page.goto('/'); + // Click the nav link (desktop text or mobile icon) + const navLink = page.getByRole('link', { name: /Korrespondenz/i }).first(); + await navLink.click(); + await expect(page).toHaveURL(/\/korrespondenz/); + }); +}); + +test.describe('Korrespondenz – single-person mode', () => { + test('shows hint bar and documents when navigated with senderId', async ({ page }) => { + // Get a real person ID from the persons list + await page.goto('/persons'); + const firstPersonLink = page.locator('a[href^="/persons/"]').first(); + await firstPersonLink.click(); + await page.waitForURL(/\/persons\/.+/); + + // Extract the person ID from the URL + const personId = page.url().split('/persons/')[1].split('?')[0]; + + // Navigate to korrespondenz in single-person mode + await page.goto(`/korrespondenz?senderId=${personId}`); + + // Hint bar should be visible + await expect(page.getByText(/Alle Briefe von/i)).toBeVisible(); + + // Filter controls should be active (not dimmed) + const filterStrip = page.locator('[aria-disabled="false"]').first(); + await expect(filterStrip).toBeAttached(); + + await page.screenshot({ path: 'test-results/e2e/korrespondenz-single-person.png' }); + }); + + test('sort toggle changes URL direction param', async ({ page }) => { + await page.goto('/persons'); + const firstPersonLink = page.locator('a[href^="/persons/"]').first(); + await firstPersonLink.click(); + await page.waitForURL(/\/persons\/.+/); + const personId = page.url().split('/persons/')[1].split('?')[0]; + + await page.goto(`/korrespondenz?senderId=${personId}&dir=DESC`); + await page.getByTestId('conv-sort-btn').click(); + + await expect(page).toHaveURL(/dir=ASC/); + await page.screenshot({ path: 'test-results/e2e/korrespondenz-sort-asc.png' }); + }); +}); + +test.describe('Korrespondenz – bilateral mode', () => { + test('shows asymmetry bar when both persons have shared documents', async ({ page }) => { + // Navigate to a person then follow a co-correspondent suggestion if available + await page.goto('/persons'); + const firstPersonLink = page.locator('a[href^="/persons/"]').first(); + await firstPersonLink.click(); + await page.waitForURL(/\/persons\/.+/); + const senderId = page.url().split('/persons/')[1].split('?')[0]; + + // Try to find a co-correspondent link from the person detail page + const corrLink = page + .locator('a[href*="/korrespondenz?senderId="][href*="receiverId="]') + .first(); + if (await corrLink.isVisible({ timeout: 2000 }).catch(() => false)) { + await corrLink.click(); + await page.waitForURL(/\/korrespondenz\?.*receiverId=/); + + // Hint bar should NOT be shown in bilateral mode + await expect(page.getByText(/Alle Briefe von/i)).not.toBeVisible(); + + await page.screenshot({ path: 'test-results/e2e/korrespondenz-bilateral.png' }); + } else { + // No bilateral data available for this person — skip with a note + test.skip(true, `No bilateral correspondent links found for person ${senderId}`); + } + }); + + test('swap button swaps sender and receiver in URL', async ({ page }) => { + await page.goto('/persons'); + const firstPersonLink = page.locator('a[href^="/persons/"]').first(); + await firstPersonLink.click(); + await page.waitForURL(/\/persons\/.+/); + const senderId = page.url().split('/persons/')[1].split('?')[0]; + + const corrLink = page + .locator('a[href*="/korrespondenz?senderId="][href*="receiverId="]') + .first(); + if (await corrLink.isVisible({ timeout: 2000 }).catch(() => false)) { + const href = await corrLink.getAttribute('href'); + await corrLink.click(); + await page.waitForURL(/\/korrespondenz\?.*receiverId=/); + + // Extract original receiverId from the href + const url = new URL(href!, 'http://x'); + const originalReceiverId = url.searchParams.get('receiverId')!; + + // Click swap + await page.getByTestId('conv-swap-btn').click(); + + // After swap the former receiver is now senderId + await expect(page).toHaveURL(new RegExp(`senderId=${originalReceiverId}`)); + await page.screenshot({ path: 'test-results/e2e/korrespondenz-swapped.png' }); + } else { + test.skip(true, `No bilateral correspondent links found for person ${senderId}`); + } + }); +});