playwright.config.ts contrôle où les tests s'exécutent, quels navigateurs utiliser, le comportement en matière de timeout et de tentatives. Il gère aussi le nombre de workers parallèles, les reporters et les paramètres d'environnement comme baseURL.

La config minimale

Après npm init playwright@latest, vous obtenez quelque chose comme :

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: 'html',
  use: {
    baseURL: 'http://localhost:3000',
    trace: 'on-first-retry',
  },
  projects: [
    { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
    { name: 'firefox',  use: { ...devices['Desktop Firefox'] } },
    { name: 'webkit',   use: { ...devices['Desktop Safari'] } },
  ],
});

Parcourons chaque section.

Options de niveau supérieur

testDir

Le répertoire où Playwright cherche les fichiers de test.

testDir: './tests',

Chemin relatif ou absolu. Les fichiers correspondant à /.spec.ts ou /.test.ts dans ce dossier sont détectés automatiquement.

fullyParallel

fullyParallel: true,

Avec true, tous les tests s'exécutent en parallèle entre les workers, même ceux dans le même fichier. Avec false (comportement d'origine), les tests d'un même fichier s'exécutent séquentiellement, mais des fichiers différents tournent en parallèle.

Pour la plupart des projets : mettez true. Les tests doivent être assez indépendants pour s'exécuter dans n'importe quel ordre.

forbidOnly

forbidOnly: !!process.env.CI,

Si un test contient test.only(), cette option fait échouer toute l'exécution. Le schéma !!process.env.CI signifie qu'elle ne s'applique qu'en CI. Vous pouvez utiliser test.only() en local pour déboguer, mais vous ne pouvez pas l'envoyer par inadvertance en production.

Utilisez toujours cette option dans les configs de production.

retries

retries: process.env.CI ? 2 : 0,

Nombre de tentatives avant de marquer un test comme échoué. Deux tentatives en CI (aide avec les tests flaky), zéro en local (les échecs sont visibles immédiatement).

Si un test échoue à la première tentative mais réussit à la deuxième, Playwright le signale comme "flaky" dans le rapport.

workers

workers: process.env.CI ? 1 : undefined,

Nombre de workers parallèles (instances de navigateur). Par défaut (undefined), Playwright utilise 50 % des cœurs CPU. La valeur 1 exécute tous les tests séquentiellement, utile en CI pour éviter la contention des ressources. La valeur 4 lance quatre workers en parallèle.

En développement local avec une machine rapide, undefined convient. En CI, 1 est plus sûr sauf si vous avez un runner puissant.

timeout

timeout: 30_000,  // 30 secondes par test

Durée maximale d'exécution d'un test avant qu'il soit marqué comme échoué. 30 secondes par défaut. Pour des tests lents ou des machines CI lentes, augmentez à 60 secondes.

expect.timeout

expect: {
  timeout: 5_000,  // 5 secondes par assertion expect()
},

Les assertions Playwright réessaient automatiquement jusqu'à ce que la condition soit remplie ou que ce timeout expire. 5 secondes par défaut.

Le bloc use (options partagées)

use contient des options qui s'appliquent à tous les tests (sauf surcharge dans un projet).

use: {
  baseURL: 'http://localhost:3000',
  
  // Paramètres du navigateur
  headless: true,
  viewport: { width: 1280, height: 720 },
  
  // Enregistrement
  trace: 'on-first-retry',     // 'on-first-retry' | 'retain-on-failure' | 'always' | 'off'
  video: 'retain-on-failure',  // 'retain-on-failure' | 'always' | 'off'
  screenshot: 'only-on-failure',
  
  // Timing
  actionTimeout: 10_000,       // Timeout pour chaque action (click, fill, etc.)
  navigationTimeout: 30_000,   // Timeout pour page.goto() et page.waitForURL()
  
  // HTTP
  ignoreHTTPSErrors: true,     // Utile pour les environnements staging avec des certificats auto-signés
  
  // Locale
  locale: 'fr-FR',
  timezoneId: 'Europe/Paris',
},

baseURL

Quand défini, page.goto('/login') se résout en http://localhost:3000/login. Rend les tests portables entre environnements.

Utilisez des variables d'environnement :

baseURL: process.env.BASE_URL || 'http://localhost:3000',

trace

