import { test as base, expect, type Page } from "@playwright/test" import { attachConsoleMonitor } from "../fixtures/console-monitor" import { ADMIN_UI_CREDENTIALS, TEST_ADMIN_BASE_URL } from "../fixtures/test-constants" export const test = base.extend({ page: async ({ page }, use) => { const monitor = attachConsoleMonitor(page) const origGoto = page.goto.bind(page) const origReload = page.reload.bind(page) page.goto = ((url: string, opts?: any) => origGoto(url, { waitUntil: "domcontentloaded", ...opts })) as typeof page.goto page.reload = ((opts?: any) => origReload({ waitUntil: "domcontentloaded", ...opts })) as typeof page.reload await use(page) monitor.assertNoErrors() }, }) export async function loginToAdmin(page: Page): Promise { await page.goto(`${TEST_ADMIN_BASE_URL}/login`) // Admin bootet als SPA; das Formular ist oft erst nach Chunk-Ladevorgang interaktiv. await expect(page.getByLabel(/Benutzername|Username/i)).toBeVisible({ timeout: 20000 }) await page.getByLabel(/Benutzername|Username/i).fill(ADMIN_UI_CREDENTIALS.username) await page.getByLabel(/Passwort|Password/i).fill(ADMIN_UI_CREDENTIALS.password) await page.getByRole("button", { name: /Anmelden|Sign in|Login/i }).click() await expect(page).toHaveURL(/\/projects\//, { timeout: 15000 }) await expect(page.locator("main")).toBeVisible() } export async function openNovaProjectDashboard(page: Page): Promise { await loginToAdmin(page) const germanLocaleButton = page.getByRole("button", { name: /^Deutsch$/ }) if ((await germanLocaleButton.count()) > 0) { await germanLocaleButton.first().click() } const openNovaButton = page.getByRole("button", { name: /Nova öffnen|Open Nova/i }) if ((await openNovaButton.count()) > 0 && (await openNovaButton.first().isVisible())) { await openNovaButton.first().click() } await expect(page.getByRole("textbox", { name: /Kollektionen durchsuchen|Search collections/i })).toBeVisible({ timeout: 15000, }) } export async function openContentCollection(page: Page): Promise { await openCollection(page, /Inhalte/, "content", "Inhalte") } export async function openNewContentEntry(page: Page): Promise { await openNewCollectionEntry(page, /Inhalte/, "content", "Inhalte") } export async function openContentEntry(page: Page, rowText: string | RegExp): Promise { await openContentCollection(page) const entryRow = page.getByRole("row").filter({ hasText: rowText }).first() await expect(entryRow).toBeVisible() await entryRow.click() await expect(page).toHaveURL(/\/collections\/content\/entries\/[^/?]+/) await expect(page.locator("main")).toBeVisible() } export async function openNavigationCollection(page: Page): Promise { await openCollection(page, /Navigation/, "navigation", "Navigation") } export async function openNewNavigationEntry(page: Page): Promise { await openNewCollectionEntry(page, /Navigation/, "navigation", "Navigation") } export async function openMedialibCollection(page: Page): Promise { await openCollection(page, /Mediathek/, "medialib", "Mediathek") } export async function openNewMedialibEntry(page: Page): Promise { await openNewCollectionEntry(page, /Mediathek/, "medialib", "Mediathek") } async function openCollection(page: Page, linkName: RegExp, slug: string, heading: string): Promise { await openNovaProjectDashboard(page) await page.getByRole("link", { name: linkName }).first().click() await expect(page).toHaveURL(new RegExp(`/collections/${slug}(\\?.*)?$`)) await expect(page.locator("main h1")).toHaveText(heading) } async function openNewCollectionEntry(page: Page, linkName: RegExp, slug: string, heading: string): Promise { await openCollection(page, linkName, slug, heading) await page.getByRole("button", { name: /Neuer Eintrag|New Entry/i }).click() await expect(page).toHaveURL(new RegExp(`/collections/${slug}/entries/new`)) await expect(page.getByRole("heading", { level: 1, name: /Neuer Eintrag|New Entry/i })).toBeVisible() } export { expect, type Page }