Communitygithub.com

bitovi/ai-enablement-prompts

Vergleicht eine Basis-URL mit einer Entwicklungs- oder Storybook-URL, indem Playwright-Screenshots auf mehreren Breakpoints erstellt, ein pixelgenauer Bildvergleich durchgeführt und die Ergebnisse zur Steuerung von CSS- und HTML-Korrekturen gemeldet werden. Verwenden Sie dies beim Nachbau einer vorhandenen Seite oder Komponente, zur Überprüfung der visuellen Genauigkeit oder zur Kontrolle der responsiven Wiedergabetreue.

Was ist ai-enablement-prompts?

Diese Fähigkeit ermöglicht einen pixelgenauen visuellen Vergleich zwischen zwei URLs – einer Basis-URL (z. B. Produktionsseite) und einer aktuellen URL (z. B. lokaler Entwicklungsserver oder Storybook-Story). Der Workflow umfasst das Erstellen von Playwright-Screenshots auf mehreren Breakpoints (mobil, Tablet, Desktop), die Ausführung eines pixelbasierten Bildvergleichs mit `pixelmatch`, und die Ausgabe quantitativer Daten (diffPercent) sowie einer visuellen Differenzkarte. Besonders nützlich ist die Fähigkeit, einzelne Komponenten auf Elementebene zu vergleichen, indem der Viewport auf die Begrenzungsrahmen der Komponente zugeschnitten wird – so werden Störungen durch umliegende Seitenelemente vermieden. Die Ergebnisse – sowohl die JSON-Daten als auch das visuelle Differenzbild – können dann genutzt werden, um CSS- und HTML-Korrekturen zu identifizieren und zu iterieren, bis die gewünschte Übereinstimmung erreicht ist. Unterstützt werden Workflows mit Playwright MCP, das `temp/`-Verzeichnis, ein Skript `scripts/visual-diff.mjs`, und ein temporärer HTTP-Server zur Anzeige der Differenzbilder. Die Fähigkeit ist für Entwicklerteams konzipiert, die Seiten oder Komponenten exakt nachbauen, die visuelle Genauigkeit überprüfen oder die responsive Wiedergabetreue sicherstellen müssen.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bitovi/ai-enablement-prompts/tree/HEAD/plugins/playwright/skills/visual-diff

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Fähigkeit: Visueller Vergleich (Visual Diff)

Vergleichen Sie zwei URLs visuell – eine Basis (z. B. Produktionsseite) und eine aktuelle (z. B. lokaler Entwicklungsserver oder Storybook-Story) – um pixelgenaue Unterschiede zu finden und Korrekturen zu steuern.


Wann verwenden

  • Nachbau einer vorhandenen Seite oder eines Abschnitts in Storybook oder der Astro-Seite
  • Überprüfung der visuellen Genauigkeit einer Komponente im Vergleich zu einem Referenzdesign
  • Kontrolle der responsiven Wiedergabetreue über Breakpoints hinweg nach Stiländerungen
  • Iteratives Anpassen von CSS/HTML, bis eine Komponente ihrer Referenz entspricht

Wann NICHT verwenden

  • Nur Inhaltsänderungen (Textaktualisierungen, Textkorrekturen), bei denen das Layout unverändert bleibt
  • Vergleiche von Designs aus Figma – verwenden Sie stattdessen die Figma MCP-Fähigkeit
  • Leistungs- oder Barrierefreiheits-Audits – verwenden Sie Lighthouse oder das a11y-Addon

Voraussetzungen

Stellen Sie vor dem Start sicher:

  1. Playwright MCP ist in .vscode/mcp.json mit --caps=vision konfiguriert
  2. pixelmatch und pngjs sind installiert: Überprüfen Sie die devDependencies in package.json
  3. Die Basis-URL ist erreichbar (externe Seite oder ein laufender Server)
  4. Die aktuelle URL ist erreichbar (Entwicklungsserver auf :4321, Storybook auf :6006 usw.)
  5. Das temp/-Verzeichnis existiert im Workspace-Root (es ist in gitignore)

Wenn der Entwicklungsserver oder Storybook nicht läuft, starten Sie diese über die VS Code-Aufgaben:

  • Entwicklungsserver: Verwenden Sie die Dev Server-Aufgabe
  • Storybook: Verwenden Sie die Storybook-Aufgabe

