/** * Screenshots der Oberfläche für Anleitung und Design-Abnahme (#002). * * pnpm build && pnpm start # erstes Terminal * pnpm exec tsx scripts/screenshots.ts # zweites Terminal * * Umgebung: * SSHKV_URL Basis-URL (Standard http://localhost:3400) * SSHKV_BILDER Zielordner (Standard docs/anleitung/bilder) * SSHKV_SEITEN Kommagetrennte Auswahl der Seitennamen (Standard: alle) * * Prüft nebenbei, dass keine Seite horizontal scrollt (Design-Vorgabe ab 390 px), und * endet dann mit Fehlercode – so taugt das Skript auch als schneller Layout-Test. */ import { mkdir } from "node:fs/promises"; import { join } from "node:path"; import { chromium } from "@playwright/test"; const BASIS = (process.env["SSHKV_URL"] ?? "http://localhost:3400").replace(/\/$/, ""); const ZIEL = process.env["SSHKV_BILDER"] ?? join(process.cwd(), "docs/anleitung/bilder"); const SEITEN = [ { name: "uebersicht", pfad: "/" }, { name: "schluessel-detail", pfad: "/schluessel/beispiel" }, ]; const ANSICHTEN = [ { name: "desktop", width: 1440, height: 900 }, { name: "mobil", width: 390, height: 844 }, ]; async function main() { const auswahl = process.env["SSHKV_SEITEN"]?.split(",").map((s) => s.trim()); const seiten = auswahl ? SEITEN.filter((s) => auswahl.includes(s.name)) : SEITEN; await mkdir(ZIEL, { recursive: true }); const browser = await chromium.launch(); const fehler: string[] = []; try { for (const ansicht of ANSICHTEN) { const kontext = await browser.newContext({ viewport: { width: ansicht.width, height: ansicht.height }, deviceScaleFactor: 1, locale: "de-DE", timezoneId: "Europe/Berlin", colorScheme: "dark", }); const seite = await kontext.newPage(); for (const s of seiten) { const antwort = await seite.goto(`${BASIS}${s.pfad}`, { waitUntil: "networkidle" }); if (!antwort?.ok()) { fehler.push(`${s.pfad}: HTTP ${antwort?.status() ?? "keine Antwort"}`); continue; } // Erst nach dem Laden der selbst gehosteten Schriften fotografieren, sonst // stehen Fallback-Schriften im Bild. await seite.evaluate(() => document.fonts.ready); const ueberlauf = await seite.evaluate( () => document.documentElement.scrollWidth - document.documentElement.clientWidth, ); if (ueberlauf > 0) { fehler.push(`${s.pfad} @ ${ansicht.width}px: ${ueberlauf}px horizontaler Überlauf`); } const datei = join(ZIEL, `${s.name}-${ansicht.name}.png`); await seite.screenshot({ path: datei, fullPage: true }); console.log(`✓ ${datei}`); } await kontext.close(); } } finally { await browser.close(); } if (fehler.length > 0) { console.error(`\n${fehler.length} Problem(e):\n- ${fehler.join("\n- ")}`); process.exitCode = 1; } } await main();