import { expect, test, type Page } from "@playwright/test"; /** * Vorlagen im gebauten Stand (#019). Testvorlagen heissen zz-e2e-… und werden am Ende des * Ablaufs archiviert, damit die Entwicklungsdatenbank sauber bleibt. */ async function oidcAnmelden(page: Page, rolle: "admin" | "operator" | "reader") { await page.goto("/anmelden"); await page.getByRole("link", { name: /Mit Mock-OIDC anmelden/ }).click(); await page.locator(`button[data-rolle="${rolle}"]`).click(); await page.getByRole("button", { name: "Anmelden", exact: true }).click(); await expect(page.getByRole("heading", { name: "Übersicht" })).toBeVisible(); } test("Admin legt eine Vorlage an, sieht Feldfehler und archiviert sie", async ({ page }) => { const name = `zz-e2e-${Date.now().toString(36)}`; await oidcAnmelden(page, "admin"); await page.goto("/vorlagen"); await expect(page.getByRole("heading", { name: "Deployment-Zugang" })).toBeVisible(); await page.getByRole("link", { name: "Vorlage anlegen" }).click(); await expect(page).toHaveURL(/\/vorlagen\/neu$/); await page.getByLabel("Name").fill(name); await page.getByLabel("Zielbenutzer").fill("zzdeploy"); await page.getByRole("checkbox", { name: /Benutzer anlegen/ }).check(); await page.getByLabel("authorized_keys-Optionen (optional)").fill('from="{{quellIp}}",no-pty'); // Die Vorschau meldet den Fehler schon vor dem Absenden, der Server dann am Feld. await expect(page.getByText("Unbekannter Platzhalter {{quellIp}}.").first()).toBeVisible(); await page.getByRole("button", { name: "Vorlage anlegen" }).click(); await expect(page.locator("#feld-authorizedKeysOptionen-fehler")).toHaveText( "Unbekannter Platzhalter {{quellIp}}.", ); // Eingaben bleiben nach der Feldmeldung stehen. await expect(page.getByLabel("Name")).toHaveValue(name); await page.getByLabel("authorized_keys-Optionen (optional)").fill('from="{{quellHostIp}}",no-pty'); await page.getByLabel("Alias-Muster für ~/.ssh/config (optional)").fill("zz-{{zielHost}}"); await expect(page.getByText('from="10.0.0.5",no-pty')).toBeVisible(); await expect(page.getByText("zz-srv-web01")).toBeVisible(); // sudo „bestimmte Befehle“ blendet das Befehlsfeld ein, „voll“ warnt. await page.getByRole("radio", { name: "voll" }).check(); await expect(page.getByRole("note")).toContainText("root"); await page.getByRole("radio", { name: "bestimmte Befehle" }).check(); await page.getByLabel("Erlaubte Befehle").fill("/usr/bin/systemctl restart nginx"); await expect(page.getByLabel("sudoers-Inhalt", { exact: true })).toContainText( "zzdeploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx", ); await page.getByRole("button", { name: "Vorlage anlegen" }).click(); await expect(page).toHaveURL(/\/vorlagen$/); const karte = page.locator("article", { has: page.getByRole("heading", { name }) }); await expect(karte).toBeVisible(); await expect(karte.getByText('from="{{quellHostIp}}",no-pty')).toBeVisible(); await expect(karte.getByText("wird angelegt")).toBeVisible(); await karte.getByRole("link", { name: `${name} bearbeiten` }).click(); await page.getByRole("button", { name: "Vorlage archivieren" }).click(); await page.getByRole("dialog").getByRole("button", { name: "Archivieren" }).click(); await expect(page).toHaveURL(/\/vorlagen$/); await expect(page.getByRole("heading", { name })).toHaveCount(0); }); test("eingebaute Vorlagen haben keinen Archivieren-Knopf", async ({ page }) => { await oidcAnmelden(page, "admin"); await page.goto("/vorlagen"); await page.getByRole("link", { name: "Deployment-Zugang bearbeiten" }).click(); await expect(page.getByLabel("Name")).toHaveValue("Deployment-Zugang"); await expect(page.getByRole("button", { name: "Vorlage archivieren" })).toHaveCount(0); }); test("Leser sieht Vorlagen, darf aber keine anlegen oder bearbeiten", async ({ page }) => { await oidcAnmelden(page, "reader"); await page.goto("/vorlagen"); await expect(page.getByRole("heading", { name: "Deployment-Zugang" })).toBeVisible(); await expect(page.getByRole("link", { name: "Vorlage anlegen" })).toHaveCount(0); await expect(page.getByRole("link", { name: /bearbeiten/ })).toHaveCount(0); await page.goto("/vorlagen/neu"); await expect(page).toHaveURL(/\/kein-zugriff/); });