Communitygithub.com

bitovi/ai-enablement-prompts

Comparez une URL de référence à une URL de développement ou Storybook en prenant des captures d'écran Playwright à plusieurs points de rupture, en effectuant une différence d'image au niveau pixel et en rapportant les résultats pour guider les corrections de style et HTML. À utiliser lors de la réplication d'une page ou d'un composant existant, de la vérification de la précision visuelle ou du contrôle de la fidélité responsive.

Qu'est-ce que ai-enablement-prompts ?

Cette compétence permet de comparer visuellement deux URLs — une baseline (ex. site de production) et une actuelle (ex. serveur de développement local ou story Storybook) — en utilisant Playwright pour prendre des captures d'écran à plusieurs points de rupture (mobile, tablette, desktop) et en effectuant une différence d'image au niveau pixel avec pixelmatch. Idéale pour les développeurs qui répliquent des pages existantes en Storybook ou sur un site Astro, elle détecte les écarts de mise en page, de style et de rendu HTML. La compétence guide l'utilisateur à travers un workflow en sept étapes : recevoir les entrées, capturer les écrans de la baseline et de l'actuelle, exécuter le script de différence, visualiser l'image de différence, interpréter les résultats (pourcentage de pixels différents et inspection visuelle) et itérer sur les corrections CSS/HTML. Elle prend en charge les captures d'écran plein écran ou centrées sur un composant, avec un recadrage automatique pour éviter la pollution par les éléments de page environnants. Un seuil de sensibilité réglable et un tableau d'interprétation des pourcentages de différence aident à décider quand les modifications sont suffisantes. Fonctionne avec les MCP Playwright, nécessite pixelmatch et pngjs dans les dépendances, et sauvegarde les images dans un dossier temporaire gitignoré.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Compétence : Différence Visuelle

Comparez visuellement deux URLs — une baseline (ex. site de production) et une actuelle (ex. serveur de développement local ou story Storybook) — pour trouver des différences au niveau pixel et guider les corrections.


Quand l'utiliser

  • Répliquer une page ou une section existante dans Storybook ou le site Astro
  • Vérifier la précision visuelle d'un composant par rapport à un design de référence
  • Contrôler la fidélité responsive sur différents points de rupture après des modifications de style
  • Itérer sur le CSS/HTML jusqu'à ce qu'un composant corresponde à sa référence

Quand NE PAS l'utiliser

  • Modifications de contenu uniquement (mises à jour de texte, corrections éditoriales) lorsque la mise en page est inchangée
  • Comparer des designs provenant de Figma — utilisez plutôt la compétence Figma MCP
  • Audits de performance ou d'accessibilité — utilisez Lighthouse ou l'addon a11y

Prérequis

Avant de commencer, vérifiez :

  1. Playwright MCP est configuré dans .vscode/mcp.json avec --caps=vision
  2. pixelmatch et pngjs sont installés : vérifiez les devDependencies dans package.json
  3. L'URL de la baseline est accessible (site externe ou serveur en cours d'exécution)
  4. L'URL actuelle est accessible (serveur de développement sur :4321, Storybook sur :6006, etc.)
  5. Le répertoire temp/ existe à la racine du workspace (il est ignoré par git)

Si le serveur de développement ou Storybook n'est pas en cours d'exécution, démarrez-les via les tâches VS Code :

  • Serveur de développement : utilisez la tâche Serveur de développement
  • Storybook : utilisez la tâche Storybook

Workflow

Étape 1 : Recevoir les entrées

L'agent a besoin de :

EntréeObligatoireExemple
URL de la baselineOuihttps://www.bitovi.com/
URL actuelleOuihttp://localhost:4321/ ou http://localhost:6006/?path=/story/card--default
Sélecteur CSSNon#hero-section ou .card-grid (pour une comparaison centrée sur un élément)
Points de ruptureNonPar défaut : mobile (375×667), tablette (768×1024), desktop (1280×720)

Étape 2 : Capturer la baseline

Comparaison centrée sur un composant (recommandée pour comparer un seul composant)

Lorsque vous comparez un composant spécifique — en particulier lorsque la story Storybook ne rend que ce composant alors que la baseline affiche une page entière autour — recadrez dans la boîte englobante du composant afin que la différence ne soit pas polluée par des sections de page non liées (barres de navigation, superpositions persistantes, autres modules au-dessus/en dessous).

