From a967483cd9809c596cb675d8c8e5f8366c89fac2 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Mar 2026 22:26:03 +0100 Subject: [PATCH] fix(e2e): update tests to match current UI and fix panel persistence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Code: - Persist panelOpen to localStorage so panel stays open after reload - Auto-open panel to Metadaten when document has no file (no prior state) Tests: - Nav active state: check bg-nav-active instead of text-brand-navy (nav uses semantic tokens since dark mode refactor) - Save button: use exact:true to avoid matching "Speichern & abschließen" (new button was added alongside the plain "Speichern" button) Note: annotation tests (documents.spec.ts:324, 356) are pre-existing flaky failures due to test data contamination, not caused by this PR. Co-Authored-By: Claude Sonnet 4.6 --- frontend/e2e/documents.spec.ts | 6 +++--- frontend/e2e/history.spec.ts | 4 ++-- frontend/e2e/persons.spec.ts | 2 +- frontend/src/routes/documents/[id]/+page.svelte | 11 +++++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/frontend/e2e/documents.spec.ts b/frontend/e2e/documents.spec.ts index cd144535..8ddac2b1 100644 --- a/frontend/e2e/documents.spec.ts +++ b/frontend/e2e/documents.spec.ts @@ -25,7 +25,7 @@ test.describe('Document list', () => { test('navigation bar shows active state for Dokumente', async ({ page }) => { const navLink = page.getByRole('navigation').getByRole('link', { name: 'Dokumente' }); - await expect(navLink).toHaveClass(/text-brand-navy/); + await expect(navLink).toHaveClass(/bg-nav-active/); }); test('text search filters the document list', async ({ page }) => { @@ -91,7 +91,7 @@ test.describe('Document creation', () => { await page.waitForSelector('[data-hydrated]'); await page.getByLabel('Titel').fill('E2E Testbrief'); - await page.getByRole('button', { name: /Speichern/i }).click(); + await page.getByRole('button', { name: 'Speichern', exact: true }).click(); await expect(page).toHaveURL(/\/documents\/[^/]+$/); await expect(page.getByRole('heading', { name: 'E2E Testbrief' })).toBeVisible(); @@ -112,7 +112,7 @@ test.describe('Document editing', () => { await page.waitForSelector('[data-hydrated]'); await page.getByLabel('Titel').fill('E2E Testbrief (überarbeitet)'); - await page.getByRole('button', { name: /Speichern/i }).click(); + await page.getByRole('button', { name: 'Speichern', exact: true }).click(); await expect(page).toHaveURL(/\/documents\/[^/]+$/); await expect(page.getByText('E2E Testbrief (überarbeitet)')).toBeVisible(); diff --git a/frontend/e2e/history.spec.ts b/frontend/e2e/history.spec.ts index 9d012d8d..ede436e1 100644 --- a/frontend/e2e/history.spec.ts +++ b/frontend/e2e/history.spec.ts @@ -25,7 +25,7 @@ test.describe('Document history panel', () => { await page.goto('/documents/new'); await page.waitForSelector('[data-hydrated]'); await page.getByLabel('Titel').fill('E2E History Test Dokument'); - await page.getByRole('button', { name: /Speichern/i }).click(); + await page.getByRole('button', { name: 'Speichern', exact: true }).click(); // Wait for redirect to the new document's UUID-based URL (not /documents/new) await page.waitForURL(/\/documents\/[0-9a-f-]{36}$/); docPath = new URL(page.url()).pathname; @@ -34,7 +34,7 @@ test.describe('Document history panel', () => { await page.goto(`${docPath}/edit`); await page.waitForSelector('[data-hydrated]'); await page.getByLabel('Titel').fill('E2E History Test Dokument (bearbeitet)'); - await page.getByRole('button', { name: /Speichern/i }).click(); + await page.getByRole('button', { name: 'Speichern', exact: true }).click(); await page.waitForURL(/\/documents\/[0-9a-f-]{36}$/); await context.close(); diff --git a/frontend/e2e/persons.spec.ts b/frontend/e2e/persons.spec.ts index e1089a71..1b5aed2d 100644 --- a/frontend/e2e/persons.spec.ts +++ b/frontend/e2e/persons.spec.ts @@ -212,7 +212,7 @@ test.describe('Conversations', () => { test('nav link is active on the conversations page', async ({ page }) => { await page.goto('/conversations'); const navLink = page.getByRole('link', { name: 'Konversationen' }); - await expect(navLink).toHaveClass(/text-brand-navy/); + await expect(navLink).toHaveClass(/bg-nav-active/); }); test('sort toggle changes the button label', async ({ page }) => { diff --git a/frontend/src/routes/documents/[id]/+page.svelte b/frontend/src/routes/documents/[id]/+page.svelte index dbfdf827..24e11344 100644 --- a/frontend/src/routes/documents/[id]/+page.svelte +++ b/frontend/src/routes/documents/[id]/+page.svelte @@ -67,6 +67,7 @@ $effect(() => { const LS_KEY_HEIGHT = 'doc-panel-height'; const LS_KEY_TAB = 'doc-panel-tab'; +const LS_KEY_OPEN = 'doc-panel-open'; let panelOpen = $state(false); let panelHeight = $state(0); // set to full height on mount @@ -79,6 +80,7 @@ onMount(() => { const savedHeight = localStorage.getItem(LS_KEY_HEIGHT); const savedTab = localStorage.getItem(LS_KEY_TAB); + const savedOpen = localStorage.getItem(LS_KEY_OPEN); if (savedTab && ['metadata', 'transcription', 'discussion', 'history'].includes(savedTab)) { activeTab = savedTab as DocumentPanelTab; @@ -90,6 +92,14 @@ onMount(() => { if (!isNaN(h) && h >= 80) panelHeight = h; } + if (savedOpen === 'true') { + panelOpen = true; + } else if (savedOpen === null && !doc?.filePath) { + // No prior state and no file — open to metadata so the panel is immediately useful. + panelOpen = true; + activeTab = 'metadata'; + } + localStorageRestored = true; function onKeyDown(e: KeyboardEvent) { @@ -111,6 +121,7 @@ $effect(() => { if (!localStorageRestored) return; localStorage.setItem(LS_KEY_HEIGHT, String(panelHeight)); localStorage.setItem(LS_KEY_TAB, activeTab); + localStorage.setItem(LS_KEY_OPEN, String(panelOpen)); });