Arbeitsablauf

Schritt 1: Eingaben empfangen

Der Agent benötigt:

EingabeErforderlichBeispiel
Basis-URLJahttps://www.bitovi.com/
Aktuelle URLJahttp://localhost:4321/ oder http://localhost:6006/?path=/story/card--default
CSS-SelektorNein#hero-section oder .card-grid (für elementbezogenen Vergleich)
BreakpointsNeinStandard: Mobil (375×667), Tablet (768×1024), Desktop (1280×720)

Schritt 2: Screenshot der Basis erstellen

Komponentenbezogener Vergleich (bevorzugt beim Vergleich einer einzelnen Komponente)

Beim Vergleich einer bestimmten Komponente – insbesondere wenn die Storybook-Story nur diese Komponente rendert, die Basis-Seite jedoch eine gesamte Seite darum herum hat – beschneiden Sie auf den Begrenzungsrahmen der Komponente, damit der Diff nicht durch nicht verwandte Seitenabschnitte (Navigationsleisten, fixierte Overlays, andere Module darüber/darunter) verunreinigt wird.

So beschneiden Sie auf der Basis-Seite:

  1. Navigieren Sie zur Basis-URL
  2. Ändern Sie die Viewport-Größe auf { width: 1280, height: 720 }
  3. Scrollen Sie das Zielelement in den sichtbaren Bereich:
    () => document.querySelector('<selector>').scrollIntoView({ behavior: 'instant', block: 'start' })
    
  4. Messen Sie die gerenderte Höhe der Komponente:
    () => document.querySelector('<selector>').getBoundingClientRect().height
    
  5. Ändern Sie die Viewport-Höhe auf genau diese Höhe (Breite bleibt konstant):
    mcp_playwright_browser_resize → { width: 1280, height: <gemessene Höhe> }
    
  6. Erstellen Sie den Screenshot – er erfasst jetzt nur den Bereich der Komponente.

Warnung zum Hintergrunddurchscheinen: Was hinter der Komponente sichtbar ist, unterscheidet sich zwischen Storybook (leer) und der Basis-Seite (andere Module). Häufige Fälle: klebende/lokale Navigationsleisten, die oben überlappen, Modals/Overlays mit anderem Seiteninhalt dahinter und teilweise transparente Komponenten. Diese residualen Diffs gruppieren sich außerhalb des eigentlichen Inhalts der Komponente und sind nicht umsetzbar – ignorieren Sie sie.

So beschneiden Sie auf der Storybook-Story:

Storybooks iframe.html rendert nur die Komponente ohne umgebendes Chrome – kein Größenanpassung nötig. Navigieren Sie einfach und erstellen Sie den Screenshot:

mcp_playwright_browser_navigate → { url: "http://localhost:6006/iframe.html?id=<story-id>&viewMode=story" }
mcp_playwright_browser_resize → { width: 1280, height: <gleiche Höhe wie beim Basis-Beschnitt> }
mcp_playwright_browser_take_screenshot → { filename: "temp/vdiff-current-desktop.png" }

Vollbild-Viewport-Screenshot (beim Vergleich vollständiger Seiten)

1. mcp_playwright_browser_navigate → { url: "<basis-url>" }
2. mcp_playwright_browser_resize → { width: 1280, height: 720 }
3. mcp_playwright_browser_wait_for → { time: 2 }       # Seite vollständig rendern lassen
4. mcp_playwright_browser_take_screenshot → {
     type: "png",
     filename: "temp/vdiff-baseline-desktop.png"
   }

Für jeden Breakpoint wiederholen:

BreakpointBreiteHöheDateinamen-Suffix
Mobil375667-mobile
Tablet7681024-tablet
Desktop1280720-desktop

Schritt 3: Screenshot der aktuellen Seite erstellen

Wiederholen Sie den exakt gleichen Prozess für die aktuelle URL, mit Dateinamen wie temp/vdiff-current-{breakpoint}.png.

Wichtig: Verwenden Sie auf beiden Seiten die gleichen Viewport-Dimensionen und die gleiche Beschneidungsstrategie (komponentenbezogen oder Vollbild), damit der Vergleich Äpfel mit Äpfeln ist.