Comment recadrer sur la baseline :

  1. Naviguez vers l'URL de la baseline
  2. Redimensionnez la fenêtre à { width: 1280, height: 720 }
  3. Faites défiler jusqu'au composant cible :
    () => document.querySelector('<selector>').scrollIntoView({ behavior: 'instant', block: 'start' })
    
  4. Mesurez la hauteur rendue du composant :
    () => document.querySelector('<selector>').getBoundingClientRect().height
    
  5. Redimensionnez la hauteur de la fenêtre à cette valeur exacte (gardez la largeur constante) :
    mcp_playwright_browser_resize → { width: 1280, height: <hauteur mesurée> }
    
  6. Prenez la capture d'écran — elle ne capture désormais que la zone du composant.

Avertissement sur les fuites d'arrière-plan : Ce qui est visible derrière le composant différera entre Storybook (vide) et la baseline (autres modules). Cas courants : barres de navigation locales/globales chevauchant le haut, modales/superpositions avec d'autres contenus visibles derrière, et composants partiellement transparents. Ces différences résiduelles se regroupent en dehors du contenu propre du composant et ne sont pas exploitables — ignorez-les.

Comment recadrer sur la story Storybook :

iframe.html de Storybook ne rend que le composant sans chrome environnant — pas de redimensionnement nécessaire. Naviguez et capturez :

mcp_playwright_browser_navigate → { url: "http://localhost:6006/iframe.html?id=<story-id>&viewMode=story" }
mcp_playwright_browser_resize → { width: 1280, height: <même hauteur que le recadrage baseline> }
mcp_playwright_browser_take_screenshot → { filename: "temp/vdiff-current-desktop.png" }

Capture plein écran fenêtré (pour comparer des pages entières)

1. mcp_playwright_browser_navigate → { url: "<url-baseline>" }
2. mcp_playwright_browser_resize → { width: 1280, height: 720 }
3. mcp_playwright_browser_wait_for → { time: 2 }       # laisser la page s'afficher complètement
4. mcp_playwright_browser_take_screenshot → {
     type: "png",
     filename: "temp/vdiff-baseline-desktop.png"
   }

Répéter pour chaque point de rupture :

Point de ruptureLargeurHauteurSuffixe du fichier
Mobile375667-mobile
Tablette7681024-tablet
Desktop1280720-desktop

Étape 3 : Capturer l'actuelle

Répétez exactement le même processus pour l'URL actuelle, en utilisant les noms de fichiers temp/vdiff-current-{breakpoint}.png.

Important : Utilisez les mêmes dimensions de fenêtre et la même stratégie de recadrage (centrée sur le composant ou plein écran) des deux côtés pour que la comparaison soit pertinente.

Étape 4 : Exécuter le script de différence

Pour chaque point de rupture, exécutez le script de différence visuelle dans le terminal :

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

Le script renvoie du JSON sur la sortie standard :

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

Si dimensionsMismatch est vrai, les images avaient des tailles différentes. Le script complète l'image la plus petite avec des pixels transparents avant de comparer. Cela indique souvent un problème de mise en page à investiguer.

Étape 5 : Visualiser l'image de différence

Démarrez un serveur HTTP temporaire pour servir le répertoire temp/, puis naviguez avec Playwright vers l'image de différence :

# Démarrer le serveur en arrière-plan (une fois par session)
npx -y http-server temp/ -p 8787 --cors -c-1 &

Puis naviguez avec Playwright vers l'image de différence :

mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # déclenche la vision — l'agent peut maintenant voir la différence

Le drapeau --caps=vision sur Playwright MCP permet à l'agent de voir l'image directement dans le résultat de la capture d'écran.

Remarque : Les URLs file:// sont bloquées par Playwright MCP, donc le serveur HTTP est nécessaire. Démarrez-le une fois et réutilisez-le pour toutes les images de différence de la session.

