import AxeBuilder from "@axe-core/playwright"; import { expect, test } from "@playwright/test"; import { authenticatedStatePath } from "../global-setup"; import { expectAuthenticatedShell, fillMarkdown, openNewKnowledgePage } from "./support/v2"; // Reuses the single shared login performed once in global-setup.ts (the login // endpoint is rate-limited — see that file's comment) rather than each test signing // in for itself; only auth-journey.spec.ts exercises the login endpoint directly. test.use({ storageState: authenticatedStatePath }); test.describe("discovery: search, revisions, backlinks and tags", () => { test("a page can be found by search, filtered by tag, and shows backlinks", async ({ page }) => { const uniqueTitle = `E2E-zoekpagina ${Date.now()}`; const tag = `e2etag${Date.now()}`; await page.goto("/"); await expectAuthenticatedShell(page); await openNewKnowledgePage(page); await page.getByLabel("Paginatitel").fill(uniqueTitle); await fillMarkdown(page, "Inhoud met een uniek doorzoekbaar woord zoekbaarheidsproef."); await page.getByLabel(/Labels/).fill(tag); await page.getByRole("button", { name: "Publiceren", exact: true }).click(); await expect(page.getByRole("heading", { name: uniqueTitle })).toBeVisible(); // The tag appears as a chip on the page. await expect(page.getByText(tag)).toBeVisible(); // A second page links to the first — proving backlinks. await openNewKnowledgePage(page); const linkingTitle = `E2E-linkpagina ${Date.now()}`; await page.getByLabel("Paginatitel").fill(linkingTitle); await fillMarkdown(page, `Zie [[${uniqueTitle}]] voor meer.`); await page.getByRole("button", { name: "Publiceren", exact: true }).click(); await expect(page.getByRole("heading", { name: linkingTitle })).toBeVisible(); // Navigate to the target page via search, then check its backlinks panel. await page.goto("/search"); await expect(page.getByRole("heading", { name: "Zoeken" })).toBeVisible(); const searchAccessibility = await new AxeBuilder({ page }).analyze(); expect(searchAccessibility.violations).toEqual([]); // Scoped to the search results list specifically: on a desktop viewport the // permanent sidebar tree also shows a same-named entry once the page exists, so an // unscoped locator would be ambiguous. const searchResults = page.getByRole("region", { name: "Zoekresultaten" }); await page.getByLabel("Zoekterm").fill("zoekbaarheidsproef"); await page.getByRole("button", { name: "Zoekopdracht uitvoeren" }).click(); await expect(searchResults.getByRole("link", { name: new RegExp(uniqueTitle) })).toBeVisible(); // Tag filter narrows results to just the tagged page. await page.getByLabel("Label").fill(tag); await page.getByRole("button", { name: "Zoekopdracht uitvoeren" }).click(); await expect(searchResults.getByRole("link", { name: new RegExp(uniqueTitle) })).toBeVisible(); await page.getByLabel("Label", { exact: true }).fill(`${tag}-absent`); await page.getByRole("button", { name: "Zoekopdracht uitvoeren" }).click(); await expect(searchResults.getByText("Geen resultaten voor deze zoekterm.")).toBeVisible(); await page.getByLabel("Zoekterm").fill(""); await page.getByLabel("Label", { exact: true }).fill(tag); await page.getByRole("button", { name: "Zoekopdracht uitvoeren" }).click(); await expect(searchResults.getByRole("link", { name: new RegExp(uniqueTitle) })).toBeVisible(); await searchResults.getByRole("link", { name: new RegExp(uniqueTitle) }).click(); await expect(page.getByRole("heading", { name: uniqueTitle })).toBeVisible(); // Scoped to the backlinks panel: on a desktop viewport the permanent sidebar tree // also shows a same-named entry for the linking page. await page.getByText("Pagina's die hierheen linken").click(); const backlinksPanel = page.locator(".backlinks"); await expect(backlinksPanel.getByRole("button", { name: linkingTitle })).toBeVisible(); }); test("revision history lets an editor preview and restore a past revision without losing history", async ({ page }) => { const originalTitle = `E2E-revisiepagina ${Date.now()}`; await page.goto("/"); await expectAuthenticatedShell(page); await openNewKnowledgePage(page); await page.getByLabel("Paginatitel").fill(originalTitle); await fillMarkdown(page, "Oorspronkelijke inhoud."); await page.getByRole("button", { name: "Publiceren", exact: true }).click(); await expect(page.getByRole("heading", { name: originalTitle })).toBeVisible(); const updatedTitle = `${originalTitle} (bijgewerkt)`; await page.getByRole("button", { name: "Bewerken" }).click(); await page.getByLabel("Paginatitel").fill(updatedTitle); await page.getByRole("button", { name: "Wijzigingen publiceren" }).click(); await expect(page.getByRole("heading", { name: updatedTitle })).toBeVisible(); await page.getByText("Revisiegeschiedenis").click(); await expect(page.getByRole("button", { name: `Revisie 1: ${originalTitle}` })).toBeVisible(); const revisionAccessibility = await new AxeBuilder({ page }).analyze(); expect(revisionAccessibility.violations).toEqual([]); await page.getByRole("button", { name: `Revisie 1: ${originalTitle}` }).click(); await expect(page.getByRole("heading", { name: `Revisie 1: ${originalTitle}` })).toBeVisible(); await page.getByRole("button", { name: "Deze revisie herstellen" }).click(); await expect(page.getByRole("heading", { name: originalTitle, exact: true })).toBeVisible(); // History is never rewritten: the "(bijgewerkt)" state remains revision 2. The // history panel was already open before the restore and refreshes in place — // it must not be re-toggled here (that would close it instead). await expect(page.getByRole("button", { name: `Revisie 2: ${updatedTitle}` })).toBeVisible(); }); });