Der Service war nur ueber die reinen Pruefregeln abgedeckt. Die DB-Tests halten fest, was die Oberflaeche voraussetzt: doppelte Namen melden sich am Feld name, Aenderungen protokollieren genau die geaenderten Felder, eingebaute Vorlagen lassen sich nicht archivieren. Der E2E-Ablauf prueft Feldfehler, Vorschau und Rechte im gebauten Stand; die Screenshots dienen der Layout-Abnahme bei 390 px. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
4.2 KiB
TypeScript
83 lines
4.2 KiB
TypeScript
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/);
|
|
});
|