Der Test liest Version, Cluster, Nodes, Storages, Bridges, VNets und die effektiven Rechte des Tokens und leitet daraus ab, welcher Vorgang per API, per SSH oder gar nicht geht – je PVE-Version: Template-Bau per API erst ab 8.4 mit import-Storage, Snippets und LXC-Exec nur per SSH. Fehlende Rechte erscheinen einzeln mit Pfad und Zweck; die Rollenliste in docs/proxmox-rechte.md prüft ein Test gegen den Code. SSH-Host-Keys werden wie Zertifikate erst nach Bestätigung genutzt, und bestätigt werden kann nur ein Schlüssel, den der letzte Test gesehen hat. Statussymbole in der GUI sind jetzt gezeichnet: ◐ und ○ fehlen im Web-Subset von JetBrains Mono. Refs #003 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.3 KiB
TypeScript
55 lines
2.3 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
||
import { anmelden as anmeldenZu, keinQuerscrollen } from "./helfer";
|
||
|
||
async function anmelden(page: import("@playwright/test").Page) {
|
||
await anmeldenZu(page);
|
||
await expect(page.getByRole("heading", { name: "Übersicht" })).toBeVisible();
|
||
}
|
||
|
||
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();
|
||
// Symbol + Text: das gezeichnete ✗ steht im selben Element wie die Meldung.
|
||
await expect(
|
||
page.getByText("Benutzername oder Passwort ist falsch.").locator("xpath=..").locator("svg"),
|
||
).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);
|
||
});
|