#038: Die E2E-Ablaeufe laufen ab jetzt vor jedem Merge nach main, nicht vor jedem Commit. Gemessen: Bau 14 s, Start 7 s, Ablaeufe 256 s — zu den vier Minuten des bestehenden Tores. Neun Minuten vor jedem Commit ist ein Tor, das umgangen wird. Vor jedem Merge waeren es in Phase 2 acht Laeufe gewesen, und jeder der vier Befunde aus #027 waere am Tag seiner Entstehung aufgefallen. Geprueft wurde jeder der 16 Ablaeufe gegen die Frage, ob es ein Vitest-Gegenstueck gibt. Neun Zusagen haengen ausschliesslich dort, und keine laesst sich holen: alle brauchen einen echten Browser. Die Liste steht in CLAUDE.md. Der eigentliche Fund dabei war keine Testluecke, sondern eine Konvention ohne Pruefer: "jede Seite prueft selbst" steht seit #007 in CLAUDE.md, und geprueft hat es bis hierher nur ein Mensch, der nachsieht. Der Review von Phase 2 hat alle 27 Seiten durchgesehen — ein Ergebnis, das fuer genau einen Tag gilt. tests/zugang.test.ts liest sie jetzt, samt jedem Route Handler; die Ausnahmen (Auth, Healthcheck) stehen namentlich mit Begruendung, und ein Test prueft auch die Gegenrichtung. #037: Das Lesemodell der Anhaenge liegt in queries/ und engt selbst ein — vorher hing das daran, dass beide Aufrufer den Lauf vorher pruefen. /meine-geraete wird bei 390 px gemessen, mit einem echten MITARBEITER-Konto aus dem E2E-Vorlauf, dazu ein Test, dass dort kein Link in die Verwaltung angeboten wird. Dabei selbst einen Fehler gemacht, der die neue Regel begruendet: fuer das zweite Konto brauchte `anmelden` eine Variante, die nicht auf / wartet, und ich habe das Warten fuer alle gelockert. Das machte zwei unverwandte Ablaeufe unzuverlaessig — sichtbar nur im vollen Durchgang, einzeln waren beide gruen. Ein gemeinsamer Helfer in einer Testsuite ist geteilter Zustand. Ohne vollen Durchgang haette ich zwei rote Ablaeufe gemergt. 1457 Vitest-Tests (vorher 1454), 115 E2E-Ablaeufe (vorher 113). Offen bleibt nur noch #024, und das verlangt einen echten Proxmox-Host. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
80d97467da
commit
75c335df23
+72
-5
@@ -1,7 +1,15 @@
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
import "dotenv/config";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { SEED_TAG, SEED_VORLAGE, anmelden, betriebsmodus } from "./helfer";
|
||||
import {
|
||||
E2E_MITARBEITER_MAIL,
|
||||
E2E_MITARBEITER_PASSWORT,
|
||||
SEED_TAG,
|
||||
SEED_VORLAGE,
|
||||
anmelden,
|
||||
anmeldenMit,
|
||||
betriebsmodus,
|
||||
} from "./helfer";
|
||||
|
||||
/**
|
||||
* Am Handy scrollt nichts nach rechts (#018).
|
||||
@@ -191,10 +199,10 @@ const SEITEN: readonly Hauptseite[] = [
|
||||
* Zustellungs-Protokoll sind Tabellen, und Tabellen sind die Stellen, an denen
|
||||
* horizontales Scrollen entsteht.
|
||||
*
|
||||
* Nicht dabei: `/meine-geraete` (#035) — es verlangt das Recht
|
||||
* `selbstauskunft`, und das hat nur `MITARBEITER`. Dieser Ablauf meldet sich
|
||||
* als Admin an, der dort „kein Zugriff“ sähe; gemessen würde die
|
||||
* Verweigerungsseite. Dafür braucht es ein eigenes Konto, siehe #037.
|
||||
* `/meine-geraete` steht **nicht** in dieser Liste, sondern in einem eigenen
|
||||
* Block darunter: die Seite verlangt `selbstauskunft`, und das hat nur
|
||||
* `MITARBEITER`. Mit der Anmeldung dieses Ablaufs (Admin) würde die
|
||||
* Verweigerungsseite gemessen — und die scrollt garantiert nicht (#037).
|
||||
*/
|
||||
{ name: "Vorlagen: Bausteine", pfad: () => "/vorlagen/bausteine" },
|
||||
{ name: "Admin: Schnellstart", pfad: () => "/admin/schnellstart" },
|
||||
@@ -283,6 +291,65 @@ test.describe("Am Handy bei 390 px", () => {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* `/meine-geraete` braucht eine andere Anmeldung (#037).
|
||||
*
|
||||
* Eigener Block statt eines Sonderfalls in der Schleife oben: die Seitenliste
|
||||
* dort gilt für **eine** Rolle, und ein `if` darin hätte beim nächsten Eintrag
|
||||
* geerbt werden müssen. Die Messung selbst ist dieselbe Funktion.
|
||||
*/
|
||||
test.describe("Am Handy bei 390 px: die Selbstauskunft", () => {
|
||||
const PFAD = "/meine-geraete";
|
||||
|
||||
test(`scrollt „Meine Geräte“ nicht horizontal`, async ({ page }) => {
|
||||
test.slow();
|
||||
await anmeldenMit(page, E2E_MITARBEITER_MAIL, E2E_MITARBEITER_PASSWORT);
|
||||
|
||||
await page.goto(PFAD);
|
||||
/*
|
||||
* Dieselbe Vorsicht wie oben, hier noch wichtiger: hätte das Konto die Rolle
|
||||
* verloren, landete es auf `/kein-zugriff` — und der Ablauf hätte grün
|
||||
* gemeldet, ohne die Seite gesehen zu haben.
|
||||
*/
|
||||
expect(new URL(page.url()).pathname, `${PFAD} hat weitergeleitet.`).toBe(PFAD);
|
||||
await page.waitForLoadState("load");
|
||||
|
||||
// Und es ist wirklich die Selbstauskunft, nicht eine leere Hülle: der Name
|
||||
// der verknüpften Person steht darauf.
|
||||
const person = process.env["E2E_MITARBEITER_PERSON"];
|
||||
if (person) {
|
||||
await expect(page.getByText(person, { exact: false }).first()).toBeVisible();
|
||||
}
|
||||
|
||||
const masse = await messen(page);
|
||||
expect(
|
||||
masse.scroll,
|
||||
`„Meine Geräte“ (${PFAD}) scrollt horizontal: erwartet <= ${masse.sichtbar}, ` +
|
||||
`war ${masse.scroll} — ${masse.scroll - masse.sichtbar} px zu breit.` +
|
||||
(masse.uebeltaeter.length > 0 ? `\n Zu weit rechts: ${masse.uebeltaeter.join("\n ")}` : ""),
|
||||
).toBeLessThanOrEqual(masse.sichtbar);
|
||||
});
|
||||
|
||||
test("sieht dort keinen Weg in die Verwaltung", async ({ page }) => {
|
||||
/*
|
||||
* Die Gegenprobe zur Rolle, und sie gehört hierher: die Seitenleiste nennt
|
||||
* seit #035 an jedem Eintrag ihr Recht, damit einem `MITARBEITER` keine
|
||||
* sechs Links angeboten werden, die alle auf `/kein-zugriff` führen. Das
|
||||
* ist in Vitest als Rollenmatrix geprüft — dass es im **gerenderten** DOM
|
||||
* ankommt, nur hier.
|
||||
*/
|
||||
await anmeldenMit(page, E2E_MITARBEITER_MAIL, E2E_MITARBEITER_PASSWORT);
|
||||
await page.goto("/meine-geraete");
|
||||
|
||||
for (const ziel of ["/admin", "/vorlagen", "/laeufe", "/mitarbeiter", "/geraete", "/archiv"]) {
|
||||
await expect(
|
||||
page.locator(`a[href^="${ziel}"]`),
|
||||
`Ein MITARBEITER bekommt einen Link auf ${ziel} angeboten.`,
|
||||
).toHaveCount(0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
if (laufId) {
|
||||
await prisma.kommentar.deleteMany({ where: { laufId } });
|
||||
|
||||
Reference in New Issue
Block a user