Les traces Playwright capturent un enregistrement complet de chaque action (snapshot DOM, captures d'écran, appels réseau) pour le débogage.

  • 'on-first-retry' : capture à la première nouvelle tentative d'un test échoué (recommandé)
  • 'retain-on-failure' : capture pour tout test échoué (plus de stockage)
  • 'always' : capture tout (beaucoup de stockage, lent)
  • 'off' : pas de traces

Visualisez les traces avec npx playwright show-trace trace.zip.

video

  • 'retain-on-failure' : sauvegarde la vidéo uniquement pour les tests échoués (recommandé)
  • 'always' : sauvegarde tout
  • 'off' : pas de vidéo

projects : configs multi-navigateurs

Les projets permettent d'exécuter les mêmes tests sur différents navigateurs, viewports ou configurations.

projects: [
  // Navigateurs desktop
  {
    name: 'chromium',
    use: { ...devices['Desktop Chrome'] },
  },
  {
    name: 'firefox',
    use: { ...devices['Desktop Firefox'] },
  },
  {
    name: 'webkit',
    use: { ...devices['Desktop Safari'] },
  },
  
  // Mobile
  {
    name: 'mobile-chrome',
    use: { ...devices['Pixel 7'] },
  },
  {
    name: 'mobile-safari',
    use: { ...devices['iPhone 14'] },
  },
],

devices['Desktop Chrome'] est un preset qui définit le viewport, le user agent et d'autres valeurs par défaut propres au navigateur. Liste complète : npx playwright show-report ou la documentation Playwright.

Projets pour différents environnements

projects: [
  {
    name: 'staging',
    use: {
      ...devices['Desktop Chrome'],
      baseURL: 'https://staging.myapp.com',
    },
    testMatch: '**/*.spec.ts',
  },
  {
    name: 'production',
    use: {
      ...devices['Desktop Chrome'],
      baseURL: 'https://myapp.com',
    },
    testMatch: '**/smoke/*.spec.ts',  // Uniquement les smoke tests en production
  },
],

Projets de setup (configuration globale)

projects: [
  {
    name: 'setup',
    testMatch: /.*\.setup\.ts/,  // Fichiers comme auth.setup.ts
  },
  {
    name: 'chromium',
    use: { ...devices['Desktop Chrome'] },
    dependencies: ['setup'],  // Exécute setup en premier
  },
],

Utilisé pour exécuter la configuration d'authentification une seule fois avant tous les tests, puis réutiliser l'état d'auth sauvegardé.

reporter

Format de génération des résultats de tests :

reporter: [
  ['html'],                                // Rapport HTML dans playwright-report/
  ['junit', { outputFile: 'results.xml' }], // JUnit XML pour la CI
  ['list'],                                 // Sortie console en direct
],

En développement local, 'html' est idéal, ouvrez playwright-report/index.html pour un rapport visuel complet. En CI, ajoutez 'junit' pour que les outils CI (GitHub Actions, GitLab CI, Jenkins) puissent analyser les résultats.

globalSetup et globalTeardown

Pour le setup qui s'exécute une fois avant que toute la suite de tests commence :

globalSetup: './global-setup.ts',
globalTeardown: './global-teardown.ts',

// global-setup.ts
import { chromium } from '@playwright/test';

export default async function globalSetup() {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  
  // Connexion et sauvegarde de l'état d'auth
  await page.goto('http://localhost:3000/login');
  await page.fill('[data-testid="email"]', 'admin@test.com');
  await page.fill('[data-testid="password"]', 'AdminPass1');
  await page.click('[data-testid="submit"]');
  await page.context().storageState({ path: 'auth.json' });
  
  await browser.close();
}

Les tests utilisent ensuite l'état d'auth sauvegardé sans se reconnecter :

use: {
  storageState: 'auth.json',
},

Une config prête pour la production

import { defineConfig, devices } from '@playwright/test';
import dotenv from 'dotenv';

dotenv.config();

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 2 : undefined,
  
  timeout: 45_000,
  expect: { timeout: 8_000 },
  
  reporter: [
    ['html'],
    ...(process.env.CI ? [['junit', { outputFile: 'test-results/results.xml' }] as const] : []),
  ],
  
  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
    video: 'retain-on-failure',
    screenshot: 'only-on-failure',
    actionTimeout: 10_000,
    navigationTimeout: 30_000,
  },
  
  projects: [
    {
      name: 'setup',
      testMatch: /auth\.setup\.ts/,
    },
    {
      name: 'chromium',
      use: {
        ...devices['Desktop Chrome'],
        storageState: 'playwright/.auth/user.json',
      },
      dependencies: ['setup'],
    },
    {
      name: 'api',
      testMatch: '**/api/**/*.spec.ts',
      use: { storageState: undefined },  // Les tests API n'ont pas besoin d'auth navigateur
    },
  ],
});

Lancer des projets spécifiques

# Tous les tests sur chromium
npx playwright test --project=chromium

# Uniquement le projet setup
npx playwright test --project=setup

# Plusieurs projets
npx playwright test --project=chromium --project=firefox

Récapitulatif des options les plus importantes

| Option | Recommandation |

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

| testDir | './tests' |

| fullyParallel | true |

| forbidOnly | !!process.env.CI |

| retries | CI ? 2 : 0 |

| timeout | 30 000–60 000 |

| trace | 'on-first-retry' |

| video | 'retain-on-failure' |

| baseURL | Depuis une variable d'environnement |

| reporter | HTML en local, + JUnit en CI |

Le fichier de config mérite 30 minutes de travail soigné au démarrage d'un projet. Un playwright.config.ts bien configuré évite des heures de débogage et de problèmes CI par la suite.

→ See also: Installer Playwright: Guide d'Installation Étape par Étape (2026) | Configuration d'Environnement Playwright: Local, Staging et Production | Exécution Parallèle dans Playwright: Workers, Fragments et Fragmentation pour la Vitesse | Variables d'Environnement dans les Tests Playwright: Un Guide Complet