Baustein 2: Inhalte einlesen und pruefen, Handouts, Suche, Glossar
Die fachlichen Inhalte liegen als Dateien unter content/ und werden beim Start eingelesen, geprueft und in den Speicher geladen. - Inhaltslader mit Zod-Schemata und Querverweispruefung - Fehlermeldungen nennen Datei und Zeile, gesammelt statt beim ersten Fehler geworfen; die Anwendung startet bei Fehlern nicht - npm run inhalte:pruefen prueft ohne Start - Handout-Ansicht mit festem Aufbau, Uebersicht nach Themenbloecken - Volltextsuche mit Gewichtung und Trefferausschnitt - Gelesen-Markierung je Handout - Glossar mit Suche und automatischer Verlinkung in den Handouts - Beispielinhalte: 4 Wochen, 12 Handouts, 24 Merkkarten, 4 Aufgaben, 4 Checklisten, 2 Lernzielkontrollen, 24 Glossareintraege - rahmenplan.yaml aus FIAusbV 2020 und KMK-Rahmenlehrplan, mit Fundstellen - gray-matter entfernt, YAML-Kopf wird selbst herausgeloest - npm run screenshots nimmt die Bilder fuer die Anleitung auf - 39 neue Tests, insgesamt 68 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e856349cd4
commit
1af5613e9b
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Nimmt die Bildschirmfotos für die Anleitung auf.
|
||||
*
|
||||
* npm run build && npm run start (in einer zweiten Konsole)
|
||||
* npm run screenshots
|
||||
*
|
||||
* Die Bilder landen unter docs/bilder/ und werden bei jedem Lauf überschrieben.
|
||||
* So veralten sie nicht – wer die Oberfläche ändert, lässt das Skript neu laufen.
|
||||
*
|
||||
* Umgebungsvariablen:
|
||||
* LERNBAR_BASIS Adresse der laufenden Anwendung (Vorgabe http://localhost:3000)
|
||||
* LERNBAR_AUSBILDER E-Mail des Ausbilderkontos
|
||||
* LERNBAR_AZUBI E-Mail des Azubikontos
|
||||
* LERNBAR_PASSWORT_* zugehörige Passwörter
|
||||
*/
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { chromium, type Page } from '@playwright/test';
|
||||
|
||||
const BASIS = process.env.LERNBAR_BASIS ?? 'http://localhost:3000';
|
||||
const ZIEL = path.join(process.cwd(), 'docs', 'bilder');
|
||||
|
||||
const AUSBILDER = {
|
||||
email: process.env.LERNBAR_AUSBILDER ?? 'ausbilder@betrieb.de',
|
||||
passwort: process.env.LERNBAR_PASSWORT_AUSBILDER ?? 'ausbilder-start',
|
||||
};
|
||||
const AZUBI = {
|
||||
email: process.env.LERNBAR_AZUBI ?? 'azubi@betrieb.de',
|
||||
passwort: process.env.LERNBAR_PASSWORT_AZUBI ?? 'azubi-start-2026',
|
||||
};
|
||||
|
||||
const SCHREIBTISCH = { width: 1280, height: 900 };
|
||||
const HANDY = { width: 390, height: 844 };
|
||||
|
||||
async function anmelden(seite: Page, konto: { email: string; passwort: string }) {
|
||||
await seite.goto(`${BASIS}/anmelden`);
|
||||
await seite.waitForSelector('#email');
|
||||
await seite.fill('#email', konto.email);
|
||||
await seite.fill('#passwort', konto.passwort);
|
||||
await seite.click('button[type=submit]');
|
||||
await seite.waitForURL(`${BASIS}/`);
|
||||
}
|
||||
|
||||
async function abmelden(seite: Page) {
|
||||
await seite.click('button:has-text("Abmelden")');
|
||||
await seite.waitForURL(/anmelden/);
|
||||
}
|
||||
|
||||
async function bild(seite: Page, name: string, ganzeSeite = true) {
|
||||
const datei = path.join(ZIEL, `${name}.png`);
|
||||
await seite.screenshot({ path: datei, fullPage: ganzeSeite });
|
||||
console.log(` ${path.relative(process.cwd(), datei)}`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
fs.mkdirSync(ZIEL, { recursive: true });
|
||||
|
||||
const browser = await chromium.launch();
|
||||
const umgebung = await browser.newContext({ viewport: SCHREIBTISCH, locale: 'de-DE', colorScheme: 'light' });
|
||||
const seite = await umgebung.newPage();
|
||||
|
||||
console.log('Bildschirmfotos werden aufgenommen …');
|
||||
|
||||
// --- Anmeldung ---
|
||||
await seite.goto(`${BASIS}/anmelden`);
|
||||
await seite.waitForSelector('#email');
|
||||
await bild(seite, '01-anmelden');
|
||||
|
||||
// --- Ausbilder ---
|
||||
await anmelden(seite, AUSBILDER);
|
||||
await bild(seite, '02-ausbilder-ueberblick');
|
||||
|
||||
await seite.goto(`${BASIS}/verwaltung`);
|
||||
await seite.waitForSelector('#neu-name');
|
||||
await bild(seite, '03-verwaltung');
|
||||
|
||||
await abmelden(seite);
|
||||
|
||||
// --- Azubi ---
|
||||
await anmelden(seite, AZUBI);
|
||||
await bild(seite, '10-azubi-start');
|
||||
|
||||
await seite.goto(`${BASIS}/handouts`);
|
||||
await seite.waitForSelector('h1');
|
||||
await bild(seite, '11-handouts-liste');
|
||||
|
||||
await seite.goto(`${BASIS}/handouts?suche=subnetting`);
|
||||
await seite.waitForSelector('h2');
|
||||
await bild(seite, '12-handouts-suche');
|
||||
|
||||
await seite.goto(`${BASIS}/handouts/N3`);
|
||||
await seite.waitForSelector('h1');
|
||||
await seite.click('.pruefungsfrage > summary');
|
||||
await bild(seite, '13-handout-n3');
|
||||
|
||||
await seite.goto(`${BASIS}/glossar`);
|
||||
await seite.waitForSelector('h1');
|
||||
await bild(seite, '14-glossar');
|
||||
|
||||
// --- Dunkle Darstellung ---
|
||||
await seite.goto(`${BASIS}/handouts/N3`);
|
||||
await seite.waitForSelector('button[aria-pressed]');
|
||||
await seite.click('button[aria-pressed="false"]');
|
||||
await seite.waitForTimeout(200);
|
||||
await bild(seite, '20-dunkel');
|
||||
await seite.click('button[aria-pressed="true"]');
|
||||
|
||||
// --- Handy ---
|
||||
const handy = await browser.newContext({
|
||||
viewport: HANDY,
|
||||
locale: 'de-DE',
|
||||
isMobile: true,
|
||||
hasTouch: true,
|
||||
deviceScaleFactor: 2,
|
||||
});
|
||||
const handySeite = await handy.newPage();
|
||||
await anmelden(handySeite, AZUBI);
|
||||
await handySeite.goto(`${BASIS}/handouts/N3`);
|
||||
await handySeite.waitForSelector('h1');
|
||||
await bild(handySeite, '30-handy-handout');
|
||||
|
||||
await browser.close();
|
||||
console.log('Fertig.');
|
||||
}
|
||||
|
||||
main().catch((fehler) => {
|
||||
console.error('Die Bildschirmfotos konnten nicht aufgenommen werden.');
|
||||
console.error(fehler instanceof Error ? fehler.message : fehler);
|
||||
console.error(`Läuft die Anwendung unter ${BASIS}? Stimmen LERNBAR_AUSBILDER und LERNBAR_AZUBI?`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user