IE-Concept

Tests fonctionnels avec playwright

Tests fonctionnels avec Playwright

Afin de maintenir la fonctionnalité d’une application Web à tout moment et en toutes circonstances, il est essentiel de mettre en place des tests fonctionnels automatisés. Cette approche implique l’utilisation d’outils logiciels spécialisés pour tester divers aspects des fonctionnalités de l’application, y compris sa capacité à répondre aux entrées de l’utilisateur, à effectuer des tâches ou des opérations spécifiées et à produire les résultats attendus. En automatisant ces tests, les développeurs Web peuvent identifier et résoudre rapidement et facilement tout problème ou bogue susceptible de survenir, sans avoir besoin de tests manuels approfondis ou de débogage. De plus, l’utilisation de tests fonctionnels automatisés peut aider à minimiser le risque de temps d’arrêt coûteux ou d’erreurs, ainsi qu’à améliorer la qualité et la fiabilité globales de l’application. En tant que tel, il s’agit d’un élément clé de toute stratégie de développement Web robuste et efficace.

Pourquoi automatiser ses tests fonctionnels ?

Un test fonctionnel signifie que l’on va physiquement se déplacer sur l’application pour cliquer sur les boutons, interagir avec l’API et la base de données, et vérifier que le résultat est bien celui attendu.

Une application peut être amenée à être modifiée très fréquemment. Or, il est impensable d’exécuter manuellement tous les tests à chaque fois, aussi, la solution est de programmer un robot via le logiciel Playwright, qui ira cliquer aussi rapidement que l’application le lui permet sur les boutons que nous avons besoin d’actionner, afin de réaliser les manipulations que nous avons besoin de tester.

Pourquoi Playwright ?

Playwright est un outil open-source créer en 2020 qui permet de créer des scénarios de tests sous forme de code, puis de les jouer sur différents navigateurs. Cet outil permet donc d’automatiser des tests fonctionnels d’applications / services Web.

Avec Playwright il est possible de directement exécuter les tests depuis l’éditeur de code, par exemple vscode, et de voir quelles lignes du fichier fonctionnent et quelles lignes échouent, avec à chaque fois le temps d’exécution en millisecondes.

Comparé à Jest, Cypress ou NightWatch, la librairie Node.js Playwright se veut plus rapide à l’exécution.

Le GIF ci-dessus montre l’exemple d’exécution d’un fichier de test appelé «exemple.spec.js». Vous pouvez voir que Playwright ouvre son propre navigateur pour exécuter les tests.

Présentation de l’application et des tests d'exemples

Avec cette application, on va pouvoir voir les bases des tests fonctionnels avec Playwright.
Vous pouvez retrouver le code source juste ici : Github du projet.

Pour valider cette application, nous allons tester les points suivants :

  • Afficher la page
  • Vérifier le lien de la page
  • Vérifier le Titre
  • Vérifier le contenu du texte
  • Vérifier le texte du bouton
  • Vérifier le clic sur le bouton
  • Attendre
  • Vérifier le nouveau texte du bouton

Avec Playwright il est possible de directement exécuter les tests depuis l’éditeur de code, par exemple vscode, et de voir quelles lignes du fichier fonctionnent et quelles lignes échouent, avec à chaque fois le temps d’exécution en millisecondes.

Lancement du projet

1 – Installation de NPM pour le projet

Maintenant, lancez votre terminal et allez dans le dossier racine de votre projet. Ensuite, vous utiliserez la commande suivante :

				
					[root@localhost] # | npm install
				
			

Cette commande va permettre d’installer toutes les dépendances (paquets) nécessaires pour l’utilisation de votre projet.

2 – Exécution du projet

				
					[root@localhost] # | npm start
				
			

Cette commande va vous permettre de démarrer votre serveur et par conséquent pouvoir afficher votre projet. Le lien de votre projet sera automatiquement ‘localhost:3000’.

Installation de Playwright

1 – Installation avec les extensions VS Code

Recherchez Playwright dans les extensions VS code et cliquez sur installer.

2 – Installation par commande

Depuis un nouveau terminal :

				
					[root@localhost] # | npm install --global yarn
				
			

Si yarn n’est pas installé sur votre machine, faites la commande ci-dessus.

				
					[root@localhost] # | npm init playwright@latest
				
			

