import { expect, test } from "@playwright/test"; import { anmelden, archivieren, aufZiel, hostEinrichten, kernAufbauen, PORT, zieleZuruecksetzen, } from "./hilfen"; /** * Widerruf im Browser (#024), gebauter Stand + Worker: Ausgangslage ist der Kern-Anwendungsfall * (Private Key auf A, Public Key auf B). „Widerrufen“ → Dialog → Dry-Run → anwenden → Status * „widerrufen“; danach kommt A nicht mehr nach B. */ test.setTimeout(240_000); test.beforeAll(() => zieleZuruecksetzen()); test("Widerruf mit einem Klick", async ({ page }) => { const kennung = Date.now().toString(36); const hostA = `zz-e2e-a-${kennung}`; const hostB = `zz-e2e-b-${kennung}`; const zweck = `zz-e2e Widerruf ${kennung}`; await anmelden(page); await hostEinrichten(page, hostA, PORT.a); await hostEinrichten(page, hostB, PORT.b); await kernAufbauen(page, zweck, hostA, hostB); await page.reload(); // Dialog: zeigt genau, was passiert. await page.getByRole("button", { name: "Widerrufen" }).click(); const dialog = page.getByRole("dialog", { name: `„${zweck}“ widerrufen?` }); await expect(dialog.getByText(`root@${hostB}`)).toBeVisible(); await expect(dialog.getByText(`root@${hostA}:~/.ssh/`)).toBeVisible(); await expect(dialog.getByText(/config-Eintrag „Host zu-b“/)).toBeVisible(); await page.screenshot({ path: "docs/anleitung/bilder/widerruf-desktop.png" }); await dialog.getByRole("button", { name: "Widerruf vorbereiten" }).click(); // Zwischenzustand: noch nicht widerrufen, nichts mehr zuweisbar. await expect(page.getByRole("heading", { name: "Widerruf läuft" })).toBeVisible(); await expect(page.getByText("Widerruf unvollständig")).toBeVisible(); await expect(page.getByRole("button", { name: "Ausrollen" })).toHaveCount(0); await page.getByRole("button", { name: "Dry-Run starten" }).click(); await expect(page.getByText(`root@${hostB}:/root/.ssh/authorized_keys`)).toBeVisible({ timeout: 30_000 }); await page.screenshot({ path: "docs/anleitung/bilder/widerruf-dry-run-desktop.png", fullPage: true }); await page.getByRole("button", { name: /Änderung anwenden/ }).click(); await expect(page.getByRole("heading", { name: "Widerrufen", exact: true })).toBeVisible({ timeout: 60_000, }); await expect(page.getByText("Widerruf unvollständig")).toHaveCount(0); expect(aufZiel("ziel-a", "ls /root/.ssh")).not.toContain("id_ed25519"); expect(() => aufZiel("ziel-a", "ssh -o BatchMode=yes -o ConnectTimeout=5 zu-b true")).toThrow(); await archivieren(page, hostA); await archivieren(page, hostB); });