Schritt 4: Diff-Skript ausführen

Für jeden Breakpoint führen Sie das visuelle Diff-Skript im Terminal aus:

node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-desktop.png \
  --current temp/vdiff-current-desktop.png \
  --output temp/vdiff-diff-desktop.png

Das Skript gibt JSON auf stdout aus:

{
  "totalPixels": 921600,
  "diffPixels": 4521,
  "diffPercent": 0.49,
  "width": 1280,
  "height": 720,
  "baselineDimensions": { "width": 1280, "height": 720 },
  "currentDimensions": { "width": 1280, "height": 720 },
  "dimensionsMismatch": false,
  "diffImagePath": "/absoluter/pfad/zu/temp/vdiff-diff-desktop.png"
}

Wenn dimensionsMismatch true ist, hatten die Bilder unterschiedliche Größen. Das Skript füllt das kleinere Bild mit transparenten Pixeln auf, bevor es vergleicht. Dies deutet oft auf ein Layout-Problem hin, das untersucht werden sollte.

Schritt 5: Diff-Bild anzeigen

Starten Sie einen temporären HTTP-Server, um das temp/-Verzeichnis auszuliefern, und navigieren Sie dann mit Playwright zum Diff-Bild:

# Server im Hintergrund starten (einmal pro Sitzung ausführen)
npx -y http-server temp/ -p 8787 --cors -c-1 &

Navigieren Sie dann mit Playwright zum Diff-Bild:

mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # löst vision aus – der Agent kann jetzt das Diff sehen

Das --caps=vision-Flag bei Playwright MCP bedeutet, dass der Agent das Bild direkt in der Screenshot-Ausgabe sehen kann.

Hinweis: file://-URLs werden von Playwright MCP blockiert, daher ist der HTTP-Server erforderlich. Starten Sie ihn einmal und verwenden Sie ihn für alle Diff-Bilder in der Sitzung wieder.

Diff-Bild lesen:

  • Rote Pixel = Unterschiede zwischen Basis und aktueller Seite
  • Gelbe Pixel = Anti-Aliasing-Unterschiede (normalerweise ignorierbar)
  • Abgedunkeltes Original = Bereiche, die übereinstimmen (bei 30% Deckkraft für Kontext)
  • Große rote Cluster = strukturelle Probleme (fehlende Elemente, Layout-Verschiebungen, falsche Größen)
  • Verstreute rote Punkte = Subpixel-Rendering, Schriftglättung oder Anti-Aliasing (normalerweise akzeptabel)
  • Rote Bänder an den Rändern = Maßunterschiede oder Unterschiede bei Padding/Margin

Schritt 6: Interpretieren und handeln

Kombinieren Sie die quantitativen JSON-Daten mit der visuellen Diff-Inspektion:

diffPercentInterpretationAktion
< 1%Visuell identischNur minimale Subpixel-Unterschiede. Keine Aktion erforderlich.
1–5%Gute ÜbereinstimmungDiff-Bild auf Abstands-, Schriftstärke- oder Randunterschiede prüfen. Kleine CSS-Anpassungen wahrscheinlich nötig.
5–15%Deutliche UnterschiedeLayout-Verschiebungen, Farbunterschiede oder fehlende Elemente. Überprüfen Sie die roten Cluster im Diff, um zu identifizieren, welche Abschnitte Arbeit benötigen.
> 15%Erhebliche AbweichungGroße strukturelle oder stilistische Unterschiede. Konzentrieren Sie sich zuerst auf die größten roten Regionen – diese zeigen die größten Layout-Diskrepanzen.

Beim Interpretieren des Diff-Bildes beachten:

  • Wo auf der Seite befinden sich die roten Cluster? (oben, Mitte, unten, links, rechts)
  • Sind sie mit bestimmten Elementen verbunden? (Navigation, Hero, Karten, Footer)
  • Deuten die Cluster auf Abstandsprobleme, Farbunterschiede oder fehlende Inhalte hin?

Schritt 7: Korrigieren und erneut vergleichen

  1. Nehmen Sie CSS/HTML-Korrekturen basierend auf der Diff-Analyse vor
  2. Wiederholen Sie die Schritte 3–6 (nur die aktuelle URL erneut screenshoten)
  3. Fahren Sie fort, bis diffPercent ein akzeptables Niveau erreicht

