liksi logo

Playwright - Le dramaturge de vos tests e2e

Benjamin Sourisse - Publié le 25/01/2024
Playwright - Le dramaturge de vos tests e2e

Chez LIKSI, l’émulation technique est forte et les moments de partages sont nombreux. C’est suite à une conférence de Florent VAUTION (Head of QA @ Ouest-France) à nos bureaux de Rennes, que j’ai eu l’idée de regarder du côté de Playwright, lui ayant préféré Cypress jusqu’à présent. Cet article n’a pas vocation à être exhaustif mais à vous présenter les grandes lignes et fonctionnalités principales.

Le bien nommé Playwright (de l’anglais “dramaturge”) vous permet, à l’instar de Cypress, de mettre en scène des scénarios de tests end-to-end fiables et automatisables. La release initiale de ce framework sous licence opensource Apache-2.0 date du 31/01/2020 et compte, à l’écriture de cet article, pas moins de 56.8k stars sur Github.

Framework Initial release Licence Github stars Company
Playwright 31/01/2020 Apache-2.0 GitHub stars Microsoft
Cypress 10/09/2017 MIT / Proprietary GitHub stars Cypress

Playwright permet de lancer les scénarios de tests grâce à son API qui prend en charge les moteurs Firefox, Chromium et Webkit, aussi bien en émulation mobile que desktop. Playwright est écrit en Node.js mais il peut être utilisé en TypeScript/JavaScript, Python, .NET et Java avec d’ailleurs une documentation adaptée à chaque langage. Dans cet article, nous verrons le cas d’usage en TS.

Index

L’installation

npm init playwright@latest

Playwright possède un programme d’init qui vous permettra de configurer l’installation pour l’adapter à votre projet avec les options suivantes :

  • Choix entre TS et JS
  • Nom du répertoire pour les scripts de test
  • Possibilité d’ajout d’un fichier workflow Gihub Action
  • Installation du browser Playwright (nécessaire au mode headed)

Le reste de la configuration se fera essentiellement au travers du fichier playwright.config.ts dont vous trouverez la documentation ici.

L’écriture des tests

L’écriture des tests est assez simple car elle se résume finalement à deux grands principes :

  • Exécuter des actions dans notre interface
  • Contrôler que l’état de notre interface est conforme à nos attentes

La classe Locator

Pour exécuter une action (clic sur un bouton, hover sur une icône, complétion d’un champ…), il faut d’abord localiser l’élément cible dans le DOM. Pour cela, c’est la classe locator de l’API qui sera principalement utilisée au travers de la méthode page.locator(). Cette classe comporte les méthodes nécessaires à une recherche rapide dans le DOM mais également des dizaines d’actions nécessaires

Par exemple, je localise mon élément button qui a un label “Add” et je lance l’action de cliquer dessus :

await page.getByRole("button", { name: "Add" }).click();

La fonction expect()

Comme tout bon framework de test e2e, il faut pouvoir exécuter des actions mais aussi contrôler leurs résultats et l’état du DOM. Les assertions (“affirmations” en anglais) sont là pour ça. Ces contrôles se font grâce à la classe GenericAssertions de Playwright qui sera instanciée par l’appel à la fonction expect(). Là aussi, il existe quelques dizaines de méthodes couvrant la totalité ou presque des cas possibles.

Voici un exemple qui combine le locator et l’assertion afin de vérifier qu’un élément du DOM est bien présent. Ici, je recherche dans le DOM une cellule de tableau comportant “Storage Used” et je dois la trouver une fois.

expect(page.getByRole("cell", { name: "Storage Used" })).toHaveCount(1);

La gestion des timeout

Une chose que j’ai trouvée agréable dans Playwright a été le fait que je n’ai pas eu de problème avec d’éventuels délais d’attente. Lorsqu’un élément met du temps à s’afficher (par exemple en cas d’animation CSS, de réponse API lente…), Playwright patiente de manière automatique sans que j’ai eu à configurer quoique ce soit. Cette page de documentation vous sera utile pour les questions en rapport aux délais d’attente.

