Files
proxdeploy/tests/e2e/grundgeruest.spec.ts
T
florian.wildeandClaude Opus 5.5 871bb3a77c feat: Grundgerüst mit Anmeldung, Layout und Design-Tokens
Next.js 16, Prisma 7, Tailwind 4 und Vitest/Playwright, Konfiguration aus
Laufzettel übernommen, weil dort derselbe Stack erprobt ist.

Die Farben der Branding-Vorgabe stehen als Tokens in globals.css, das
helle Theme setzt dieselben Namen neu. Amber und Rot sind dort
abgedunkelt, sonst reicht der Kontrast nicht – ein Test prüft beide
Themes gegen 4,5:1.

Anmeldung mit lokalem Benutzer, Rolle je Anfrage aus der Datenbank,
Audit-Log per Trigger nur anhängbar. Geprüft im gebauten Stand auf
1440 px und 390 px.

Closes #001

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:23:41 +02:00

66 lines
2.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test, type Page } from "@playwright/test";
const BENUTZER = process.env["E2E_BENUTZER"] ?? "admin";
const PASSWORT = process.env["E2E_PASSWORT"] ?? "proxdeploy-dev-admin";
async function anmelden(page: Page) {
await page.goto("/");
await expect(page).toHaveURL(/\/anmelden/);
await page.getByLabel("Benutzername").fill(BENUTZER);
await page.getByLabel("Passwort").fill(PASSWORT);
await page.getByRole("button", { name: "Anmelden" }).click();
await expect(page.getByRole("heading", { name: "Übersicht" })).toBeVisible();
}
async function keinQuerscrollen(page: Page) {
const breiten = await page.evaluate(() => ({
inhalt: document.documentElement.scrollWidth,
fenster: window.innerWidth,
}));
expect(breiten.inhalt).toBeLessThanOrEqual(breiten.fenster);
}
test("falsches Passwort zeigt eine Meldung mit Symbol und Text", async ({ page }) => {
await page.goto("/anmelden");
// Eigener Name: Fehlversuche zählen je Benutzer, der echte Admin soll nie gesperrt werden.
await page.getByLabel("Benutzername").fill("e2e-unbekannt");
await page.getByLabel("Passwort").fill("falsch-falsch");
await page.getByRole("button", { name: "Anmelden" }).click();
// Wenn die Seite nicht hydriert, passiert hier nichts – das ist die eigentliche Prüfung.
await expect(page.getByText("Benutzername oder Passwort ist falsch.")).toBeVisible();
await expect(page.getByText("✗")).toBeVisible();
});
test("Anmelden, Übersicht, Abmelden", async ({ page }) => {
await anmelden(page);
await keinQuerscrollen(page);
await page.screenshot({ path: `test-results/uebersicht-${test.info().project.name}.png`, fullPage: true });
if (test.info().project.name === "handy") {
await page.getByRole("button", { name: "Navigation öffnen" }).click();
}
await page.getByRole("button", { name: "Abmelden" }).click();
await expect(page).toHaveURL(/\/anmelden/);
});
test("Theme-Wechsel bleibt nach dem Neuladen erhalten", async ({ page }) => {
await anmelden(page);
await expect(page.locator("html")).toHaveAttribute("data-theme", "dunkel");
if (test.info().project.name === "handy") {
await page.getByRole("button", { name: "Navigation öffnen" }).click();
}
await page.getByRole("button", { name: "Helles Theme einschalten" }).click();
await expect(page.locator("html")).toHaveAttribute("data-theme", "hell");
await page.reload();
await expect(page.locator("html")).toHaveAttribute("data-theme", "hell");
await page.screenshot({
path: `test-results/uebersicht-hell-${test.info().project.name}.png`,
fullPage: true,
});
});
test("Anmeldeseite ohne Querscrollen", async ({ page }) => {
await page.goto("/anmelden");
await keinQuerscrollen(page);
});