De zéro à un test qui passe, il faut environ 30 minutes.
Pourquoi Playwright plutôt qu'autre chose
Avant d'installer quoi que ce soit, la version courte : Playwright est ce que la plupart des nouveaux projets choisissent en 2026, et pour de bonnes raisons.
Selenium était le standard pendant des années. Ça fonctionne, mais c'est lent à configurer, verbeux à écrire, et ça demande de gérer manuellement les drivers de navigateur. Cypress est plus simple mais ne supporte que les navigateurs basés sur Chromium et impose un payant pour les runs parallèles en CI.
Playwright gère les applications web modernes sans configuration particulière. Il attend automatiquement que les éléments soient prêts avant d'interagir avec eux, donc pas besoin d'appels sleep() aléatoires dans vos tests. Il supporte Chromium, Firefox et WebKit. Il intègre un test runner, l'enregistrement vidéo des échecs, et un générateur de code qui écrit les locators à votre place pendant que vous cliquez sur une page.
Si vous partez de zéro en 2026, Playwright est le bon choix.
Installation
Vous avez besoin de Node.js d'abord. Vérifiez s'il est installé :
node --versionSi ça retourne un numéro de version (v18 ou plus, c'est parfait), vous pouvez continuer. Sinon, téléchargez la version LTS sur nodejs.org.
Créez maintenant un nouveau dossier pour votre projet et lancez l'installateur Playwright :
mkdir my-first-tests
cd my-first-tests
npm init playwright@latestL'installateur pose quelques questions. Pour l'apprentissage, acceptez les valeurs par défaut :
- TypeScript ou JavaScript → TypeScript
- Dossier des tests → tests
- Workflow GitHub Actions → non (à ajouter plus tard)
- Installer les navigateurs Playwright → oui
Le téléchargement des navigateurs prend une à deux minutes. Une fois terminé, votre projet ressemble à ça :
my-first-tests/
tests/
example.spec.ts
playwright.config.ts
package.jsonC'est tout. Pas de fichiers de configuration à combattre, pas de gestionnaires de drivers, pas de test runner séparé à installer.
Lancer l'exemple de test
Avant d'écrire quoi que ce soit, lancez ce qui est fourni avec l'installation :
npx playwright testPlaywright exécute les tests d'exemple en mode headless (pas de fenêtre de navigateur visible) et affiche les résultats dans le terminal. Vous verrez quelque chose comme :
Running 2 tests using 2 workers
2 passed (3s)Pour voir ce qui s'est passé, ouvrez le rapport HTML :
npx playwright show-reportÇa ouvre un navigateur avec un rapport détaillé de chaque test : les étapes exécutées, la durée de chacune, et des captures d'écran à la fin.
npx playwright test --headed pour regarder le navigateur s'ouvrir et exécuter le test en temps réel. Utile quand on débute et qu'on veut voir ce qui se passe.Votre premier test
Supprimez le fichier de test d'exemple et créez-en un nouveau. Ouvrez tests/login.spec.ts et écrivez ceci :
import { test, expect } from '@playwright/test';
test('user can log in', async ({ page }) => {
await page.goto('https://lab.becomeqa.com');
await page.getByRole('button', { name: 'Login' }).click();
await page.getByLabel('Username').fill('admin@becomeqa.com');
await page.getByLabel('Password').fill('testpass123');
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('My Travel Items')).toBeVisible();
});Lancez-le :
npx playwright test tests/login.spec.tsVous devriez voir 1 passed. Voici ce que fait chaque partie.
Comprendre ce que vous venez d'écrire
test('user can log in', async ({ page }) => {
test est la fonction qui définit un cas de test. Le premier argument est le nom : rédigez-le comme une phrase décrivant ce que fait l'utilisateur, pas ce que fait le code. async signifie que la fonction est asynchrone, ce qui est nécessaire car chaque action de navigateur prend du temps. { page } est la fixture page de Playwright, qui vous donne un onglet de navigateur frais à utiliser.
await page.goto('https://lab.becomeqa.com')
Ouvre l'URL. await dit à JavaScript d'attendre la fin de cette action avant de passer à la ligne suivante. Vous utiliserez await devant chaque action Playwright.
page.getByRole('button', { name: 'Login' })
C'est un locator. Il trouve un élément sur la page. getByRole trouve des éléments par leur rôle ARIA et leur nom accessible. Il trouve ici un bouton avec le texte "Login". C'est le type de locator le plus fiable parce qu'il est lié au fonctionnement réel de l'élément, pas à sa classe CSS ou sa position.
await page.getByLabel('Username').fill('admin@becomeqa.com')
Trouve le champ de saisie associé à un label "Username" et tape l'adresse e-mail dedans.
await expect(page.getByText('My Travel Items')).toBeVisible()
C'est l'assertion, la partie qui vérifie vraiment quelque chose. Elle confirme que le texte "My Travel Items" est visible sur la page après la connexion. Si la connexion échoue et que ce texte n'apparaît pas, le test échoue.
Locators : comment trouver les éléments
Les locators indiquent à Playwright avec quel élément interagir. Il en existe plusieurs types, chacun adapté à une situation différente.
getByRole est le choix privilégié. Il utilise les rôles ARIA, qui décrivent le sens sémantique des éléments :
page.getByRole('button', { name: 'Submit' }) // un bouton libellé Submit
page.getByRole('link', { name: 'Home' }) // un lien libellé Home
page.getByRole('textbox', { name: 'Search' }) // un champ texte libellé SearchgetByLabel fonctionne pour les champs de formulaire avec un label visible :
page.getByLabel('Email address')
page.getByLabel('Password')getByPlaceholder quand il n'y a pas de label mais un placeholder :
page.getByPlaceholder('Enter your email')getByText trouve les éléments par leur contenu texte visible :
page.getByText('My Travel Items')
page.getByText('Sign out')getByTestId utilise un attribut data-testid. Utile quand les développeurs en ajoutent spécifiquement pour les tests :
page.getByTestId('submit-button')Évitez les locators basés sur les classes CSS ou XPath. Ils cassent dès qu'un développeur renomme une classe ou restructure le HTML. Les locators basés sur les rôles survivent à ces changements.
Actions : interagir avec la page
Une fois que vous avez un locator, vous pouvez agir dessus :
await locator.click() // cliquer sur un élément
await locator.fill('some text') // vider et taper dans un champ
await locator.type('some text') // taper caractère par caractère (pour les inputs qui réagissent aux frappes)
await locator.check() // cocher une case
await locator.selectOption('value') // sélectionner dans un dropdown
await locator.hover() // survoler un élément
await locator.press('Enter') // appuyer sur une touche du clavierPoint important : vous n'avez presque jamais besoin d'attendre les éléments vous-même. Playwright attend automatiquement qu'un élément soit visible et actif avant d'agir. C'est l'auto-attente, et c'est ce qui élimine la plupart de l'instabilité dans les tests Playwright.
Assertions : vérifier le résultat
Une assertion est ce qui rend un test vraiment utile. Sans assertions, vous ne faites que cliquer sur une page.
// Vérifier la visibilité
await expect(page.getByText('Welcome')).toBeVisible();
await expect(page.getByRole('dialog')).toBeHidden();
// Vérifier le contenu textuel
await expect(page.getByRole('heading')).toHaveText('My Travel Items');
await expect(page.getByRole('heading')).toContainText('Travel');
// Vérifier les valeurs de champs
await expect(page.getByLabel('Email')).toHaveValue('test@example.com');
// Vérifier l'URL
await expect(page).toHaveURL('https://lab.becomeqa.com/dashboard');
// Vérifier le titre de la page
await expect(page).toHaveTitle('BecomeQA Lab');
// Vérifier le nombre d'éléments
await expect(page.getByRole('row')).toHaveCount(5);Les assertions de Playwright ont aussi une auto-attente. toBeVisible() ne vérifie pas juste l'état actuel. Elle réessaie pendant jusqu'à 5 secondes par défaut, en attendant que l'élément apparaisse. Pas besoin d'attentes explicites avant les assertions non plus.
Un test plus complet
Voici un deuxième test qui continue après la connexion :
import { test, expect } from '@playwright/test';
test('user can log in', async ({ page }) => {
await page.goto('https://lab.becomeqa.com');
await page.getByRole('button', { name: 'Login' }).click();
await page.getByLabel('Username').fill('admin@becomeqa.com');
await page.getByLabel('Password').fill('testpass123');
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('My Travel Items')).toBeVisible();
});
test('travel items table has data', async ({ page }) => {
// connexion d'abord
await page.goto('https://lab.becomeqa.com');
await page.getByRole('button', { name: 'Login' }).click();
await page.getByLabel('Username').fill('admin@becomeqa.com');
await page.getByLabel('Password').fill('testpass123');
await page.getByRole('button', { name: 'Submit' }).click();
// vérifier la table
await expect(page.getByRole('table')).toBeVisible();
const rows = page.getByRole('row');
await expect(rows).toHaveCount(6); // en-tête + 5 lignes de données
});Lancez les deux tests :
npx playwright test tests/login.spec.tsVous remarquerez que les étapes de connexion sont dupliquées entre les tests. C'est normal pour l'instant. Une fois que vous avez plus de tests, vous déplacerez le setup répété dans un bloc beforeEach ou une fixture, mais c'est un sujet intermédiaire.
Le fichier playwright.config.ts
Ouvrez playwright.config.ts. Les valeurs par défaut fonctionnent bien, mais deux paramètres valent la peine d'être connus :
export default defineConfig({
testDir: './tests',
timeout: 30000, // durée max par test en ms
retries: 0, // nombre de retries pour un test en échec
use: {
baseURL: 'https://lab.becomeqa.com', // ajoutez ceci
trace: 'on-first-retry',
},
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
});Si vous définissez baseURL, vous pouvez écrire page.goto('/') au lieu de l'URL complète dans vos tests. Ajoutez-la à la config et mettez vos tests à jour :
await page.goto('/'); // au lieu de 'https://lab.becomeqa.com'Par défaut Playwright lance les tests sur les trois navigateurs (Chromium, Firefox, WebKit). Pour ne lancer que sur Chromium pendant l'apprentissage :
npx playwright test --project=chromiumQuand un test échoue
Cassons notre test intentionnellement. Changez le texte attendu pour quelque chose qui n'existe pas :
await expect(page.getByText('This text does not exist')).toBeVisible();Lancez-le et vous verrez :
1 failed
login.spec.ts:10:3 › user can log in ✗
Error: expect(locator).toBeVisible()
Locator: getByText('This text does not exist')
Expected: visible
Received: hidden
Timeout: 5000msL'erreur indique exactement ce qu'il attendait et que ça n'est jamais devenu visible. Consultez maintenant la trace :
npx playwright show-reportCliquez sur le test en échec. Vous verrez un détail étape par étape avec des captures à chaque action. C'est le trace viewer, l'une des fonctionnalités les plus utiles de Playwright pour déboguer les échecs.
→ See also: Installer Playwright: Guide d'Installation Étape par Étape (2026) | Locators Playwright: getByRole, getByLabel, getByText, getByTestId Comparés | Assertions dans Playwright: Le Guide Complet | Playwright Trace Viewer: Déboguez les Tests Échoués Comme un ProRemettez le test à 'My Travel Items' avant de continuer.
FAQ
Dois-je connaître TypeScript avant de commencer ?Non. Le TypeScript que vous écrirez pour les tests est minimal, principalement async/await et des types de base. Le cours Playwright couvre exactement ce dont vous avez besoin au fur et à mesure.
TypeScript est le meilleur choix même si vous le découvrez. Il détecte les erreurs avant l'exécution du test. La syntaxe supplémentaire est légère et les bénéfices sont immédiats.
Comment trouver le bon locator pour un élément ?Utilisez l'outil codegen de Playwright : npx playwright codegen https://lab.becomeqa.com. Il ouvre un navigateur, enregistre vos clics, et génère automatiquement le code de locator. Utilisez-le pour explorer, puis nettoyez ce qu'il génère.
Généralement un problème de timing ou un await manquant. Lancez avec --headed en local pour regarder ce qui se passe, puis vérifiez si vous avez oublié un await quelque part.