import { createRequire } from "node:module"; import { expect, test } from "@playwright/test"; const require = createRequire(import.meta.url); const axePath = require.resolve("axe-core/axe.min.js"); async function expectNoAccessibilityViolations(page: import("@playwright/test").Page) { await page.addScriptTag({ path: axePath }); const violations = await page.evaluate(async () => { const axe = (window as typeof window & { axe: { run: (options: unknown) => Promise<{ violations: Array<{ id: string; impact?: string | null; help: string; nodes: Array<{ target: unknown; failureSummary?: string }> }> }> } }).axe; const result = await axe.run({ runOnly: { type: "tag", values: ["wcag2a", "wcag2aa", "wcag21aa"] } }); return result.violations.map(({ id, impact, help, nodes }) => ({ id, impact, help, nodes: nodes.map((node: { target: unknown; failureSummary?: string }) => ({ target: node.target, failureSummary: node.failureSummary })) })); }); expect(violations).toEqual([]); } for (const viewport of [ { name: "desktop", width: 1280, height: 900 }, { name: "mobile", width: 390, height: 844 } ]) { test(`resident permit self-service is keyboard and accessibility conformant on ${viewport.name}`, async ({ page }) => { const journey = await mockPublicResidentPermitJourney(page); await page.setViewportSize(viewport); await page.goto("/forms/public/resident-parking-permit?theme=light"); await expect(page.getByRole("heading", { level: 1, name: "Anwohnerparkausweis beantragen" })).toBeVisible(); await expectNoAccessibilityViolations(page); const name = page.getByLabel("Name der antragstellenden Person"); await name.focus(); await page.keyboard.type("Ada Lovelace"); await page.keyboard.press("Tab"); await expect(page.getByLabel("E-Mail-Adresse")).toBeFocused(); await page.keyboard.type("ada.lovelace@example.test"); await page.keyboard.press("Tab"); await expect(page.getByLabel("Hauptwohnsitz")).toBeFocused(); await page.keyboard.type("Musterstraße 17, 10115 Berlin"); await page.keyboard.press("Tab"); await expect(page.getByLabel("Kfz-Kennzeichen")).toBeFocused(); await page.keyboard.type("B-AL 1843"); await page.keyboard.press("Tab"); await expect(page.getByRole("button", { name: "Entwurf speichern" })).toBeFocused(); await page.keyboard.press("Enter"); await expect.poll(() => journey.savedValues()).toEqual({ applicant_name: "Ada Lovelace", applicant_email: "ada.lovelace@example.test", residence_address: "Musterstraße 17, 10115 Berlin", licence_plate: "B-AL 1843" }); await page.getByRole("button", { name: "Absenden" }).click(); const confirm = page.getByRole("alertdialog", { name: "Formular absenden" }); await expect(confirm).toBeVisible(); await expectNoAccessibilityViolations(page); await confirm.getByRole("button", { name: "Absenden" }).click(); await expect(page.getByText("Übermittlung eingegangen")).toBeVisible(); await expect(page.getByText("receipt-rpp-2026-0001")).toBeVisible(); await expectNoHorizontalOverflow(page); }); test(`resident permit assisted intake preserves per-field provenance on ${viewport.name}`, async ({ page }) => { const journey = await mockAssistedResidentPermitJourney(page); await page.setViewportSize(viewport); await page.goto("/forms-runtime?theme=light"); await page.getByRole("button", { name: "Assistierte Erfassung" }).click(); const startDialog = page.getByRole("dialog", { name: "Assistierte Erfassung starten" }); await expect(startDialog).toBeVisible(); await expectNoAccessibilityViolations(page); await startDialog.getByLabel("Referenz der betroffenen Partei").fill("party:resident-ada-lovelace"); await startDialog.getByLabel("Referenz der zuständigen Funktion").fill("function:parking-permits"); await startDialog.getByLabel("Zweck").fill("Anwohnerparkausweis beantragen"); await startDialog.getByLabel("Referenz der Rechtsgrundlage").fill("law:resident-parking-permit"); await startDialog.getByLabel("Barrierefreiheits- oder Kommunikationsunterstützung").fill("Leichte Sprache"); const notice = startDialog.getByRole("checkbox", { name: "Datenschutz- und Verfahrenshinweis wurde erteilt" }); await notice.focus(); await page.keyboard.press("Space"); await expect(notice).toBeChecked(); await startDialog.getByLabel("Referenz der betroffenen Partei").focus(); await page.keyboard.press("Tab"); await expect(page.locator(":focus")).toHaveAttribute("aria-label", "Feldhilfe anzeigen"); await page.keyboard.press("Tab"); await expect(startDialog.getByLabel("Referenz der vertretenen Partei")).toBeFocused(); await startDialog.getByRole("button", { name: "Sitzung starten" }).click(); await expect(page).toHaveURL(/\/forms-runtime\/assisted-rpp-1$/); await expect(page.getByRole("heading", { level: 1, name: "Anwohnerparkausweis beantragen" })).toBeVisible(); await page.getByLabel("Name der antragstellenden Person").fill("Ada Lovelace"); await page.getByLabel("E-Mail-Adresse").fill("ada.lovelace@example.test"); await page.getByLabel("Hauptwohnsitz").fill("Musterstraße 17, 10115 Berlin"); await page.getByLabel("Kfz-Kennzeichen").fill("B-AL 1843"); await page.getByLabel("Änderungsgrund").fill("Angaben gemeinsam mit der antragstellenden Person erfasst."); await page.getByRole("button", { name: "Entwurf speichern" }).click(); await page.getByRole("button", { name: "Rücklesen und absenden" }).click(); const readback = page.getByRole("dialog", { name: "Assistiertes Rücklesen erfassen" }); await expect(readback).toBeVisible(); await expect(readback.getByRole("group", { name: "Hauptwohnsitz" })).toBeVisible(); await expectNoAccessibilityViolations(page); const addressSource = readback.getByRole("group", { name: "Hauptwohnsitz" }); await addressSource.getByLabel("Wertquelle").selectOption("document"); await addressSource.getByLabel("Quellenvertrauen").selectOption("verified"); await addressSource.getByLabel("Erklärende Partei oder Quellenreferenz").fill("files:residence-proof-2026"); const plateSource = readback.getByRole("group", { name: "Kfz-Kennzeichen" }); await plateSource.getByLabel("Wertquelle").focus(); await page.keyboard.press("ArrowDown"); await page.keyboard.press("ArrowDown"); await page.keyboard.press("ArrowDown"); await page.keyboard.press("Enter"); await plateSource.getByLabel("Quellenvertrauen").selectOption("verified"); await plateSource.getByLabel("Erklärende Partei oder Quellenreferenz").fill("register:vehicle-B-AL-1843"); await readback.getByRole("button", { name: "Erfassen und fortfahren" }).click(); await expect.poll(() => journey.confirmationSources()).toMatchObject({ applicant_name: { source: "person_statement", confidence: "stated" }, residence_address: { source: "document", confidence: "verified", declared_by_ref: "files:residence-proof-2026" }, licence_plate: { source: "system", confidence: "verified", declared_by_ref: "register:vehicle-B-AL-1843" } }); const submit = page.getByRole("alertdialog", { name: "Formular absenden" }); await submit.getByRole("button", { name: "Absenden" }).click(); await expect(page.getByText("receipt-assisted-rpp-2026-0001")).toBeVisible(); await expect(page.getByText("Rücklesen erfasst")).toBeVisible(); await expectNoHorizontalOverflow(page); }); } test("shared components remain accessible and keyboard operable", async ({ page }) => { await page.goto("/?theme=light"); await expect(page.getByRole("heading", { level: 1, name: "Zentrale GovOPlaN-Oberflächen" })).toBeVisible(); await expectNoAccessibilityViolations(page); const editorActions = page.getByRole("toolbar", { name: "Bearbeitungsaktionen" }); await expect(page.locator("[data-page-archetype='overview']")).toBeVisible(); await expect(editorActions).toHaveAttribute("data-page-refreshable", "true"); await expect(editorActions).toHaveAttribute("data-page-dirty", "true"); await expect(editorActions.getByRole("status")).toHaveText("Unsaved changes"); await expect(editorActions.locator("[data-page-action-separation='destructive']")).toHaveCount(1); await expect(editorActions.locator("[data-page-action-separation='destructive']")).toHaveCSS("border-left-width", "2px"); const actionSlots = await editorActions.locator("[data-page-action-slot]").evaluateAll((elements) => elements.map((element) => element.getAttribute("data-page-action-slot"))); expect(actionSlots).toEqual([ "reload", "context", "destructive", "discard", "save" ]); await expect(editorActions.getByRole("button")).toHaveText([ "Neu laden", "Vorschau öffnen", "Löschen", "Verwerfen", "Änderungen speichern" ]); await editorActions.getByRole("button", { name: "Neu laden" }).focus(); await page.keyboard.press("Tab"); await expect(editorActions.getByRole("button", { name: "Vorschau öffnen" })).toBeFocused(); await page.keyboard.press("Tab"); await expect(editorActions.locator(".disabled-action-tooltip")).toBeFocused(); await expect(page.getByRole("tooltip")).toContainText("Nur die federführende Stelle"); await page.keyboard.press("Tab"); await expect(editorActions.getByRole("button", { name: "Verwerfen" })).toBeFocused(); await page.keyboard.press("Tab"); await expect(editorActions.getByRole("button", { name: "Änderungen speichern" })).toBeFocused(); await page.keyboard.press("Enter"); await expect(editorActions).toHaveAttribute("data-page-dirty", "false"); await expect(editorActions.getByRole("status")).toHaveText("Saved"); await expect(editorActions.getByRole("button", { name: "Verwerfen" })).toBeDisabled(); await expect(editorActions.getByRole("button", { name: "Änderungen speichern" })).toBeDisabled(); const metricDrilldown = page.getByRole("button", { name: "Offene Aufgaben prüfen" }); await metricDrilldown.focus(); await page.keyboard.press("Enter"); await expect(page.getByTestId("metric-drilldown-result")).toHaveText("18 offene Aufgaben"); const opener = page.getByTestId("open-dialog"); await opener.focus(); await page.keyboard.press("Enter"); await expect(page.getByRole("dialog", { name: "Konsequenz vor Ausführung prüfen" })).toBeVisible(); await expectNoAccessibilityViolations(page); await page.keyboard.press("Escape"); await expect(page.getByRole("dialog")).toBeHidden(); await expect(opener).toBeFocused(); }); test("full-page tool launch preserves a bounded return context", async ({ page }) => { await page.goto("/?theme=light"); await page.getByTestId("launch-full-page").click(); await expect(page).toHaveURL(/\/files$/); const returnButton = page.getByRole("button", { name: /RPP-2026-0001.*Anwohnerparkausweis/ }); await expect(returnButton).toBeVisible(); await returnButton.click(); await expect(page).toHaveURL(/\/?\?theme=light$/); }); test("Quick Access preserves focus and adapts to a narrow viewport", async ({ page }) => { await page.route("**/api/v1/quick-access/effective*", async (route) => { await route.fulfill({ contentType: "application/json", body: JSON.stringify(quickAccessPayload(false)) }); }); await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/?theme=light&quick-access=1"); const filesTrigger = page.getByRole("button", { name: "Files" }); await expect(filesTrigger).toBeVisible(); await filesTrigger.click(); const drawer = page.getByRole("dialog", { name: "Files" }); await expect(drawer).toBeVisible(); await expect(drawer.getByRole("button", { name: "Close" })).toBeFocused(); const drawerBounds = await drawer.boundingBox(); expect(drawerBounds?.x).toBeGreaterThanOrEqual(0); expect((drawerBounds?.x ?? 0) + (drawerBounds?.width ?? 0)).toBeLessThanOrEqual(390); await page.keyboard.press("Escape"); await expect(drawer).toBeHidden(); await expect(filesTrigger).toBeFocused(); }); test("F1 resolves focused high-risk help and restores focus accessibly", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/?theme=light&help=1"); const retentionAction = page.getByTestId("f1-retention-action"); await retentionAction.focus(); await page.keyboard.press("F1"); const dialog = page.getByRole("dialog", { name: "Kontexthilfe" }); await expect(dialog).toBeVisible(); await expect(dialog.locator("[data-help-context]")) .toHaveAttribute("data-help-context", "policy.retention.action.apply"); await expect(dialog.getByRole("heading", { level: 3 })) .toHaveText("Aufbewahrungsregeln anwenden"); await expect(dialog).toContainText("topic=policy.admin.retention-and-disposition"); await expect(dialog.getByRole("button", { name: "Administrator-Dokumentation öffnen" })) .toBeVisible(); await expectNoAccessibilityViolations(page); const bounds = await dialog.boundingBox(); expect(bounds?.x).toBeGreaterThanOrEqual(0); expect((bounds?.x ?? 0) + (bounds?.width ?? 0)).toBeLessThanOrEqual(390); await page.keyboard.press("Escape"); await expect(dialog).toBeHidden(); await expect(retentionAction).toBeFocused(); const fallbackAction = page.getByTestId("f1-fallback-action"); await fallbackAction.focus(); await page.keyboard.press("F1"); const fallbackDialog = page.getByRole("dialog", { name: "Kontexthilfe" }); await expect(fallbackDialog.locator("[data-help-context]")) .toHaveAttribute("data-help-context", "core.conformance.action.review"); await expect(fallbackDialog).toContainText("fallback_context=campaigns.list"); await page.keyboard.press("Escape"); await expect(fallbackAction).toBeFocused(); }); test("View focus has a deliberate permission-derived all-tools escape", async ({ page }) => { await page.route("**/api/v1/quick-access/effective*", async (route) => { await route.fulfill({ contentType: "application/json", body: JSON.stringify(quickAccessPayload(true)) }); }); await page.goto("/?theme=light&quick-access=focused"); const rail = page.locator(".quick-access-rail"); await expect(rail).toHaveAttribute("data-view-focus-mode", "focused"); await expect(page.getByRole("button", { name: "Files" })).toBeVisible(); await expect(page.getByRole("button", { name: "Messages" })).toHaveCount(0); const allTools = page.locator(".quick-access-view-mode-button"); await expect(allTools).toHaveAttribute("aria-pressed", "false"); await allTools.click(); await expect(rail).toHaveAttribute("data-view-focus-mode", "all"); await expect(page.getByRole("button", { name: "Messages" })).toBeVisible(); await page.getByRole("button", { name: "Messages" }).click(); const explanation = page.locator(".quick-access-view-mode[role='status']"); await expect(explanation).toHaveAttribute("data-view-focus-mode", "all"); await explanation.getByRole("button").click(); await expect(rail).toHaveAttribute("data-view-focus-mode", "focused"); await expect(page.getByRole("button", { name: "Messages" })).toHaveCount(0); }); test("product navigation hides package topology behind stable bilingual destinations", async ({ page }) => { await page.setViewportSize({ width: 1280, height: 900 }); await page.goto("/?theme=light&product-navigation=1"); await page.getByRole("button", { name: "Expand navigation" }).click(); const primary = page.locator(".icon-nav > .icon-nav-group"); await expect(primary.getByRole("link")).toHaveText([ "Arbeit", "Dateien", "Nachrichten", "Kalender" ]); await expect(primary.getByRole("link", { name: /Tasks|Files|Mail|Postbox|Calendar/ })).toHaveCount(0); const allTools = page.locator("[data-product-navigation='all-tools']"); await expect(allTools.getByText("Alle verfügbaren Werkzeuge", { exact: true })).toBeVisible(); await allTools.locator("summary").click(); await expect(allTools.getByRole("link")).toHaveText([ "Tasks", "Files", "Mail", "Postbox", "Calendar" ]); await expectNoAccessibilityViolations(page); }); test("a stale View focus falls back safely in a sparse optional-module catalogue", async ({ page }) => { await page.route("**/api/v1/quick-access/effective*", async (route) => { await route.fulfill({ contentType: "application/json", body: JSON.stringify(quickAccessPayload(false)) }); }); await page.goto("/?theme=light&quick-access=stale-focus"); const rail = page.locator(".quick-access-rail"); await expect(rail).toHaveAttribute("data-view-focus-mode", "unavailable"); await expect(page.getByRole("button", { name: "Files" })).toBeVisible(); await expect(page.locator(".quick-access-view-mode-button")).toHaveCount(0); await page.getByRole("button", { name: "Files" }).click(); await expect(page.locator(".quick-access-view-mode[role='status']")) .toHaveAttribute("data-view-focus-mode", "unavailable"); }); test("light and dark desktop geometry remains stable", async ({ page }) => { await page.setViewportSize({ width: 1440, height: 1000 }); await page.goto("/?theme=light"); await expect(page.locator("[data-conformance-id='shared-ui-lab']")).toHaveScreenshot("shared-ui-light-desktop.png", { animations: "disabled", maxDiffPixelRatio: 0.005 }); await page.goto("/?theme=dark"); await expect(page.locator("[data-conformance-id='shared-ui-lab']")).toHaveScreenshot("shared-ui-dark-desktop.png", { animations: "disabled", maxDiffPixelRatio: 0.005 }); }); test("narrow layout preserves task order without horizontal overflow", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await page.goto("/?theme=light"); await expect(page.getByText("Bedingung prüfen")).toBeVisible(); const overflowing = await page.evaluate(() => Array.from(document.querySelectorAll("body *")) .map((element) => { const rect = element.getBoundingClientRect(); return { element: `${element.tagName.toLowerCase()}.${Array.from(element.classList).join(".")}`, left: Math.round(rect.left), right: Math.round(rect.right), scrollWidth: element.scrollWidth, clientWidth: element.clientWidth }; }) .filter(({ left, right }) => left < -1 || right > window.innerWidth + 1) .slice(0, 20)); expect(overflowing).toEqual([]); await expect(page.locator("[data-page-action-archetype='editor'] [data-page-action-group='trailing']")) .toHaveCSS("justify-content", "flex-end"); const saveRightEdge = await page.locator("[data-page-action-archetype='editor'] [data-page-action-slot='save']").evaluate((element) => element.getBoundingClientRect().right); const actionBarRightEdge = await page.locator("[data-page-action-archetype='editor']").evaluate((element) => element.getBoundingClientRect().right); expect(Math.abs(actionBarRightEdge - saveRightEdge)).toBeLessThanOrEqual(1); await expect(page.locator("[data-conformance-id='shared-ui-lab']")).toHaveScreenshot("shared-ui-light-narrow.png", { animations: "disabled", maxDiffPixelRatio: 0.005 }); }); async function expectNoHorizontalOverflow(page: import("@playwright/test").Page) { const overflowing = await page.evaluate(() => Array.from(document.querySelectorAll("body *")) .filter((element) => { const style = window.getComputedStyle(element); return style.display !== "none" && style.visibility !== "hidden"; }) .map((element) => { const rect = element.getBoundingClientRect(); return { element: `${element.tagName.toLowerCase()}.${Array.from(element.classList).join(".")}`, left: Math.round(rect.left), right: Math.round(rect.right) }; }) .filter(({ left, right }) => left < -1 || right > window.innerWidth + 1) .slice(0, 20)); expect(overflowing).toEqual([]); } async function mockPublicResidentPermitJourney(page: import("@playwright/test").Page) { let current = residentPermitInstance("public-rpp-1", "started", 1, {}); let savedValues: Record = {}; await page.route("**/api/v1/forms-runtime/**", async (route) => { const request = route.request(); const path = new URL(request.url()).pathname; const method = request.method(); if (path.endsWith("/public/profiles/resident-parking-permit/start") && method === "POST") { return fulfillJson(route, { session_id: "session-public-rpp-1", mode: "anonymous", status: "active", expires_at: "2026-08-25T10:00:00Z", instance: current, token: "public-rpp-token", replayed: false }); } if (path.endsWith("/public/intake") && method === "GET") { return fulfillJson(route, { instance: current, definition: residentPermitDefinition() }); } if (path.endsWith("/public/intake") && method === "PATCH") { const payload = request.postDataJSON() as { values: Record }; savedValues = payload.values; current = residentPermitInstance("public-rpp-1", "draft", 2, payload.values); return fulfillJson(route, current); } if (path.endsWith("/public/intake/submit") && method === "POST") { const payload = request.postDataJSON() as { values: Record }; current = { ...residentPermitInstance("public-rpp-1", "submitted", 3, payload.values), receipt_id: "receipt-rpp-2026-0001" }; return fulfillJson(route, current); } return route.abort("failed"); }); return { savedValues: () => savedValues }; } async function mockAssistedResidentPermitJourney(page: import("@playwright/test").Page) { let current = residentPermitInstance("assisted-rpp-1", "started", 1, {}, true); let confirmationSources: Record = {}; let confirmations: unknown[] = []; await page.route("**/api/v1/forms-runtime/**", async (route) => { const request = route.request(); const path = new URL(request.url()).pathname; const method = request.method(); if (path.endsWith("/instances") && method === "GET") { return fulfillJson(route, { instances: [], total: 0, offset: 0, limit: 200 }); } if (path.endsWith("/assisted-intake/profiles") && method === "GET") { return fulfillJson(route, { profiles: [{ profile_id: "assisted-profile-rpp", public_id: "resident-parking-permit", definition_ref: residentPermitDefinition().reference, mode: "assisted", enabled: true, revision: 1, draft_ttl_seconds: 2_592_000, invitation_ttl_seconds: 1_209_600, rate_limit_per_minute: 60, metadata: { definition_title: "Anwohnerparkausweis beantragen" } }] }); } if (path.endsWith("/assisted-intake/start") && method === "POST") { return fulfillJson(route, { session_id: "assisted-session-rpp-1", mode: "assisted", status: "active", expires_at: "2026-08-25T10:00:00Z", instance: current, token: null, replayed: false }); } if (path.endsWith("/instances/assisted-rpp-1/definition") && method === "GET") { return fulfillJson(route, residentPermitDefinition()); } if (path.endsWith("/instances/assisted-rpp-1/history") && method === "GET") { return fulfillJson(route, { revisions: [current] }); } if (path.endsWith("/instances/assisted-rpp-1/events") && method === "GET") { return fulfillJson(route, { events: [{ event_id: `event-${current.revision}`, event_type: current.status === "submitted" ? "submitted" : "draft_saved", instance_revision: current.revision, status: current.status, occurred_at: current.recorded_at, actor_id: "operator-1", payload: {} }] }); } if (path.endsWith("/instances/assisted-rpp-1/handoffs") && method === "GET") { return fulfillJson(route, { handoffs: [] }); } if (path.endsWith("/instances/assisted-rpp-1/assisted-confirmations") && method === "GET") { return fulfillJson(route, { confirmations }); } if (path.endsWith("/instances/assisted-rpp-1/assisted-confirmations") && method === "POST") { const payload = request.postDataJSON() as { field_sources: Record }; confirmationSources = payload.field_sources; const confirmation = { confirmation_id: "confirmation-rpp-1", instance_id: "assisted-rpp-1", instance_revision: current.revision, outcome: "confirmed", method: "spoken_readback", confirmed_by_ref: "party:resident-ada-lovelace", operator_actor_id: "operator-1", confirmed_at: "2026-08-24T10:10:00Z", payload_sha256: "a".repeat(64), correction_note: null, metadata: { field_sources: confirmationSources } }; confirmations = [confirmation]; return fulfillJson(route, confirmation); } if (path.endsWith("/instances/assisted-rpp-1/submit") && method === "POST") { const payload = request.postDataJSON() as { values: Record }; current = { ...residentPermitInstance("assisted-rpp-1", "submitted", current.revision + 1, payload.values, true), receipt_id: "receipt-assisted-rpp-2026-0001" }; return fulfillJson(route, current); } if (path.endsWith("/instances/assisted-rpp-1") && method === "PATCH") { const payload = request.postDataJSON() as { values: Record }; current = residentPermitInstance("assisted-rpp-1", "draft", current.revision + 1, payload.values, true); return fulfillJson(route, current); } if (path.endsWith("/instances/assisted-rpp-1") && method === "GET") { return fulfillJson(route, current); } return route.abort("failed"); }); return { confirmationSources: () => confirmationSources }; } function residentPermitDefinition() { return { reference: { kind: "form", owner_module: "forms", object_id: "resident-parking-permit-application", tenant_id: "tenant-1", version: "3", label: "Anwohnerparkausweis beantragen" }, key: "resident_parking_permit.apply", temporal: { revision: "3", recorded_at: "2026-08-24T10:00:00Z" }, title: "Resident parking permit application", description: "Apply digitally or together with an authorized service worker.", fields: [ residentPermitField("applicant_name", "Applicant name", "text", { min_length: 2, max_length: 200 }), residentPermitField("applicant_email", "Applicant email", "email", { format: "email" }), residentPermitField("residence_address", "Primary residence", "text", { max_length: 500 }), residentPermitField("licence_plate", "Licence plate", "text", { max_length: 20 }) ], publication_state: "published", allow_drafts: true, max_attachments: 0, signature_requirement: "none", policy_refs: ["law:resident-parking-permit"], handoff_kinds: [], fallback_locale: "de", localizations: [{ locale: "de", title: "Anwohnerparkausweis beantragen", description: "Beantragen Sie den Anwohnerparkausweis digital oder gemeinsam mit einer berechtigten Servicestelle.", field_labels: { applicant_name: "Name der antragstellenden Person", applicant_email: "E-Mail-Adresse", residence_address: "Hauptwohnsitz", licence_plate: "Kfz-Kennzeichen" }, field_help_texts: {}, option_labels: {}, page_titles: {}, section_titles: {} }] }; } function residentPermitField( key: string, label: string, valueType: "text" | "email", constraints: Record ) { return { key, label, value_type: valueType, required: true, help_text: null, options: [], constraints, default_value: null, visibility_condition: null }; } function residentPermitInstance( instanceId: string, status: string, revision: number, values: Record, assisted = false ) { return { reference: { kind: "form_instance", owner_module: "forms_runtime", object_id: instanceId, tenant_id: "tenant-1", version: String(revision), label: "Anwohnerparkausweis beantragen" }, tenant_id: "tenant-1", instance_id: instanceId, revision, status, definition_ref: residentPermitDefinition().reference, values, validation_results: [], attachment_refs: [], signature_refs: [], handoff_refs: [], service_ref: null, receipt_id: null as string | null, recorded_at: "2026-08-24T10:00:00Z", change_reason: revision === 1 ? "Assisted session started." : "Draft saved.", created_by: "operator-1", changed_by: "operator-1", metadata: assisted ? { intake: { session_id: "assisted-session-rpp-1", profile_id: "assisted-profile-rpp", mode: "assisted", channel: "counter", affected_party_ref: "party:resident-ada-lovelace", represented_party_ref: null, authority_basis: "self", purpose: "Anwohnerparkausweis beantragen", legal_basis_ref: "law:resident-parking-permit", consent_basis: "in-person-confirmation", notice_given: true, responsible_function_ref: "function:parking-permits", language: "de", accessibility_needs: ["Leichte Sprache"], field_sources: {}, operator: { actor_id: "operator-1", auth_method: "session" } } } : {}, status_access: null, replayed: false }; } async function fulfillJson( route: import("@playwright/test").Route, body: unknown ) { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(body) }); } function quickAccessPayload(includeMessages: boolean) { const files = { id: "files", label: "Files", description: "Files beside the current task", icon: "files", order: 10, enabled: true, forced: false, locked_by: null, tools: [{ contract_version: "1", id: "files.recent", module_id: "files", category_id: "files", label: "Recent files", description: "Select an authorized file without leaving this case.", icon: "files", surface_id: "files.route.files", full_page_path: "/files", required_all: [], required_any: [], order: 10, default_enabled: true, modes: ["select"], availability: "global", accepted_reference_kinds: [], returned_reference_kinds: ["files.file-version"], help_context_id: "files.quick_access.files", enabled: true, forced: false, locked_by: null }] }; const messages = { id: "messages", label: "Messages", description: "Messages beside the current task", icon: "messages", order: 20, enabled: true, forced: false, locked_by: null, tools: [{ contract_version: "1", id: "postbox.unread", module_id: "postbox", category_id: "messages", label: "Unread messages", description: "Open an authorized unread message.", icon: "messages", surface_id: "postbox.route.postbox", full_page_path: "/postbox", required_all: [], required_any: [], order: 10, default_enabled: true, modes: ["view"], availability: "global", accepted_reference_kinds: [], returned_reference_kinds: ["postbox.message"], help_context_id: "postbox.quick_access.messages", enabled: true, forced: false, locked_by: null }] }; return { categories: includeMessages ? [files, messages] : [files], diagnostics: [] }; }