Zum Inhalt

Automatische Screenshots

Die Dokumentation unterstützt automatisch generierte Screenshots, die über eine CI-Pipeline bei jedem Pull Request aktualisiert werden. Screenshots werden per Selenium-Browser (Chrome) direkt aus der laufenden Anwendung aufgenommen.

Screenshot-Direktive

Um einen Screenshot in einer Markdown-Datei anzufordern, wird ein HTML-Kommentar mit den Screenshot-Parametern eingefügt:

<!-- screenshot: admin-inventarliste route=/index-test.php?r=inventory/admin selector=#inventory-grid role=admin -->
![Inventarliste](../../assets/screens/admin-inventarliste.png)

Parameter

Parameter Pflicht Standard Beschreibung
route Ja* URL-Pfad relativ zur BASE_URL
selector Nein body CSS-Selektor, auf den gewartet wird
role Nein admin Login-Rolle: admin oder user
fullpage Nein false Komplette Seite oder nur Viewport
width Nein 1440 Viewport-Breite in Pixel
height Nein 900 Viewport-Höhe in Pixel
delay Nein 500 Wartezeit in ms nach Selektor-Fund

*route kann in der Manifest-Datei definiert werden.

ID-Konventionen

  • Nur Buchstaben, Ziffern, Bindestriche und Unterstriche: a-z, A-Z, 0-9, -, _
  • Empfohlenes Schema: <bereich>-<seite>[-<detail>]
  • Beispiele: admin-inventarliste, user-dashboard, admin-einstellungen-regeln

Manifest-Datei

Für wiederverwendbare oder zentral verwaltete Screenshots steht die Datei docs/screenshots.manifest.yml zur Verfügung:

screenshots:
  admin-inventarliste:
    route: "/index-test.php?r=inventory/admin"
    selector: "#inventory-grid"
    role: admin

Werte im Manifest dienen als Standardwerte. Inline-Direktiven in Markdown überschreiben die Manifest-Einträge.

Screenshots lokal generieren

Voraussetzungen

  • Docker (für Selenium Chrome)
  • PHP 7.4+ mit Composer
  • Zugang zur laufenden Anwendung (lokal oder Staging)

Schritt 1: Selenium starten

docker run -d -p 4444:4444 --shm-size=2g selenium/standalone-chrome:latest

Schritt 2: Umgebungsvariablen setzen

export BEHAT_BASE_URL=http://localhost:8080
export SELENIUM_URL=http://localhost:4444/wd/hub
export BEHAT_USER=admin@calhelp.de
export BEHAT_PASS=admin
# Optional für Rolle "user":
# export BEHAT_FRONTEND_USER=user@example.com
# export BEHAT_FRONTEND_PASS=userpass

Zugangsdaten

Zugangsdaten niemals in die Versionskontrolle einchecken. Verwenden Sie ausschließlich Umgebungsvariablen.

Schritt 3: Screenshots generieren

cd httpdocs/protected
vendor/bin/behat --suite=docs --no-interaction

Ausgabeverzeichnis

Generierte Screenshots werden unter docs/assets/screens/ abgelegt:

docs/assets/screens/
├── admin-inventarliste.png        # Aktueller Screenshot
├── admin-inventarliste.prev.png   # Backup des vorherigen Screenshots
└── .gitkeep

Beim Überschreiben eines bestehenden Screenshots wird der alte automatisch als <id>.prev.png gesichert.

CI-Pipeline

Die GitHub-Actions-Workflow-Datei .github/workflows/docs-screenshots.yml wird automatisch bei Pull Requests ausgelöst, wenn Markdown-Dateien unter docs/ oder die Manifest-Datei geändert werden.

Ablauf

  1. PR mit Markdown-Änderungen wird erstellt
  2. Workflow startet Selenium Chrome als Service-Container
  3. Behat-Suite docs wird ausgeführt
  4. Generierte/aktualisierte Screenshots werden in den PR-Branch committet
  5. Der Commit enthält [skip ci], um Endlosschleifen zu verhindern

Endlosschleifen-Schutz

Drei Schutzmechanismen:

  1. github.actor != 'github-actions[bot]' — Job wird übersprungen bei Bot-Commits
  2. [skip ci] im Commit-Text — GitHub Actions startet keinen neuen Lauf
  3. paths:-Filter — nur .md-Dateien und Manifest lösen den Workflow aus

Benötigte GitHub Secrets

Secret Beschreibung Status
BEHAT_USER Admin-Benutzername Vorhanden
BEHAT_PASS Admin-Passwort Vorhanden
DOCS_SCREENSHOT_BASE_URL URL der Staging-Instanz Neu anlegen
BEHAT_FRONTEND_USER Frontend-Benutzername Neu anlegen
BEHAT_FRONTEND_PASS Frontend-Passwort Neu anlegen

Sicherheit

Der Screenshot-Runner enthält mehrere Sicherheitsmechanismen:

  • Routen-Blacklist: URLs mit /logout, /delete, /remove, /destroy usw. werden blockiert
  • Nur relative URLs: Externe URLs werden abgelehnt
  • Destruktive Elemente deaktiviert: Nach dem Laden wird per JavaScript jeder Link/Button mit gefährlichem Text (Delete, Löschen, Abmelden usw.) deaktiviert
  • Keine Klicks auf unbekannte Links: Navigation erfolgt ausschließlich über direkte URL-Aufrufe