Lecture de l'image de différence :

  • Pixels rouges = différences entre la baseline et l'actuelle
  • Pixels jaunes = différences d'anti-aliasing (généralement ignorables)
  • Original atténué = zones qui correspondent (affichées à 30 % d'opacité pour le contexte)
  • Grosses grappes rouges = problèmes structurels (éléments manquants, décalages de mise en page, mauvais dimensionnement)
  • Points rouges éparpillés = rendu sub-pixel, lissage de police ou anti-aliasing (généralement acceptable)
  • Bandes rouges sur les bords = décalage de dimensions ou différences de rembourrage/marge

Étape 6 : Interpréter et agir

Combinez les données JSON quantitatives avec l'inspection visuelle de la différence :

diffPercentInterprétationAction
< 1 %Visuellement identiqueDifférences sub-pixel mineures uniquement. Aucune action nécessaire.
1–5 %Correspondance procheInspectez l'image de différence pour les écarts d'espacement, de graisse de police ou de bordure. De petites retouches CSS sont probablement nécessaires.
5–15 %Différences notablesDécalages de mise en page, écarts de couleur ou éléments manquants. Examinez les grappes rouges dans la différence pour identifier les sections à travailler.
> 15 %Écart significatifDifférences structurelles ou stylistiques majeures. Concentrez-vous d'abord sur les plus grandes régions rouges — elles indiquent les plus gros écarts de mise en page.

Lors de l'interprétation de l'image de différence, notez :

  • Où se trouvent les grappes rouges sur la page ? (haut, milieu, bas, gauche, droite)
  • Sont-elles associées à des éléments spécifiques ? (navigation, hero, cartes, pied de page)
  • Les grappes suggèrent-elles des problèmes d'espacement, des différences de couleur ou du contenu manquant ?

Étape 7 : Corriger et re-différencier

  1. Apportez des corrections CSS/HTML basées sur l'analyse de la différence
  2. Répétez les Étapes 3–6 (recapturez uniquement l'URL actuelle)
  3. Continuez jusqu'à ce que diffPercent atteigne un niveau acceptable

Objectifs typiques :

  • Réplication exacte : < 2 %
  • Correspondance raisonnable : < 5 %
  • Correspondance structurelle (contenu différent) : < 15 %

Captures d'écran plein écran

Par défaut, les captures d'écran ne capturent que la fenêtre visible. Pour les longues pages, utilisez l'option fullPage :

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

Avertissement : Les captures plein écran produisent de grandes images et des différences plus lentes. Ne les utilisez que pour comparer des mises en page de page entières.


Conseils spécifiques à Storybook

Lors de la capture de stories Storybook :

  1. Utilisez l'URL iframe pour des captures plus propres (pas de chrome Storybook) :

    http://localhost:6006/iframe.html?id=components-card--default&viewMode=story
    
  2. Attendez le rendu — les stories Storybook peuvent prendre un moment pour s'hydrater :

    mcp_playwright_browser_wait_for → { time: 3 }
    
  3. Les captures d'écran d'élément fonctionnent bien pour isoler le contenu de la story des éventuels padding de Storybook.


Réglage du seuil

Le drapeau --threshold (0 à 1) contrôle la sensibilité de pixelmatch :

ValeurSensibilitéCas d'utilisation
0,05Très strictCorrespondance exacte des pixels, détecte tout
0,1Par défautBon équilibre, ignore la plupart de l'anti-aliasing
0,2TolérantTolère les différences de rendu de police entre systèmes
0,3Très tolérantNe détecte que les principales différences de couleur/mise en page
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

Exemple : Comparer une section hero

# 1. Capturer la baseline (hero du site de production)
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 → {}
# Trouver la référence de la section hero, ex. ref="hero-[1]"
mcp_playwright_browser_take_screenshot → {
  type: "png",
  element: "hero section",
  ref: "hero-[1]",
  filename: "temp/vdiff-baseline-hero-desktop.png"
}

# 2. Capturer l'actuelle (story Storybook)
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. Exécuter la différence (dans le 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. Démarrer le serveur temporaire (une fois par session, dans un terminal en arrière-plan)
npx -y http-server temp/ -p 8787 --cors -c-1 &

# 5. Visualiser l'image de différence via Playwright
mcp_playwright_browser_navigate → { url: "http://localhost:8787/vdiff-diff-hero-desktop.png" }
mcp_playwright_browser_take_screenshot → {}   # déclenche la vision

# 6. Interpréter : lire la sortie JSON + inspecter visuellement la différence
# 7. Corriger les styles, re-capturer l'actuelle, re-différencier

Nettoyage

Tous les fichiers de sortie vont dans temp/, qui est ignoré par git. Pour nettoyer après une session :

rm -f temp/vdiff-*.png

Skills associés