112 lines
5.9 KiB
TypeScript
112 lines
5.9 KiB
TypeScript
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();
|
|
});
|
|
});
|