feat(doku): Anleitung, PDF und Ende-zu-Ende-Abnahme (#36)
Prüfung / pruefung (push) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s

This commit was merged in pull request #36.
This commit is contained in:
2026-09-26 09:04:15 +00:00
parent 9bd198a531
commit fbbb634e56
104 changed files with 4527 additions and 299 deletions
+9 -12
View File
@@ -1,5 +1,6 @@
import { expect, test, type Page } from "@playwright/test";
import "dotenv/config";
import { anmelden, kundeWaehlen } from "./helfer";
/**
* Die Geraeteliste durch die Oberflaeche (#011).
@@ -11,8 +12,10 @@ import "dotenv/config";
* einlesen, loeschen — und anschliessend, ob es wirklich in der Datenbank steht:
* durch Neuladen.
*
* Voraussetzung: ein **gebauter** Stand laeuft (`pnpm build && pnpm start`) und
* `SEED_ADMIN_EMAIL`/`SEED_ADMIN_PASSWORD` sind gesetzt.
* Voraussetzungen — ein gebauter Stand antwortet, der Seed-Bestand steht und der
* Server liest dieselbe Datenbank wie dieser Lauf — prueft
* `tests/e2e/global-setup.ts` vor dem ersten Ablauf (#018). Eigene Daten legt
* dieser Ablauf selbst an; auf vorhandene baut er nicht.
*
* Der Ablauf raeumt hinter sich auf: an den angelegten Geraeten haengt kein Lauf,
* sie lassen sich also loeschen. Ihre Tag-Codes bleiben vergeben, und genau das
@@ -21,16 +24,6 @@ import "dotenv/config";
const MARKE = `ZZ-E2E-${Date.now()}`;
async function anmelden(seite: Page) {
const email = process.env["SEED_ADMIN_EMAIL"];
const passwort = process.env["SEED_ADMIN_PASSWORD"];
if (!email || !passwort) throw new Error("SEED_ADMIN_EMAIL und SEED_ADMIN_PASSWORD fehlen.");
await seite.goto("/anmelden");
await seite.fill('input[name="email"]', email);
await seite.fill('input[name="passwort"]', passwort);
await Promise.all([seite.waitForURL("**/"), seite.click('button[type="submit"]')]);
}
/** Der Abschnitt „Gerät anlegen“ – eindeutig ueber seinen eigenen Knopf. */
function anlegenFormular(seite: Page) {
return seite.locator("section", { has: seite.getByRole("button", { name: "Gerät anlegen" }) });
@@ -70,6 +63,7 @@ test.describe("Geräte", () => {
await formular.getByLabel("Hostname").fill(name);
await formular.getByLabel("Seriennummer").fill(`${MARKE}-SN`);
await formular.getByLabel("Typ").selectOption("NOTEBOOK");
await kundeWaehlen(formular);
await formular.getByRole("button", { name: "Gerät anlegen" }).click();
// Der Tag-Code steht in der Meldung – er kommt gleich auf den Aufkleber.
@@ -109,6 +103,7 @@ test.describe("Geräte", () => {
const formular = anlegenFormular(page);
await formular.getByLabel("Hostname").fill(name);
await kundeWaehlen(formular);
await formular.getByRole("button", { name: "Gerät anlegen" }).click();
await expect(formular.getByRole("status")).toContainText("wurde angelegt");
@@ -150,6 +145,7 @@ test.describe("Geräte", () => {
`${MARKE}-CSV-BOESE;;SN-BOESE;INV-2;Tablet;`,
].join("\r\n"),
);
await kundeWaehlen(bereich);
await bereich.getByRole("button", { name: "Einlesen" }).click();
await expect(bereich.getByRole("status")).toContainText("1 von 2 Zeilen angelegt, 1 Zeile abgewiesen.");
@@ -175,6 +171,7 @@ test.describe("Geräte", () => {
const formular = anlegenFormular(page);
await formular.getByLabel("Bezeichnung").fill(name);
await formular.getByLabel("Typ").selectOption("RAUM");
await kundeWaehlen(formular);
await formular.getByRole("button", { name: "Gerät anlegen" }).click();
await expect(formular.getByRole("status")).toContainText("wurde angelegt");