13 Tests gegen die gebaute Anwendung mit eigener Datenbank auf Port 3111 - also durch Middleware, Authentifizierung, Validierung und Datenbank hindurch. Genau die Schicht, die Unit-Tests nicht erreichen. Laufzeit rund 20 Sekunden. api.spec.ts prueft, was bisher nur von Hand geprueft war: - Einrichtung sperrt sich nach dem ersten Konto - ohne Anmeldung liefert jeder Endpunkt 401 - fremdes Origin und falscher Content-Type werden abgewiesen - SSRF-Sperren greifen - Datentrennung: ein zweites Konto bekommt auf fremde Projekte, Aufgaben und Adminwege durchgaengig 404 beziehungsweise 403, das Original bleibt unveraendert - Aufgaben: Reihenfolge, abgeleiteter Fortschritt, untergeschobene IDs - Export ohne Geheimnisse, Import je Strategie ui.spec.ts geht den Weg eines Menschen: anmelden, Projekt anlegen, Aufgaben anlegen und ziehen, suchen, abmelden. Das Ziehen wird nach einem Neuladen erneut geprueft - sonst waere nur die Anzeige getestet, nicht das Speichern. Zwei Vorkehrungen: - global-setup.ts bricht ab, wenn der Datenbankname nicht "test" enthaelt, und zwar vor dem TRUNCATE. Der teuerste denkbare Fehler waere eine Testreihe, die die Produktivdaten leert. - Playwright startet den Server selbst mit eigener DATABASE_URL und eigenem Port; eine laufende Instanz auf 3000 stoert nicht. Beim Schreiben zeigte sich, dass synthetische Zieh-Gesten eine Pause vor dem Loslassen brauchen - dnd-kit wertet die Bewegung in einem eigenen Frame aus und faende sonst kein Ziel. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
import { execFileSync } from "node:child_process";
|
||
import { PrismaClient } from "@prisma/client";
|
||
|
||
/**
|
||
* Bereitet die Testdatenbank vor: Schema einspielen und leeren.
|
||
*
|
||
* Die Datenbank muss vorher existieren. Anlegen ist bewusst nicht Teil des
|
||
* Setups – in CI erzeugt sie der Postgres-Dienst, oertlich einmalig:
|
||
*
|
||
* docker exec nebula-db psql -U nebula -d postgres -c "CREATE DATABASE nebula_e2e_test"
|
||
*/
|
||
|
||
const DATABASE_URL =
|
||
process.env.E2E_DATABASE_URL ??
|
||
"postgresql://nebula:nebula@localhost:5432/nebula_e2e_test?schema=public";
|
||
|
||
/**
|
||
* Reihenfolge egal, weil CASCADE – aber vollstaendig muss sie sein, sonst
|
||
* schleppen Laeufe Reste mit.
|
||
*/
|
||
const TABLES = [
|
||
"Task",
|
||
"Note",
|
||
"RepoSnapshot",
|
||
"Project",
|
||
"Credential",
|
||
"Session",
|
||
"WebAuthnChallenge",
|
||
"GitConnection",
|
||
"User",
|
||
"AppSettings",
|
||
];
|
||
|
||
export default async function globalSetup() {
|
||
const name = new URL(DATABASE_URL).pathname.replace(/^\//, "");
|
||
|
||
// Schutz vor dem teuersten aller Fehler: eine Testreihe, die die echte
|
||
// Datenbank leert. Der Name muss "test" enthalten, sonst passiert nichts.
|
||
if (!name.includes("test")) {
|
||
throw new Error(
|
||
`Die Testdatenbank heisst "${name}" und enthaelt nicht "test". ` +
|
||
"Aus Sicherheitsgruenden abgebrochen – E2E_DATABASE_URL pruefen.",
|
||
);
|
||
}
|
||
|
||
console.log(`[e2e] Datenbank: ${name}`);
|
||
|
||
execFileSync("npx", ["prisma", "migrate", "deploy"], {
|
||
env: { ...process.env, DATABASE_URL },
|
||
stdio: "pipe",
|
||
shell: process.platform === "win32",
|
||
});
|
||
|
||
const prisma = new PrismaClient({ datasources: { db: { url: DATABASE_URL } } });
|
||
try {
|
||
const list = TABLES.map((table) => `"${table}"`).join(", ");
|
||
await prisma.$executeRawUnsafe(`TRUNCATE TABLE ${list} RESTART IDENTITY CASCADE`);
|
||
console.log("[e2e] Datenbank geleert.");
|
||
} finally {
|
||
await prisma.$disconnect();
|
||
}
|
||
}
|