Exécutez la commande ci-dessus depuis le répertoire de votre projet. Pressez enter sur les paramètres par défaut qui vous sont proposé. Playwright va alors s’installer dans votre projet dans les paquets de développement.

Nous allons supprimer le contenu du fichier example.spec.ts afin d’y écrire nos propres test à l’intérieur.

Comme vous voyez ci-dessus, vous devez également supprimer ces quelques lignes dans le nouveau fichier “playwright.config.ts” car dans cet exemple nous n’utiliserons que le navigateur chromium.

Nous avons désormais accès à l’onglet dans vscode, que nous utiliserons pour exécuter nos tests. Vous voyez que nous avons ici accès à tous les fichiers de tests, pour le moment vous n’en avez qu’un seul, example.spec.ts qui est vide, mais nous pourrions avoir autant de fichiers que nous voulons dans le dossier des tests.

Mise en place des tests

Voici ci-dessous une image des 7 grandes parties à comprendre dans playwright :

1) Commandes de lancement. C’est ici que nous choisirons de lancer les tests en mode normal ou en mode debug (pour voir étape par étape), que nous pourrons arrêter les tests ou encore les relancer.

2) Liste des fichiers et des tests qui sont dedans, avec un indicateur à chaque test pour savoir si il est fonctionnel, en attente ou en échec.

3) Fichier en cours de visualisation.

4) Table de contrôle de l’exécution en cours, avec la possibilité de mettre sur pause, d’avancer
étape par étape, de recommencer ou d’arrêter.

5) Code des tests.

6) Visualisation de l’application en même temps que les tests s’exécute, ce qui permet de voir avec
nos yeux quelles actions ont lieu et dans quel ordre.

7) URL de l’application, qui peut changer selon la navigation que l’on ordonne depuis nos tests.

Voici le code que nous allons utiliser pour cet article :

				
					<Fragment className="margin">
   <h1>Hello world</h1>
   <p className="text-test">Ce texte est bleu !</p>
   <button
     onClick={() =>
       this.setState({ buttonClicked: !this.state.buttonClicked })
     }
     className={this.state.buttonClicked ? "button-green" : "button-red"}
   >
     {this.state.buttonClicked ? "Activé" : "Désactivé"}
   </button>
</Fragment>
				
			

Auquel nous allons rajouter des attributs pour retrouver les éléments plus facilement depuis les tests (attributs nommés data-cy dans cet exemple) :

				
					<Fragment className="margin">
  <h1 data-cy="helloworld">Hello world</h1>
  <p data-cy="colortext" className="text-test">
    Ce texte est bleu !
  </p>
  <button
    data-cy="thebutton"
    onClick={() =>
      this.setState({ buttonClicked: !this.state.buttonClicked })
    }
    className={this.state.buttonClicked ? "button-green" : "button-red"}
  >
    {this.state.buttonClicked ? "Activé" : "Désactivé"}
  </button>
</Fragment>
				
			

Et voici le code CSS du texte bleu :

				
					.text-test {
  color: blue;
}
				
			

1 – Afficher la page