Typische Zielwerte:

  • Exakte Nachbildung: < 2%
  • Angemessene Übereinstimmung: < 5%
  • Strukturelle Übereinstimmung (unterschiedlicher Inhalt): < 15%

Vollbild-Screenshots

Standardmäßig erfassen Screenshots nur den sichtbaren Viewport. Für lange Seiten verwenden Sie die fullPage-Option:

mcp_playwright_browser_take_screenshot → {
  type: "png",
  fullPage: true,
  filename: "temp/vdiff-baseline-desktop-full.png"
}

Warnung: Vollbild-Screenshots erzeugen große Bilder und langsamere Diffs. Nur verwenden, wenn Sie gesamte Seitenlayouts vergleichen.


Storybook-spezifische Tipps

Beim Screenshot von Storybook-Stories:

  1. Verwenden Sie die iframe-URL für sauberere Screenshots (kein Storybook-Chrome):

    http://localhost:6006/iframe.html?id=components-card--default&viewMode=story
    
  2. Auf Rendern warten – Storybook-Stories benötigen möglicherweise einen Moment zur Hydratation:

    mcp_playwright_browser_wait_for → { time: 3 }
    
  3. Element-Screenshots eignen sich gut, um den Story-Inhalt von eventuellem Storybook-Padding zu isolieren.


Schwellenwertanpassung

Das --threshold-Flag (0 bis 1) steuert die Empfindlichkeit von pixelmatch:

WertEmpfindlichkeitAnwendungsfall
0.05Sehr strengExakter Pixelabgleich, erfasst alles
0.1StandardGute Balance, ignoriert die meisten Anti-Aliasing-Artefakte
0.2GroßzügigToleriert Unterschiede im Schrift-Rendering zwischen Systemen
0.3Sehr großzügigErfasst nur größere Farb-/Layout-Unterschiede
node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-desktop.png \
  --current temp/vdiff-current-desktop.png \
  --output temp/vdiff-diff-desktop.png \
  --threshold 0.2

Beispiel: Vergleich eines Hero-Abschnitts

# 1. Screenshot der Basis (Produktionsseite Hero)
mcp_playwright_browser_navigate → { url: "https://www.bitovi.com/" }
mcp_playwright_browser_resize → { width: 1280, height: 720 }
mcp_playwright_browser_wait_for → { time: 2 }
mcp_playwright_browser_snapshot → {}
# Finden Sie die Referenz für den Hero-Abschnitt, z.B. ref="hero-[1]"
mcp_playwright_browser_take_screenshot → {
  type: "png",
  element: "hero section",
  ref: "hero-[1]",
  filename: "temp/vdiff-baseline-hero-desktop.png"
}

# 2. Screenshot der aktuellen Seite (Storybook-Story)
mcp_playwright_browser_navigate → { url: "http://localhost:6006/iframe.html?id=components-hero--default" }
mcp_playwright_browser_resize → { width: 1280, height: 720 }
mcp_playwright_browser_wait_for → { time: 3 }
mcp_playwright_browser_take_screenshot → {
  type: "png",
  filename: "temp/vdiff-current-hero-desktop.png"
}

# 3. Diff ausführen (im Terminal)
node scripts/visual-diff.mjs \
  --baseline temp/vdiff-baseline-hero-desktop.png \
  --current temp/vdiff-current-hero-desktop.png \
  --output temp/vdiff-diff-hero-desktop.png

# 4. Temporären Server starten (einmal pro Sitzung, im Hintergrund-Terminal)
npx -y http-server temp/ -p 8787 --cors -c-1 &

# 5. Diff-Bild über Playwright anzeigen
mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-hero-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # löst vision aus

# 6. Interpretieren: JSON-Ausgabe lesen + Diff-Bild visuell prüfen
# 7. Stile korrigieren, aktuelle Seite erneut screenshoten, erneut diffen

Aufräumen

Alle Ausgabedateien werden im temp/-Verzeichnis abgelegt, das in gitignore steht. So räumen Sie nach einer Sitzung auf:

rm -f temp/vdiff-*.png

Verwandte Skills