import { SEEDED_TEST_CONTENT } from "../../fixtures/test-constants" import { createCollectionEntry, deleteCollectionEntry, listCollectionEntries } from "./admin-api" type ContentEntry = { id?: string _id?: string | { $oid?: string } translationKey?: string [key: string]: unknown } function getEntryId(entry: ContentEntry): string | undefined { if (typeof entry.id === "string") return entry.id if (typeof entry._id === "string") return entry._id if (entry._id && typeof entry._id === "object" && typeof entry._id.$oid === "string") return entry._id.$oid return undefined } const SEEDED_TRANSLATION_KEYS = new Set(Object.values(SEEDED_TEST_CONTENT).map((entry) => entry.translationKey)) const SEEDED_CONTENT_ENTRIES = [ { active: true, type: "page", lang: "de", translationKey: SEEDED_TEST_CONTENT.home.translationKey, name: "Playwright Startseite", path: SEEDED_TEST_CONTENT.home.path, teaserText: "Deterministisch erzeugte Testseite fuer API- und E2E-Tests.", meta: { title: "Playwright Startseite", description: "Seeded Startseite fuer stabile Playwright-Tests.", keywords: ["playwright", "seed", "e2e"], }, blocks: [ { type: "hero", headline: "Playwright Seed Startseite", headlineH1: true, tagline: "Deterministische Testdaten", subline: "Diese Seite wird vor dem Testlauf frisch ueber die Admin-API angelegt.", containerWidth: "wide", callToAction: { buttonText: "Zum Kontakt", buttonLink: `/de${SEEDED_TEST_CONTENT.contact.path}`, }, }, { type: "features", anchorId: "seed-features", headline: "Stabile Grundlage fuer Frontend-Tests", tagline: "Seed", padding: { top: "md", bottom: "md" }, featureBoxes: [ { icon: "lightning", title: "Frisch angelegt", text: "Die Inhalte werden in globalSetup erstellt statt aus Demo-Daten uebernommen.", }, { icon: "database", title: "API-nah", text: "Die Seed-Daten kommen ueber dieselben Collection-Endpunkte wie das CMS.", }, { icon: "globe", title: "Mehrsprachig", text: "DE und EN teilen sich denselben translationKey fuer Routing-Checks.", }, ], }, { type: "richtext", anchorId: "seed-richtext", headline: "Mehr Kontext", tagline: "API + UI", padding: { top: "md", bottom: "md" }, imagePosition: "none", text: "

Dieser Richtext-Block prueft, dass formatierter HTML-Inhalt im SPA gerendert wird.

", }, { type: "accordion", anchorId: "seed-faq", headline: "Hauefige Fragen", tagline: "Verhalten", padding: { top: "md", bottom: "md" }, accordionItems: [ { question: "Warum Seed-Daten?", answer: "

Damit Tests nicht blind auf bestehende Inhalte oder Demo-Routen vertrauen.

", open: true, }, { question: "Was wird geprueft?", answer: "

API-Antworten, Routing, Sprachwechsel und Block-Rendering.

", open: false, }, ], }, ], }, { active: true, type: "page", lang: "en", translationKey: SEEDED_TEST_CONTENT.home.translationKey, name: "Playwright Home", path: SEEDED_TEST_CONTENT.home.path, teaserText: "Deterministically seeded page for API and E2E coverage.", meta: { title: "Playwright Home", description: "Seeded home page for stable Playwright tests.", keywords: ["playwright", "seed", "home"], }, blocks: [ { type: "hero", headline: "Playwright Seed Home", headlineH1: true, tagline: "Deterministic fixtures", subline: "This page is recreated before every test run through the admin API.", containerWidth: "wide", callToAction: { buttonText: "Go to contact", buttonLink: `/en${SEEDED_TEST_CONTENT.contact.path}`, }, }, { type: "features", anchorId: "seed-features", headline: "Stable frontend coverage", tagline: "Seed", padding: { top: "md", bottom: "md" }, featureBoxes: [ { icon: "lightning", title: "Freshly created", text: "The content is created during globalSetup instead of relying on demo data.", }, { icon: "database", title: "API-backed", text: "The seed uses the same collection endpoints as the CMS itself.", }, { icon: "globe", title: "Localized", text: "DE and EN share the same translationKey for route switching checks.", }, ], }, { type: "richtext", anchorId: "seed-richtext", headline: "More context", tagline: "API + UI", padding: { top: "md", bottom: "md" }, imagePosition: "none", text: "

This richtext block proves that formatted HTML content renders in the SPA.

", }, { type: "accordion", anchorId: "seed-faq", headline: "Common questions", tagline: "Behavior", padding: { top: "md", bottom: "md" }, accordionItems: [ { question: "Why seeded data?", answer: "

So the tests do not depend on existing demo pages or editorial content.

", open: true, }, { question: "What is covered?", answer: "

API responses, routing, locale switching and block rendering.

", open: false, }, ], }, ], }, { active: true, type: "page", lang: "de", translationKey: SEEDED_TEST_CONTENT.contact.translationKey, name: "Playwright Kontakt", path: SEEDED_TEST_CONTENT.contact.path, teaserText: "Seeded Kontaktseite fuer Formular- und Routing-Tests.", meta: { title: "Playwright Kontakt", description: "Seeded Kontaktseite fuer Playwright.", keywords: ["playwright", "kontakt"], }, blocks: [ { type: "hero", headline: "Kontakt fuer Testlauf", headlineH1: true, tagline: "Seed", subline: "Diese Seite prueft das aktuelle ContactForm-Rendering.", }, { type: "contact-form", anchorId: "kontaktformular", headline: "Schreibe uns", padding: { top: "md", bottom: "md" }, }, ], }, { active: true, type: "page", lang: "en", translationKey: SEEDED_TEST_CONTENT.contact.translationKey, name: "Playwright Contact", path: SEEDED_TEST_CONTENT.contact.path, teaserText: "Seeded contact page for form and routing tests.", meta: { title: "Playwright Contact", description: "Seeded contact page for Playwright.", keywords: ["playwright", "contact"], }, blocks: [ { type: "hero", headline: "Contact for the test run", headlineH1: true, tagline: "Seed", subline: "This page verifies the current contact form rendering.", }, { type: "contact-form", anchorId: "contact-form", headline: "Write to us", padding: { top: "md", bottom: "md" }, }, ], }, { active: false, type: "page", lang: "de", translationKey: SEEDED_TEST_CONTENT.inactive.translationKey, name: "Playwright Inaktiv", path: SEEDED_TEST_CONTENT.inactive.path, teaserText: "Nicht aktive Seed-Seite fuer 404-Checks.", meta: { title: "Playwright Inaktiv", description: "Nicht aktive Seed-Seite fuer Routing-Tests.", keywords: ["playwright", "inactive"], }, blocks: [ { type: "richtext", anchorId: "inactive", headline: "Sollte nicht sichtbar sein", tagline: "Seed", padding: { top: "md", bottom: "md" }, imagePosition: "none", text: "

Diese Seite ist absichtlich inaktiv und darf im Frontend nicht erscheinen.

", }, ], }, ] as const export async function cleanupSeededTestContent(baseURL: string): Promise { const contentEntries = await listCollectionEntries(baseURL, "content") const seededEntries = contentEntries.filter( (entry) => typeof entry.translationKey === "string" && SEEDED_TRANSLATION_KEYS.has(entry.translationKey) ) let deleted = 0 for (const entry of seededEntries) { const entryId = getEntryId(entry) if (!entryId) continue const ok = await deleteCollectionEntry(baseURL, "content", entryId) if (ok) deleted++ } return deleted } export async function seedTestContent(baseURL: string): Promise { let created = 0 for (const entry of SEEDED_CONTENT_ENTRIES) { await createCollectionEntry(baseURL, "content", entry as unknown as Record) created++ } return created } export async function ensureSeededTestContent(baseURL: string): Promise<{ deleted: number; created: number }> { const deleted = await cleanupSeededTestContent(baseURL) const created = await seedTestContent(baseURL) return { deleted, created } }