Tests end-to-end avec Playwright
Cas d'usage : tester son module Magento 2
Introduction
Tester un module Magento 2 de bout en bout avec un outil comme Playwright présente plusieurs avantages :
- Validation de l'expérience utilisateur (UX) : Les tests de bout en bout permettent de s'assurer que l'expérience utilisateur de votre site web Magento 2 fonctionne correctement. Playwright peut automatiser des actions telles que la navigation, le remplissage de formulaires, la sélection de produits, le paiement, etc., pour vérifier que tout se passe comme prévu du point de vue de l'utilisateur.
- Identification des problèmes de fonctionnalité : En testant l'ensemble du flux utilisateur, vous pouvez identifier les problèmes de fonctionnalité qui pourraient survenir lorsque les différentes parties de votre module Magento 2 interagissent entre elles. Cela permet de détecter les bugs et de les corriger avant qu'ils n'affectent les clients.
- Assurance qualité (QA) : Les tests de bout en bout font partie intégrante de l'assurance qualité (QA) pour garantir que votre module Magento 2 répond aux normes de qualité et fonctionne correctement. Cela peut aider à éviter les retours clients, les problèmes de réputation et les pertes de ventes.
- Réduction des erreurs humaines : L'automatisation des tests avec Playwright permet de réduire les erreurs humaines potentielles lors de la vérification manuelle de chaque fonctionnalité. Les tests automatisés sont également reproductibles et peuvent être exécutés à tout moment.
- Gain de temps : Les tests automatisés permettent de gagner du temps par rapport à la vérification manuelle, surtout lorsque vous devez effectuer des tests de regression à chaque mise à jour de votre module. Cela permet d'accélérer le processus de développement.
- Support de différents navigateurs : Playwright prend en charge plusieurs navigateurs, ce qui vous permet de tester votre module Magento 2 sur différentes plateformes et de vous assurer qu'il fonctionne correctement pour tous les utilisateurs, quelle que soit leur configuration.
- Intégration dans un processus de CI/CD : Vous pouvez intégrer les tests de bout en bout avec Playwright dans votre processus de livraison continue (CI/CD) pour automatiser la validation de votre module à chaque nouvelle version ou mise à jour, assurant ainsi une meilleure stabilité du produit final.
Expérience personnelle
Merci ChatGPT, je n'aurais pas dit mieux. Pour la suite, je vais essayer d'écrire moi-même, pour rendre le sujet un peu plus humain, même s'il faut bien avouer que les tests automatisés, c'est plutôt une affaire de robots.
Je souhaite partager ici mon expérience et donner un aperçu de ma façon d'utiliser Playwright pour tester des modules Magento 2.
Bien sûr, la mise en place de tels tests prend du temps, surtout pour le premier module testé. Mais une fois qu'on l'a fait pour un module, c'est souvent assez facilement transposable et la satisfaction de savoir que son module fonctionne (au moins dans la limite des tests qu'on a écrits) mérite bien, à mon avis, de prendre ce temps.
En résumé, les étapes à répéter sont quasiment toujours les mêmes :
- étape 1 : Installer Magento 2
- étape 2 : Activer le module
- étape 3 : Tester le module de bout en bout :
- étape 3-1 : Se rendre dans le back office pour activer la ou les fonctionnalités apportées par le module
- étape 3-2 : Exécuter différentes actions en front ou backend et s'assurer que le résultat est conforme au résultat attendu
- Refaire les étapes 3-1 et étapes 3-2 en modifiant d'éventuelles configurations, aussi souvent que nécessaire.
Éventuellement, on pourra refaire étapes 1,2 et 3 en modifiant certains paramètres de l'environnement de test: versions de PHP, Nginx, Apache, Varnish, etc.
Ce n'est pas le but premier de cet article mais, comme toutes les étapes sont scriptables et que Playwright est utilisable en mode "headless", ces tests pourront faire l'objet d'une automatisation CI/CD. Dans la conclusion, vous trouverez un lien vers une de mes actions GitHub à titre d'exemple.
Ce qui nous intéresse ici est surtout l'étape 3 :
Tester un module avec Playwright
Installation de Playwright
Pour installer Playwright, lire la documentation de Playwright est certainement la meilleure chose à faire.
Personnellement, pour le premier module testé, j'ai crée un dossier Test/EndToEnd
dans lequel j'ai lancé la commande :
npm init playwright@latest
Avec cette commande, les navigateurs nécessaires sont téléchargés et les fichiers suivants sont crées :
playwright.config.ts
package.json
package-lock.json
tests/
example.spec.ts
tests-examples/
demo-todo-app.spec.ts
Une fois que c'est fait, on peut commencer à s'amuser en lançant :
- les tests en mode "headless"
npx playwright test
- les tests en mode "headed"
npx playwright test --headed
- les tests avec l'UI Playwright
npx playwright test --ui
Le fichier playwright.config.ts
est à mon avis le plus important et on peut trouver un aperçu des paramétrages possibles dans la documentation.
Pour la mise en place dans d'autres modules, je me contente souvent de récupérer ce fichier de configuration que j'ai modifié selon mes besoins, le package.json
et quelques autres fichiers mutualisables puis de lancer un yarn install
dans le dossier.
Écrire un test
Comme l'indique la documentation , un test est uniquement l’enchaînement des deux opérations suivantes :
- exécuter une action : visite une page, cliquer sur un bouton, remplir un formulaire, etc.
- valider une assertion : vérifier qu'un contenu est présent sur la page, vérifier qu'une url contient le bon paramètre, etc.
Pour faciliter l'écriture des actions, Playwright dispose d'une commande codegen
très pratique :
npx playwright codegen
Avec cette commande, un navigateur s'ouvre et chacune de vos actions est transcrite dans une fenêtre "Playwright Inspector". Il ne vous reste plus qu'à copier-coller tout ça pour que votre test réalise exactement les mêmes actions.
Par exemple, la capture d'écran ci-dessous montre l’enchaînement suivant :
Pour avoir une idée des possibilité d'assertions: https://playwright.dev/docs/test-assertions.
Organisation du code : Page Object Model et Fixtures
Ce que je viens de décrire plus haut suffit largement pour être capable de tester son module. Mais si on souhaite organiser son code pour qu'il soit plus rapidement réutilisable, on pourra intégrer les concepts de Page Object Model et de Fixtures.
L'idée de base du Page Object Model
est de se dire qu'à chaque page visitable doit correspondre un objet, avec quelques propriétés et méthodes nécessaires aux tests.
Concernant le principe de Fixtures
, il a pour but de maîtriser l'environnement de départ (jeu de données, configuration, etc.) de chaque test ou groupe de tests.
Si vous êtes vraiment motivés, vous pourriez aboutir à un code qui ressemble à celui de ce repo Cypress avec des jolis dossiers de fixtures et de pages-objects, et leurs déclinaisons éventuelles par thèmes (Luma, Hyva, etc.). Désolé, cet exemple est basé sur Cypress, le "concurrent" de Playwright mais le principe reste le même et je n'ai pas eu le temps de mettre en place une arborescence aussi propre pour le moment.
Je mettrais quelques liens vers mes projets en cours et vous pourrez regarder mes dossiers de fixtures et de page-objects, beaucoup moins fournis mais cohérents avec mes besoins.
À titre d'exemple, la page de login du back office est une excellente candidate pour devenir une "page-objet". En effet, on est obligatoirement amener à s'y rendre si on souhaite configurer son module. Ainsi, j'ai crée un objet adminLoginPage avec les méthodes de bases dont les noms et contenus seront, j'espère, assez explicites pour ne pas avoir à les décrire ici :
navigateTo
login
logout
Dans le même esprit, j'ai crée des objets pour la page d'accueil, pour une page produit, pour une page catégorie, pour le tunnel de paiement et pour toutes autres pages qui peuvent me servir dans mes tests, selon les modules.
Comme promis, voici ce que ça donne pour un de mes modules qui n'a besoin que du thème Luma pour une page catégorie et de quelques pages du back office (login, cache, configuration et édition d'une page catégorie) :
Gestion de l'authentification
Comme tous mes tests nécessitent de se connecter au back office, j'ai mis en place une des stratégies proposées par Playwright pour stocker et réutiliser les cookies qui gèrent l'authentification.
Chaque test étant exécuté dans un contexte isolé (équivalent d'un nouveau navigateur en navigation privée), cette étape est nécessaire pour ne pas devoir se re-connecter avant chaque nouveau test du projet.
Pour cela, on modifie le fichier playwright.config.ts et on fait on fait dépendre tout nos groupes de tests (appelés projets) d'un projet "setup" dans lequel :
- on visite la page de connexion
adminLoginPage
. - On saisit les login/mot de passe de notre utilisateur de test.
- On se connecte et on sauvegarde l'état d’authentification dans un fichier json.
Ainsi, tout groupe de test sera précédé par la connexion à l'admin :
Cas d'usage : Okaeli_RoundPricesCut
Le module Okaeli_RoundPricesCut a pour but d'afficher les prix ronds sans les décimales.
Par défaut, un prix de 15,00€ est affiché 15,00€
. Ce module permet d'afficher 15€
: rien de révolutionnaire mais c'est une fonctionnalité qu'on m'a très souvent demandée lorsque je travaillais en agence web. Alors j'en ai fait un module.
Bien que simples, les tests manuels sont fastidieux et rébarbatifs : on doit s'assurer que ça fonctionne sur les pages catégories, sur les pages produits, pour les options de prix des produits configurables, lors du processus d'achat, etc.
Je ne détaillerai ici que les tests sur les produits configurables et le test du processus d'achat car ils donnent à mon avis une bonne idée de l'ensemble.
Pré-requis
Afin d'avoir toujours le même jeu de test, j'installe certaines données de test Magento :
bin/magento setup:performance:generate-fixtures setup/performance-toolkit/profiles/ce/small.xml
Test de la page du produit configurable
Le test consiste à se rendre sur la page d'un produit configurable pour tester que tout se déroule comme prévu:
- si la fonctionnalité est activée, les prix ronds doivent s'afficher sans décimales
- si la fonctionnalité est désactivée, les prix ronds doivent s'afficher avec les décimales
Dans ce but, on peut créer un objet ConfigurableProductOnePage
qui représente la page d'un produit configurable:
import { expect, Page } from "@playwright/test";
export default class ConfigurableProductOnePage {
page: Page;
url: string;
constructor(page: Page) {
this.url = "/configurable-product-1.html";
this.page = page;
}
public async navigateTo(check = true) {
await this.page.goto(this.url);
if (check) {
await expect(this.page).toHaveTitle(/Configurable Product 1/);
}
}
}
En pratique, le test est composé de plusieurs sous tests:
-
Préparation du test
- on se connecte au back office (setup vu plus haut)
-
Test 1 : on s'assure qu'on peut paramétrer les configurations du module par défaut
- on se rend sur la page de configuration du module (
Catalog
→Price
dans ce cas) - on active la fonctionnalité sur le front
- on vide le cache
- on se rend sur la page de configuration du module (
Au niveau du code, ça ressemble à ça :
test("can set default config", async ({
adminOkaeliRoundPricesConfigPage,
adminCachePage,
}) => {
await adminOkaeliRoundPricesConfigPage.setDefaultConfig();
await adminCachePage.navigateTo();
await adminCachePage.flushMagentoCache();
});
- Test 2 : Visite de la page produit avec la fonctionnalité activée
- on se rend sur la page produit avec un prix de base rond
- on vérifie que l'affichage du prix est cohérent (pas de décimales)
- on change l'option (option prix rond)
- on vérifie que l'affichage du prix est cohérent (pas de décimales)
- on change l'option (option prix non rond)
- on vérifie que l'affichage du prix est cohérent (les décimales sont présentes)
Le code associé à ce test est le suivant :
test("can see rounded prices on configurable product", async ({
configurableProductOnePage,
page,
}) => {
await configurableProductOnePage.navigateTo();
await expect(page.locator(".product-info-price")).toHaveText(/\$1/);
await expect(page.locator(".product-info-price")).not.toHaveText(/\$1.00/);
await page.locator("select").selectOption({ index: 1 });
await expect(page.locator(".product-info-price")).toHaveText(/\$5/);
await expect(page.locator(".product-info-price")).not.toHaveText(/\$5.00/);
await page.locator("select").selectOption({ index: 8 });
await expect(page.locator(".product-info-price")).toHaveText(/\$9.99/);
});
- Test 3 : Visite de la page produit avec la fonctionnalité désactivée
- on se rend sur la page de configuration du module
- on désactive la fonctionnalité sur le front
- on vide le cache
- on refait les mêmes tests que le Test 2 en s'attendant à des résultats différents
Comme d'habitude, voici le code associé:
test("can disable rounded prices on configurable product", async ({
adminCachePage,
adminOkaeliRoundPricesConfigPage,
configurableProductOnePage,
page,
}) => {
await adminOkaeliRoundPricesConfigPage.disableFront();
await adminCachePage.navigateTo();
await adminCachePage.flushMagentoCache();
await configurableProductOnePage.navigateTo();
await expect(page.locator(".product-info-price")).toHaveText(/\$1.00/);
await page.locator("select").selectOption({ index: 1 });
await expect(page.locator(".product-info-price")).toHaveText(/\$5.00/);
await page.locator("select").selectOption({ index: 8 });
await expect(page.locator(".product-info-price")).toHaveText(/\$9.99/);
});
Si des erreurs sont détectées, on pourra éventuellement consulter un rapport en lançant :
npx playwright show-report
Test du processus d'achat
Pour voir un test un peu plus complet, je terminerai ici avec le test de l'affichage des prix lors d'un processus d'achat.
Comme pour le test de la page produit, il y a une étape de préparation, un test de configuration, puis deux tests du parcours d'achat : un avec la fonctionnalité activée et un avec la fonctionnalité désactivée.
Je ne présente ici rapidement que le test avec la fonctionnalité activée :
- on se rend sur la page produit simple
- on l'ajoute au panier
- on vérifie les prix dans le mini panier
- on va au tunnel de paiement ("proceed to checkout")
- on vérifie que les prix sont bien affichés
- on remplit les infos de livraison
- On passe à l'étape suivante (paiement)
- On vérifie que les prix sont bien affichés : prix du produit, frais de port, sous-total, total)
N.B : La durée entre chaque action a été volontairement ralenti ici pour qu'on puisse comprendre un peu ce qui se passe. En réalité, le test est bien plus rapide.
Conclusion
Cette présentation ne fait que survoler l'étendue des possibilités de Playwright. J'espère quand même qu'elle vous sera utile si jamais vous souhaitez donner une chance à cet outil.
Comme annoncé plus haut, vous trouverez ici un exemple d'action GitHub dans lequel j'installe un module Magento 2 et lance les tests Playwright.