Premier test du fichier : se rendre sur la page de l’application

				
					test.describe("EXEMPLE TESTS", () => {
test("Should go to home page", async () => {
  await page.goto("http://localhost:3000/");

  await expect(await page.url()).toBe("http://localhost:3000/");
});
				
			

Dans le code du fichier, une fonction test.describe() représentant un groupe d’actions à tester dans cette fonctionnalité, par exemple « Check that all colors are availables »,

On découpe le describe en test(), qui vont eux représenter une seule action, par exemple « Change the color to blue » qui pourrait comprendre quatre lignes de code :

Une pour ouvrir la liste des couleurs possibles via un clic,
Une pour cliquer sur la couleur demandée,
Une pour valider la nouvelle couleur en cliquant sur valider,
Une pour regarder si la couleur est bien passée au bleu.

Ici, await page.goto(“http://localhost:3000/”); nous dirigera vers le lien de l’appli  http://localhost:3000/

await expect(await page.url()).toBe(“http://localhost:3000/”); vérifiera que l’url a bien était atteint.

2 – Vérifier le titre – Test sur le texte

Ci-dessous nous testons si dans la page, l’élément identifié par le data-cy de valeur « helloworld » contient bien le texte « Hello world ».

				
					test("Should see 'Hello World'", async () => {
   await expect(
       await page.locator("[data-cy=helloworld]")
   ).toContainText("Hello world");
});
				
			

En cas d’élément introuvable, par exemple si l’on recherche l’attribut data-cy de valeur « bonjourworld » qui n’existe pas, nous aurons une erreur :

En cas d’élément trouvable mais ne contenant pas le bon texte, si nous cherchons « Hello monde » par exemple, nous aurons une erreur également :

Si l’élément existe et que son texte est le bon :

3 – Vérifier le texte – Test sur la couleur

				
					test("Should see a blue 'Ce texte est bleu'", async () => {
  await expect(
      await page.locator("[data-cy=colortext]")
  ).toContainText("Ce texte est bleu !");

  const txt = page.locator(".text-test");
  const color = await txt.evaluate((ele) => {
      return window.getComputedStyle(ele).getPropertyValue("color");
  });
  expect(color).toBe("rgb(0, 0, 255)");
});
				
			

Ici nous testons si dans la page, l’élément identifié par le data-cy de valeur « colortext » contient bien le texte « Ce texte est bleu » et possède bien l’attribut CSS « color » à la valeur « rgb(0, 0, 255) ».

Nous allons récupérer la propriété CSS « color » de l’élément possèdent la classe « text-test », puis nous allons tester si sa valeur correspond bien à une couleur bleue.

Si par exemple nous recherchons la couleur RGB 0 0 250 au lieu de 0 0 255 -> erreur :

Erreur corrigée :

4 – Vérifier le bouton – Test du clic

				
					test("Check button activé désactivé", async () => {
    await expect(
await page.locator("[data-cy=thebutton]")
    ).toContainText("Désactivé");

    await page.locator("[data-cy=thebutton]").click();

    await new Promise((f) => setTimeout(f, 1000));

    await expect(
await page.locator("[data-cy=thebutton]")
    ).toContainText("Activé");

  });
				
			

Ici nous testons si dans la page, l’élément identifié par le data-cy de valeur « thebutton » contient bien le texte « Désactivé ». Nous essayons ensuite de cliquer dessus, puis attendre 1 seconde (pour simuler un élément qui met du temps à s’actualiser), puis vérifier si sa valeur a bien changé pour « Activé ».

Si par exemple nous cliquons sur le texte bleu (d’attribut colortext) au lieu de cliquer sur le bouton, le texte de ce dernier ne changera pas, et le test échouera :

Erreur corrigée :

Code complet :

				
					import { expect, Page, test } from "@playwright/test";
import { BADHINTS } from "dns";

let page: Page;

test.beforeAll(async ({ browser }) => {
  page = await browser.newPage();
});

test.afterAll(async () => {
  await page.close();
});

test.describe("EXEMPLE TESTS", () => {
  test("Should go to home page", async () => {
    await page.goto("http://localhost:3000/");

    await expect(await page.url()).toBe("http://localhost:3000/");
  });

  test("Should see 'Hello World'", async () => {
    await expect(await page.locator("[data-cy=helloworld]")).toContainText(
      "Hello world"
    );
  });

  test("Should see a blue 'Ce texte est bleu'", async () => {
    await expect(await page.locator("[data-cy=colortext]")).toContainText(
      "Ce texte est bleu !"
    );

    const txt = page.locator(".text-test");
    const color = await txt.evaluate((ele) => {
      return window.getComputedStyle(ele).getPropertyValue("color");
    });

    expect(color).toBe("rgb(0, 0, 255)");
  });

  test("Check button activé désactivé", async () => {
    await expect(await page.locator("[data-cy=thebutton]")).toContainText(
      "Désactivé"
    );

    await page.locator("[data-cy=thebutton]").click();

    await new Promise((f) => setTimeout(f, 1000));

    await expect(await page.locator("[data-cy=thebutton]")).toContainText(
      "Activé"
    );
  });
});

				
			

Conclusion

Vous avez maintenant les connaissances pour débuter vos premiers tests fonctionnels sur vos applications. 

Cet article n’a fait qu’effleurer la surface des fonctionnalités de Playwright, pour ceux qui veulent aller plus loin, voici le lien vers la Documentation ICI. 

Si vous avez besoin de tests fonctionnels automatisés pour vos sites ou applications : n’hésitez pas à contacter IE-Concept, il y a dans notre équipe 3 personnes expérimentées dans ce domaine. Avoir une bonne couverture de tests reste la meilleur solution pour assurer la qualité de vos applications !