diff --git a/frontend/e2e/documents.spec.ts b/frontend/e2e/documents.spec.ts index 0af7211d..8e77e603 100644 --- a/frontend/e2e/documents.spec.ts +++ b/frontend/e2e/documents.spec.ts @@ -563,41 +563,69 @@ test.describe('PDF annotations — read-only user', () => { // ── J3: Edit document — add an existing tag ──────────────────────────────── // // Verifies that a user can open a document's edit page and assign a tag using -// the TagInput component, then save and see the tag chip on the detail page. +// the TagInput component, then save and see the tag link on the detail page. +// Seeds a unique tag via a throwaway document so the test never depends on the +// seeded "Familie" tag (which admin tests rename during their lifecycle). test.describe('Document editing — tags (J3)', () => { - const baseURL = process.env.E2E_BASE_URL ?? 'http://localhost:3000'; - let tagDocHref: string; + let tagDocId: string; + let seedDocId: string; + let seededTagName: string; test.beforeAll(async ({ request }) => { + const stamp = Date.now().toString(36); + seededTagName = `E2E-J3-Tag-${stamp}`; + + // Create a throwaway document and associate the unique tag with it so it + // exists in the system for the TagInput suggestion list. + const seederRes = await request.post('/api/documents', { + multipart: { title: `E2E J3 Tag Seeder ${stamp}` } + }); + if (!seederRes.ok()) throw new Error(`Create seeder failed: ${seederRes.status()}`); + const seeder = await seederRes.json(); + seedDocId = seeder.id; + + const seedTagRes = await request.put(`/api/documents/${seedDocId}`, { + multipart: { title: seeder.title, tags: seededTagName } + }); + if (!seedTagRes.ok()) throw new Error(`Seed tag failed: ${seedTagRes.status()}`); + + // Create the test document without the tag — the test will add it. const createRes = await request.post('/api/documents', { - multipart: { title: 'E2E Tag Edit Test' } + multipart: { title: `E2E Tag Edit Test ${stamp}` } }); if (!createRes.ok()) throw new Error(`Create document failed: ${createRes.status()}`); const doc = await createRes.json(); - tagDocHref = `${baseURL}/documents/${doc.id}`; + tagDocId = doc.id; + }); + + test.afterAll(async ({ request }) => { + if (tagDocId) await request.delete(`/api/documents/${tagDocId}`); + if (seedDocId) await request.delete(`/api/documents/${seedDocId}`); }); test('user adds an existing tag and sees it on the detail page', async ({ page }) => { - await page.goto(`${tagDocHref}/edit`); + await page.goto(`/documents/${tagDocId}/edit`); await page.waitForSelector('[data-hydrated]'); // TagInput has placeholder "Schlagworte hinzufügen..." when empty. const tagInput = page.getByPlaceholder('Schlagworte hinzufügen...'); await expect(tagInput).toBeVisible(); - // Type the beginning of the seeded "Familie" tag and wait for the suggestion. - await tagInput.fill('Fami'); - const suggestion = page.getByRole('option', { name: /Familie/i }).first(); + // Type the seeded tag name and wait for the suggestion. + await tagInput.fill(seededTagName); + const suggestion = page.getByRole('option', { name: seededTagName }).first(); await expect(suggestion).toBeVisible({ timeout: 5_000 }); await suggestion.click(); // Save the document. await page.getByRole('button', { name: 'Speichern', exact: true }).click(); - // Redirected to detail page — the tag chip must be visible. + // Redirected to detail page — the tag link must be visible in the metadata section. await expect(page).toHaveURL(/\/documents\/[^/]+$/); - await expect(page.getByText(/Familie/)).toBeVisible({ timeout: 5_000 }); + await expect(page.locator('a[href*="?tag="]', { hasText: seededTagName })).toBeVisible({ + timeout: 5_000 + }); await page.screenshot({ path: 'test-results/e2e/document-edit-tag.png' }); }); });