Les mocks

Lors de mes tests, j’ai eu besoin de mocker certaines réponses API. En effet, l’objectif ici n’est pas de tester l’API en elle-même mais plutôt de contrôler :

  • Les requêtes envoyées par le front à l’API (type de requête, données…).
  • L’état du DOM suite à une réponse précise de l’API.

Ainsi, dans cet exemple je viens mocker la route **/api/repo/add avec une réponse prédéfinie qui sera renvoyée au front. Je vais plus loin en contrôlant plusieurs points dans la requête API qui est envoyée par le front :

  • Contrôle de la méthode HTTP (ici, on attend un POST)
  • Contrôle de la présence de données dans la requête
  • Contrôle du format des données (ici, on attend un objet)
  • Contrôle précis des clés attendues dans l’objet qui est passé dans la requête
import { Page, expect } from "@playwright/test";

export async function mockAddRepo(page: Page) {
  page.route("**/api/repo/add", (route) => {
    const request = route.request();
    const method = request.method();
    const postData = request.postData();

    expect(method).toBe("POST");
    expect(postData).toBeTruthy();
    expect(typeof requestBody).toBe("object");

    const requestBody = JSON.parse(postData || "");
    expectRequestBodyProperties(requestBody, [
      "alias",
      "size",
      "sshPublicKey",
      "comment",
      "alert",
      "lanCommand",
    ]);

    // Mock the response
    route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify({
        message: "Repository created",
      }),
    });
  });
}

function expectRequestBodyProperties(requestBody: any, properties: string[]) {
  properties.forEach((property) => {
    expect(requestBody).toHaveProperty(property);
  });
}

Les modes headed et headless de Playwright

Le mode headless

Par défaut, les tests sont lancés en mode headless, donc sans affichage avec uniquement un retour console.

npx playwright test

Playwright va également générer un rapport HTML qu’il sera possible d’afficher ou de récupérer. Dans ce rapport, chaque test peut être parcouru pour en lire les détails de résultat :

Le mode headed

Le mode headed va lancer un navigateur ou plusieurs s’il y a plusieurs tests (le parallélisme de Playwright est gérable en config) et ces navigateurs seront refermés immédiatement à la fin de chaque test :

npx playwright test --headed

Le mode UI est le mode le plus intéressant car c’est une interface pour Playwright qui inclut des fonctionnalités comme le debug, une timeline, un picker pour récupérer le locator d’un élément, une console… C’est pour moi le mode le plus complet et intéressant à utiliser en développement.

npx playwright test --ui

L’extension VSCODE de Playwright

Playwright étant développé par Microsoft (qui est pour rappel propriétaire de VSCode, ou encore Github), il possède évidemment son extension VSCode.

Et cette extension est plutôt utile pour avoir :

  • une vue rapide sur les tests et leurs lancements
  • un mode de debug
  • l’accès à des options de run comme l’affichage du navigateur (mode headed) ou des traces

Vous trouverez également un mode record dans l’extension. Ce mode permet de lancer un navigateur, et chaque action sera transformée à la volé en une ligne de test qui correspond à l’action. Plutôt sympa !

Si vous ne souhaitez pas passer par l’extention, il est possible d’obtenir cette foncitonnalité avec :

npx playwright codegen

Conclusion

J’ai découvert Playwright il y a seulement quelques semaines et je l’ai trouvé très agréable à utiliser. La courbe d’apprentissage n’est pas très importante, la documentation est bien faite et l’outillage est bien en place. Je pense que c’est le framework de tests e2e de ces prochaines années et suite aux divers problèmes de licence Cypress dont j’ai entendu parlé lors de deux conférences, je pense que c’est le framework à choisir pour tout nouveau projet.

J’espère avoir l’occasion de m’en servir sur de futurs projets car, après tout, tester c’est faire de la qualité !


Image d’illustration d’article générée par stablediffusion.

Derniers articles