La comparaison pixel par pixel casse sur des différences sans importance : rendu des polices, anti-aliasing, timestamps dynamiques. Les outils comme Percy et Applitools Eyes utilisent la vision par ordinateur pour comprendre ce qui a changé visuellement plutôt que compter les pixels.

Le problème de la comparaison pixel parfait

// Comparaison de captures d'écran traditionnelle
test('la page d\'accueil s\'affiche correctement', async ({ page }) => {
  await page.goto('/');
  await expect(page).toHaveScreenshot('homepage.png');  // Échoue sur 1px de différence
});

Ça casse pour :

  • Les différences de rendu des polices entre OS et versions de navigateur
  • Les animations capturées à des frames différents
  • Le contenu dynamique (timestamps, noms d'utilisateur, publicités)
  • Les variations d'anti-aliasing
  • Les différences de position de défilement

Le choix devient : accepter des faux échecs constants, ou relâcher les seuils au point de laisser passer de vrais bugs visuels.

Comment fonctionne le test visuel par IA

Les services de test visuel par IA utilisent la vision par ordinateur et le machine learning pour :

1. Comprendre la mise en page : reconnaître qu'un bouton est un bouton, pas juste des pixels

2. Ignorer les différences sans importance : variations de rendu du texte, légers décalages d'espacement

3. Signaler les changements significatifs : glissements de mise en page, éléments manquants, changements de couleur, contenu qui se chevauche

4. Regrouper les échecs similaires : 50 tests montrant le même bug deviennent un seul problème groupé

L'IA est entraînée sur des milliers de vrais changements UI et apprend quelles différences sont des bugs et lesquelles sont du bruit de rendu.

Percy (BrowserStack)

Percy est l'outil de test visuel par IA le plus établi, acquis par BrowserStack.

Configuration avec Playwright

npm install --save-dev @percy/cli @percy/playwright

// tests/visual.spec.ts
import { test } from '@playwright/test';
import percySnapshot from '@percy/playwright';

test('accueil visuel', async ({ page }) => {
  await page.goto('/');
  await percySnapshot(page, 'Homepage');
});

test('page de connexion visuelle', async ({ page }) => {
  await page.goto('/login');
  await percySnapshot(page, 'Login Page');
});

test('tableau de bord après connexion', async ({ page }) => {
  await page.goto('/login');
  await page.fill('[data-testid="email"]', 'user@test.com');
  await page.fill('[data-testid="password"]', 'ValidPass1');
  await page.click('[data-testid="submit"]');
  await page.waitForURL('/dashboard');
  
  await percySnapshot(page, 'Dashboard - Authenticated');
});

Lancer Percy

# Définir votre token Percy (depuis app.percy.io)
PERCY_TOKEN=your_token npx percy exec -- npx playwright test

Au premier lancement, Percy prend des captures de référence. Les lancements suivants les comparent et l'IA signale les vrais changements visuels pour révision humaine.

Intégration CI

# .github/workflows/visual-tests.yml
- name: Lancer les tests visuels Percy
  run: npx percy exec -- npx playwright test tests/visual.spec.ts
  env:
    PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

Percy publie les résultats comme une vérification de PR : les diffs visuels apparaissent directement dans votre pull request GitHub.

Applitools Eyes

Applitools utilise son moteur "Visual AI", plus précis que la comparaison pixel. Il gère les tests responsive et la comparaison au niveau des composants.

npm install --save-dev @applitools/eyes-playwright

import { test } from '@playwright/test';
import { Eyes, Target, Configuration } from '@applitools/eyes-playwright';

test('régression visuelle', async ({ page }) => {
  const eyes = new Eyes();
  
  const configuration = new Configuration();
  configuration.setApiKey(process.env.APPLITOOLS_API_KEY!);
  eyes.setConfiguration(configuration);
  
  await eyes.open(page, 'My App', 'Homepage Test');
  
  await page.goto('/');
  await eyes.check('Homepage', Target.window().fully());
  
  await page.goto('/products');
  await eyes.check('Products Page', Target.window().fully());
  
  await eyes.close();
});

L'Ultrafast Grid

La fonctionnalité clé d'Applitools : l'Ultrafast Grid rend votre snapshot DOM dans plusieurs navigateurs et viewports simultanément, sans lancer ces navigateurs sur votre machine.

import { VisualGridRunner, BrowserType, DeviceName, ScreenOrientation } from '@applitools/eyes-playwright';

const runner = new VisualGridRunner({ testConcurrency: 5 });

const configuration = new Configuration();
configuration.addBrowser(1280, 800, BrowserType.CHROME);
configuration.addBrowser(1440, 900, BrowserType.FIREFOX);
configuration.addDeviceEmulation(DeviceName.iPhone_12, ScreenOrientation.PORTRAIT);
configuration.addDeviceEmulation(DeviceName.iPad_Pro, ScreenOrientation.LANDSCAPE);

Un seul lancement Playwright, des résultats visuels pour 4 configurations navigateur/appareil.

Comparaison de captures d'écran intégrée à Playwright

Playwright intègre une comparaison visuelle basique, sans IA :

// Intégré : comparaison pixel avec seuil configurable
test('capture d\'écran de la page d\'accueil', async ({ page }) => {
  await page.goto('/');
  
  // Autoriser jusqu'à 1% de différence pixel
  await expect(page).toHaveScreenshot('homepage.png', {
    maxDiffPixelRatio: 0.01,
  });
  
  // Ou définir un nombre absolu de pixels
  await expect(page).toHaveScreenshot('homepage.png', {
    maxDiffPixels: 50,
  });
});

// Masquer le contenu dynamique
await expect(page).toHaveScreenshot('homepage.png', {
  mask: [
    page.getByTestId('timestamp'),
    page.getByTestId('user-avatar'),
    page.getByTestId('ad-banner'),
  ],
});

Quand utiliser l'intégré : projets simples, pages statiques, environnement entièrement contrôlé. Quand utiliser les outils IA : cross-browser, multi-appareils, contenu dynamique, révision collaborative des diffs visuels.

Gérer le contenu dynamique

Le principal défi des tests visuels : le contenu qui change légitimement entre deux lancements.

Masquer les éléments dynamiques

// Percy
await percySnapshot(page, 'Dashboard', {
  percyCSS: `
    [data-testid="timestamp"] { visibility: hidden; }
    [data-testid="user-avatar"] { filter: blur(10px); }
  `,
});

// Playwright intégré
await expect(page).toHaveScreenshot({
  mask: [
    page.locator('[data-testid="timestamp"]'),
    page.locator('.ad-container'),
  ],
});

Attendre un état stable

test('test visuel du graphique', async ({ page }) => {
  await page.goto('/analytics');
  
  // Attendre la fin des animations
  await page.waitForLoadState('networkidle');
  await page.waitForTimeout(500);  // Marge pour les transitions CSS
  
  // Attendre l'élément qui confirme le chargement des données
  await page.waitForSelector('[data-testid="chart-loaded"]');
  
  await percySnapshot(page, 'Analytics Dashboard');
});

Figer le temps

// Figer Date pour que les timestamps ne changent pas entre les lancements
await page.addInitScript(() => {
  const fixedDate = new Date('2026-01-15T12:00:00Z');
  Date.now = () => fixedDate.getTime();
  Date = class extends Date {
    constructor(...args) {
      if (args.length === 0) {
        super(fixedDate.getTime());
      } else {
        super(...args);
      }
    }
  };
});

Tests visuels au niveau des composants

Plutôt que des captures pleine page, testez les composants individuellement :

test('test visuel des variantes de bouton', async ({ page }) => {
  await page.goto('/storybook/button');
  
  // Tester chaque variante de bouton
  const variants = ['primary', 'secondary', 'danger', 'ghost'];
  
  for (const variant of variants) {
    await page.click(`[data-story="${variant}"]`);
    await percySnapshot(page, `Button - ${variant}`);
  }
});

Les tests de composants sont plus stables que les captures pleine page : moins de variables, plus facile d'isoler ce qui a changé.

Mettre en place un workflow de tests visuels

1. Création de la référence

Le premier lancement crée les captures de référence. Révisez-les attentivement : n'approuvez que ce qui est visuellement correct.

2. Workflow de PR

  • Le développeur fait des modifications
  • La CI lance les tests visuels
  • Les diffs sont publiés sur la PR
  • Le QA ou le développeur révise les diffs
  • Approuver les changements attendus (nouvelle fonctionnalité correcte), rejeter les inattendus (bug)

3. Mise à jour des références

Quand l'UI change intentionnellement, les références doivent être mises à jour. Sur Percy, approuvez les diffs dans le dashboard. Sur Playwright, lancez avec le flag --update-snapshots.

npx playwright test --update-snapshots

Commitez les captures mises à jour avec la PR.

Comparatif des coûts

| Outil | Tier gratuit | Payant |

|-------|-------------|--------|

| Playwright intégré | Gratuit (open source) | Gratuit |

| Percy | 5 000 captures/mois | À partir de 99 $/mois |

| Applitools | Essai limité | Tarif personnalisé |

| Chromatic | 5 000 snapshots/mois | À partir de 149 $/mois |

Pour les petits projets, la comparaison intégrée de Playwright avec masquage et réglage des seuils suffit. Pour les équipes qui livrent fréquemment : Percy ou Applitools, la révision des diffs par IA économise des heures de comparaison manuelle.

Tableau récapitulatif

| Approche | Précision | Coût | Idéal pour |

|----------|-----------|------|------------|

| Playwright intégré | Pixel parfait | Gratuit | Pages statiques, environnement contrôlé |

| Percy | IA | À partir de 99 $/mois | Cross-browser, révision en équipe |

| Applitools | Visual AI + grid | Tarif personnalisé | Enterprise, multi-navigateurs |

Quatre règles pour que les tests visuels tiennent la route :

  • Masquer le contenu dynamique (timestamps, publicités, avatars)
  • Attendre un état stable avant les captures
  • Réviser les références avec soin avant approbation
  • Regrouper les tests visuels par page ou composant pour faciliter la révision

Les tests visuels par IA ne suppriment pas les faux positifs : ils les réduisent considérablement. Les diffs qui arrivent en révision sont beaucoup plus souvent de vrais problèmes.

→ See also: Tests de Régression Visuelle avec Playwright: toHaveScreenshot sans Applitools | Assertions dans Playwright: Le Guide Complet | Tests Multi-Navigateurs avec Playwright: Chrome, Firefox, Safari