docs(readme): Banner, Screenshots, Installation und erste Schritte
Screenshots per scripts/screenshots.ts aus dem gebauten Stand. Dabei gefunden und gefüllt: die Übersicht zeigte nur einen Platzhalter statt der letzten Deployments. Closes #018 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Screenshots für das README aus dem gebauten Stand (`scripts/neu-starten.sh`, Port 3310), dunkles
|
||||
* Theme, 1440 px und 390 px. Ergebnis: docs/bilder/*.png
|
||||
*
|
||||
* pnpm exec tsx scripts/screenshots.ts [auftrag-kurzid]
|
||||
*/
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { chromium, type Page } from "@playwright/test";
|
||||
|
||||
const BASIS = process.env["SCREENSHOT_URL"] ?? "http://127.0.0.1:3310";
|
||||
const BENUTZER = process.env["E2E_BENUTZER"] ?? "admin";
|
||||
const PASSWORT = process.env["E2E_PASSWORT"] ?? "proxdeploy-dev-admin";
|
||||
const ZIEL = "docs/bilder";
|
||||
|
||||
async function anmelden(seite: Page) {
|
||||
await seite.goto(`${BASIS}/anmelden`);
|
||||
await seite.getByLabel("Benutzername").fill(BENUTZER);
|
||||
await seite.getByLabel("Passwort").fill(PASSWORT);
|
||||
await seite.getByRole("button", { name: "Anmelden" }).click();
|
||||
await seite.waitForURL((url) => !url.pathname.startsWith("/anmelden"));
|
||||
}
|
||||
|
||||
async function bild(seite: Page, name: string, ganz = false) {
|
||||
await seite.waitForLoadState("networkidle");
|
||||
// Blinkender Cursor und Spinner sollen nicht zufällig halb im Bild stehen.
|
||||
await seite.addStyleTag({ content: "*{animation:none!important;transition:none!important}" });
|
||||
await seite.screenshot({ path: `${ZIEL}/${name}.png`, fullPage: ganz });
|
||||
console.log(`${ZIEL}/${name}.png`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const auftrag = process.argv[2];
|
||||
if (!auftrag) throw new Error("Kurz-ID eines erfolgreichen Auftrags angeben (für die Live-Ansicht).");
|
||||
mkdirSync(ZIEL, { recursive: true });
|
||||
const browser = await chromium.launch();
|
||||
try {
|
||||
const kontext = await browser.newContext({
|
||||
viewport: { width: 1440, height: 900 },
|
||||
deviceScaleFactor: 1,
|
||||
});
|
||||
await kontext.addCookies([{ name: "pd_theme", value: "dunkel", url: BASIS }]);
|
||||
const seite = await kontext.newPage();
|
||||
await anmelden(seite);
|
||||
|
||||
await seite.goto(`${BASIS}/`);
|
||||
await bild(seite, "uebersicht");
|
||||
|
||||
await seite.goto(`${BASIS}/auftraege/${auftrag}`);
|
||||
await bild(seite, "live-ansicht");
|
||||
|
||||
await seite.goto(`${BASIS}/auftraege`);
|
||||
await bild(seite, "verlauf");
|
||||
|
||||
await seite.goto(`${BASIS}/server/demo`);
|
||||
await bild(seite, "server", true);
|
||||
|
||||
await seite.goto(`${BASIS}/katalog`);
|
||||
await bild(seite, "katalog");
|
||||
|
||||
// Assistent bis zur Zusammenfassung – mit echtem Dry-Run gegen den Server.
|
||||
await seite.goto(`${BASIS}/ausrollen`);
|
||||
await seite.waitForLoadState("networkidle");
|
||||
const weiter = async (bis: number) => {
|
||||
await seite.getByRole("button", { name: "Weiter" }).click();
|
||||
await seite.getByText(`Schritt ${bis} von 9`).waitFor();
|
||||
};
|
||||
for (let s = 2; s <= 4; s++) await weiter(s);
|
||||
await seite.getByLabel("Name (Hostname)").fill("web01");
|
||||
for (let s = 5; s <= 7; s++) await weiter(s);
|
||||
// Ohne hinterlegten Schlüssel einen angeben (öffentlicher Beispielschlüssel).
|
||||
const feld = seite.locator("textarea#schluessel");
|
||||
if ((await feld.inputValue()) === "")
|
||||
await feld.fill(
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFTdkCuqQ6mF7I8QzmkNaQpKj7S/I2+yuxWeYasJjLd florian@laptop",
|
||||
);
|
||||
for (let s = 8; s <= 9; s++) await weiter(s);
|
||||
await seite.getByText("Geplante Proxmox-Aufrufe").waitFor({ timeout: 60_000 });
|
||||
await bild(seite, "assistent-zusammenfassung");
|
||||
|
||||
const handy = await browser.newContext({ viewport: { width: 390, height: 844 }, deviceScaleFactor: 2 });
|
||||
await handy.addCookies([{ name: "pd_theme", value: "dunkel", url: BASIS }]);
|
||||
const klein = await handy.newPage();
|
||||
await anmelden(klein);
|
||||
await klein.goto(`${BASIS}/auftraege/${auftrag}`);
|
||||
await bild(klein, "handy-live-ansicht");
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
}
|
||||
|
||||
await main();
|
||||
Reference in New Issue
Block a user