104 lines
4.2 KiB
TypeScript
104 lines
4.2 KiB
TypeScript
import { chromium } from "@playwright/test";
|
|
import "dotenv/config";
|
|
import { prisma } from "@/lib/db";
|
|
import { anmelden, SEED_GERAET, SEED_TAG, SEED_VORLAGE } from "./helfer";
|
|
|
|
/**
|
|
* Was vor dem ersten Ablauf stimmen muss (#018).
|
|
*
|
|
* Bisher standen die Voraussetzungen als Satz im Kopfkommentar jeder Datei
|
|
* („Voraussetzung: ein gebauter Stand laeuft und `pnpm beispiel:vorlage` hat
|
|
* …“). Ein Kommentar prueft nichts. Stimmte etwas davon nicht, fiel das erst
|
|
* mitten im Lauf auf, und die Meldung sprach von einem Zeitablauf oder von null
|
|
* Treffern — nie von der Ursache.
|
|
*
|
|
* Hier wird es geprueft, einmal, bevor irgendein Ablauf startet. Jede Meldung
|
|
* sagt, **was** fehlt und **was zu tun ist**.
|
|
*/
|
|
|
|
const APP_URL = process.env["E2E_APP_URL"] ?? "http://127.0.0.1:3000";
|
|
|
|
function fehlen(was: string, abhilfe: string): never {
|
|
throw new Error(`Ende-zu-Ende-Tests: ${was}\n → ${abhilfe}`);
|
|
}
|
|
|
|
export default async function vorbereiten(): Promise<void> {
|
|
if (!process.env["SEED_ADMIN_EMAIL"] || !process.env["SEED_ADMIN_PASSWORD"]) {
|
|
fehlen(
|
|
"SEED_ADMIN_EMAIL oder SEED_ADMIN_PASSWORD fehlt.",
|
|
"Beide stehen in der .env und müssen zu dem Administrator passen, den der Seed angelegt hat.",
|
|
);
|
|
}
|
|
|
|
// 1. Laeuft ueberhaupt etwas an dieser Adresse?
|
|
const antwort = await fetch(`${APP_URL}/api/gesundheit`, { signal: AbortSignal.timeout(5000) }).catch(
|
|
() => undefined,
|
|
);
|
|
if (!antwort?.ok) {
|
|
fehlen(
|
|
`Unter ${APP_URL} antwortet keine Anwendung.`,
|
|
"Erst bauen und starten: pnpm build && PORT=3300 APP_URL=http://127.0.0.1:3300 pnpm start — " +
|
|
"und die Adresse über E2E_APP_URL mitgeben. Gegen `pnpm dev` laufen die Abläufe nicht " +
|
|
"(siehe CLAUDE.md, „Oberfläche prüfen“).",
|
|
);
|
|
}
|
|
|
|
// 2. Steht der Seed-Bestand, mit dem die Ablaeufe arbeiten?
|
|
const vorlage = await prisma.vorlage.findFirst({
|
|
where: { name: SEED_VORLAGE },
|
|
select: { id: true, versionen: { where: { status: "VEROEFFENTLICHT" }, select: { id: true } } },
|
|
});
|
|
if (!vorlage || vorlage.versionen.length === 0) {
|
|
fehlen(
|
|
`Die Vorlage „${SEED_VORLAGE}“ fehlt oder ist nicht veröffentlicht.`,
|
|
"pnpm db:seed laufen lassen.",
|
|
);
|
|
}
|
|
const geraet = await prisma.geraet.findUnique({ where: { tagCode: SEED_TAG }, select: { id: true } });
|
|
if (!geraet) {
|
|
fehlen(`Das Beispielgerät ${SEED_GERAET} (${SEED_TAG}) fehlt.`, "pnpm db:seed laufen lassen.");
|
|
}
|
|
|
|
/*
|
|
* 2b. In welchem Betriebsmodus laeuft die Installation?
|
|
*
|
|
* Ein Ablauf soll das nicht selbst aus der Datenbank holen muessen — und zwei
|
|
* Quellen fuer dieselbe Auskunft liefen frueher oder spaeter auseinander. Der
|
|
* Modus steht danach in `E2E_BETRIEBSMODUS`, und ein Ablauf, der nur in einem
|
|
* der beiden Sinn ergibt, ueberspringt sich selbst mit einem Grund.
|
|
*/
|
|
const einstellung = await prisma.einstellung.findUnique({
|
|
where: { id: "global" },
|
|
select: { modus: true },
|
|
});
|
|
process.env["E2E_BETRIEBSMODUS"] = einstellung?.modus ?? "INTERN";
|
|
|
|
/*
|
|
* 3. Liest der Server **dieselbe** Datenbank?
|
|
*
|
|
* Der Testprozess schreibt über DATABASE_URL aus der .env, der Server bekommt
|
|
* seine eigene mit. Zeigen beide woandershin, legt ein Ablauf seine Daten in
|
|
* die eine und sucht sie in der anderen. Geprüft wird an einer Vorlage, die
|
|
* hier entsteht und gleich wieder verschwindet.
|
|
*/
|
|
const probe = `ZZ Datenbankprüfung ${Date.now()}`;
|
|
const angelegt = await prisma.vorlage.create({ data: { name: probe, kategorie: "ZZ Test" } });
|
|
const browser = await chromium.launch();
|
|
try {
|
|
const tab = await browser.newPage({ baseURL: APP_URL });
|
|
await anmelden(tab);
|
|
await tab.goto(`/vorlagen?suche=${encodeURIComponent(probe)}`);
|
|
if ((await tab.getByRole("link", { name: probe }).count()) === 0) {
|
|
fehlen(
|
|
"Der Server unter Test liest eine andere Datenbank als dieser Lauf.",
|
|
"DATABASE_URL des Testprozesses (aus der .env) und die des Servers müssen auf dieselbe " +
|
|
"Datenbank zeigen — sonst schreibt der Ablauf in die eine und sucht in der anderen.",
|
|
);
|
|
}
|
|
} finally {
|
|
await browser.close();
|
|
await prisma.vorlage.delete({ where: { id: angelegt.id } });
|
|
await prisma.$disconnect();
|
|
}
|
|
}
|