Test de navigateur automatisé avec l'API WebDriver

Publié: 2022-03-10
Résumé rapide ↬ Cet article donne un aperçu des concepts, technologies et techniques de codage impliqués dans l'exécution automatique de scripts de test sur des navigateurs à l'aide de WebDriverJS sur Windows 10 et Microsoft Edge.

Cliquer manuellement sur différents navigateurs pendant qu'ils exécutent votre code de développement, localement ou à distance, est un moyen rapide de valider ce code. Il vous permet d'inspecter visuellement que les choses sont telles que vous les vouliez du point de vue de la mise en page et des fonctionnalités. Cependant, ce n'est pas une solution pour tester l'ensemble de la base de code de votre site sur l'assortiment de navigateurs et de types d'appareils disponibles pour vos clients. C'est là que les tests automatisés prennent tout leur sens.

Mené par le projet Selenium, le test Web automatisé est une suite d'outils permettant de créer, de gérer et d'exécuter des tests sur les navigateurs sur toutes les plates-formes.

API WebDriverJS

L'API WebDriver est une norme qui extrait les liaisons spécifiques à l'appareil/au navigateur du développeur afin que les scripts de test écrits dans la langue de votre choix puissent être écrits une seule fois et exécutés sur de nombreux navigateurs différents via WebDriver. Certains navigateurs ont des fonctionnalités WebDriver intégrées, d'autres nécessitent que vous téléchargiez un binaire pour votre combinaison navigateur/OS.

api webdriverjs

Piloter le navigateur via les API WebDriver

La spécification WebDriver du W3C documente les API disponibles pour les développeurs pour contrôler par programmation le navigateur. Ce diagramme montre un exemple de page avec certaines des collections générales WebDriver et des API qui peuvent être utilisées pour obtenir et définir les propriétés du navigateur.

api webdriverjs

Création de tests

Vous avez le choix entre plusieurs langues en fonction des liaisons de langue prises en charge pour WebDriver. Les langages de base pris en charge par le projet principal Selenium/WebDriverJS incluent :

  • C#
  • Java
  • JavaScript (via nœud)
  • Python
  • Rubis
Plus après saut! Continuez à lire ci-dessous ↓

Les tests peuvent varier de la vérification de la mise en page de la page, des valeurs renvoyées par les appels côté serveur, du comportement attendu de l'interaction de l'utilisateur à la vérification du flux de travail, comme s'assurer qu'un flux de travail de panier fonctionne comme prévu.

À des fins d'illustration, supposons que nous testons l'application TODOMVC, une application de démonstration implémentée dans plusieurs frameworks JavaScript modèle-vue-contrôle différents. Cette application simple fournit une interface utilisateur pour saisir des éléments à faire, modifier, supprimer et marquer des éléments comme terminés. Nous utiliserons l'exemple basé sur React sur https://todomvc.com/examples/react/.

Nous pourrons ensuite démontrer l'exécution des tests pour l'exemple React par rapport aux exemples Backbone.js et Vue.js en changeant simplement l'URL.

  • L'essentiel du fichier d'exemple JS complet

Pour cette démonstration, nous allons écrire des tests en JavaScript s'exécutant dans node pour :

  1. Ajoutez trois éléments à faire et vérifiez que ce que nous avons tapé a été créé dans un élément à faire.
  2. Modifiez cet élément en double-cliquant, en envoyant des commandes clavier de retour arrière et en ajoutant plus de texte.
  3. Supprimez cet élément à l'aide des API de la souris.
  4. Cochez un élément de la liste comme terminé.

Configuration de votre environnement de test d'automatisation de base

Commençons par configurer notre machine Windows 10 pour exécuter WebDriver en utilisant JavaScript. Les appels à WebDriver depuis le nœud seront presque toujours asynchrones. Pour rendre le code plus facile à lire, nous avons utilisé async/wait over Promises ou callbacks d'ES2016.

Vous aurez besoin d'installer node.js plus récent que la v7.6 ou d'utiliser Babel pour une compilation croisée afin de prendre en charge la fonctionnalité async/wait. De plus, nous utilisons Visual Studio Code pour l'édition et le débogage du nœud.

WebDriverJS pour Microsoft Edge

Chaque navigateur aura un fichier binaire dont vous aurez besoin localement pour interagir avec le navigateur lui-même. Ce binaire est appelé par votre code via les API Selenium WebDriver. Vous pouvez trouver les derniers téléchargements et la documentation pour Microsoft Edge WebDriver ici.

Notez que la version d'Edge sur laquelle vous souhaitez exécuter les tests doit être testée avec la version correspondante de MicrosoftWebDriver.exe . Nous allons utiliser la version stable d'Edge (16.16299) avec la version 5.16299 correspondante de MicrosoftWebDriver.exe.

Placez le MicrosoftWebDriver.exe dans votre chemin ou dans le même dossier que votre script de test sera exécuté. L'exécution de cet exécutable démarrera une fenêtre de console vous indiquant l'URL et le numéro de port que WebDriverJS attendra pour gérer les demandes à envoyer.

WebDriverJS pour les autres navigateurs

Vous pouvez facilement indiquer à WebDriverJS d'exécuter des tests dans un navigateur différent en définissant une variable de configuration et en installant le pilote binaire approprié pour le navigateur respectif. Vous pouvez les trouver ici:

  • Apple Safari : fourni avec Safari 10+
  • Google Chrome : ChromeDriver
  • Microsoft Internet Explorer : IEDriver du projet Selenium
  • Mozilla Firefox : pilote Gecko
  • Opéra : OperaChromiumDriver

Selenium WebDriverJS pour JavaScript

Pour interagir avec le pilote binaire que vous venez de télécharger via JavaScript, vous devez installer la bibliothèque d'automatisation Selenium WebDriver pour JavaScript. Cela peut être facilement installé en tant que package de nœud en utilisant :

npm install selenium-webdriver

Écrire du code d'automatisation

Une fois que le fichier binaire du pilote spécifique à votre navigateur se trouve dans le chemin ou le dossier local de votre système et que vous avez installé Selenium WebDriver via npm, vous pouvez commencer à automatiser le navigateur via le code.

Décomposons notre exemple de code en différentes étapes dont vous aurez besoin.

  1. Créez une variable locale pour charger et interagir avec la bibliothèque.
     var webdriver = require('selenium-webdriver');
  2. Par défaut, WebDriverJS suppose que vous exécutez localement et que le fichier de pilote existe. Plus tard, nous montrerons comment vous pouvez transmettre des informations de configuration dans la bibliothèque lors de la première instanciation du navigateur. WebDriverJS est instancié avec une variable de configuration appelée "capacities" pour définir le pilote de navigateur que vous souhaitez utiliser.
     var capabilities = { 'browserName': 'MicrosoftEdge' }; var entrytoEdit = "Browser Stack";
  3. Ensuite, vous créez une variable et appelez build() avec la variable de configuration des capacités pour que WebDriverJS instancie le navigateur :
     var browser = new webdriver.Builder().withCapabilities(capabilities).build();
  4. Maintenant que nous pouvons interagir avec le navigateur, nous lui disons de naviguer vers une URL en utilisant la méthode `get`. Cette méthode est asynchrone, nous utilisons donc `wait` pour attendre qu'elle se termine.
     // Have the browser navigate to the TODO MVC example for React await browser.get('https://todomvc.com/examples/react/#');
  5. Pour certains navigateurs et systèmes, il est préférable de laisser le temps au binaire WebDriverJS de naviguer jusqu'à l'URL et de charger la page. Pour notre exemple, nous attendons 1 seconde (1000ms) en utilisant la fonction manage de WebDriverJS :
     //Send a wait to the browser to account for script execution running await browser.manage().timeouts().implicitlyWait(1000);
  6. Vous avez maintenant un crochet programmatique dans un navigateur en cours d'exécution via la variable de navigateur. Notez le diagramme de collection plus haut dans ce document qui montre les collections d'API WebDriver. Nous utilisons la collection Elements pour obtenir des éléments spécifiques de la page. Dans ce cas, nous recherchons la zone de saisie dans l'exemple TODOMVC afin de pouvoir saisir certains éléments TODO. Nous demandons à WebDriverJS de rechercher les éléments qui correspondent à la règle de classe .new-todo car nous savons que c'est la classe affectée à ce champ. Nous déclarons une constante car nous ne pouvons pas modifier les données qui reviennent - il suffit de les interroger. Notez que cela trouvera le premier élément dans le DOM qui correspond au modèle CSS, ce qui est bien dans notre cas car nous savons qu'il n'y en a qu'un.
     const todoEntry = await browser.findElement(webdriver.By.css('.new-todo'));
  7. Ensuite, nous envoyons des frappes au champ que nous venons d'obtenir en utilisant la fonction sendKeys. Nous plaçons la touche d'entrée échappée sur sa propre ligne d'attente pour éviter les conditions de course. Nous utilisons le modèle d'itération for (x of y) car nous traitons des promesses. toDoTestItems est simplement un tableau de 3 chaînes, une variable de chaîne (que nous testerons plus tard) et 2 littéraux. Sous les couvertures, WebDriverJS enverra des caractères individuels de la chaîne un à la fois, mais nous passons simplement la variable de chaîne entière à sendKeys :

     var toDoTestItems = [entrytoEdit, "Test Value1", "Test Value2"]; //Send keystrokes to the field we just found with the test strings and then send the Enter special character for (const item of toDoTestItems) { await todoEntry.sendKeys(item); await todoEntry.sendKeys("\n"); }

À ce stade, exécutons le script avec node et voyons si nous voyons un navigateur qui navigue vers la page et entre ces trois éléments TODO de test. Enveloppez le code après la première déclaration de variable dans une fonction async comme ceci :

 async function run() {

Fermez la fonction } à la fin du code, puis appelez cette fonction asynchrone avec :

 run();

Enregistrez votre fichier JS. Accédez à la fenêtre de commande du nœud, accédez au dossier dans lequel vous avez enregistré le fichier JS et exécutez node yourfile.js

Vous devriez voir une fenêtre de navigateur apparaître et le texte envoyé au fichier TODOMVC être entré en tant que nouvelles entrées TODO dans l'application. Félicitations - vous êtes opérationnel avec WebDriverJS.

Essayez de remplacer l'URL chargée par WebDriverJS dans cet exemple par l'un des autres exemples TODOMVC et observez que le même code de test peut s'exécuter sur différents frameworks.

 await browser.get('https://todomvc.com/examples/vue/');

Exécution de tests sur BrowserStack

Nous avons montré comment ce test s'exécute localement sur votre machine. Le même test peut être exécuté tout aussi facilement en utilisant des services de test en ligne comme BrowserStack. Inscrivez-vous pour un accès gratuit au service BrowserStack afin d'accéder aux navigateurs Microsoft Edge pour des tests gratuits en direct et automatisés. Une fois connecté, accédez à la section "Automatiser" et recherchez les paramètres de votre compte de test automatisé. Vous devrez les transmettre à la fonction WebDriverJS pour vous connecter via le code, nommer votre session de test et transmettre votre jeton d'accès.

Ensuite, ajoutez simplement ces valeurs dans la variable de capabilities et appelez à nouveau le générateur WebDriver.

 var capabilities = { 'browserName': MicrosoftEdge, 'browserstack.user': 'yourusername', 'browserstack.key': 'yqniJ4quDL6s2Ak2EZpe', 'browserstack.debug': 'true', 'build': 'Name your test' }

Vous pouvez en savoir plus sur la variable de capabilities et les valeurs que BrowserStack peut accepter ici.

Appelez ensuite la fonction builder et transmettez l'URL du serveur BrowserStack :

 var browser = new webdriver.Builder(). usingServer('https://hub-cloud.browserstack.com/wd/hub'). withCapabilities(capabilities). build();

Enfin, vous devez demander à WebDriverJS de quitter le navigateur, sinon il continuera à fonctionner et finira par expirer. Placez un appel à la fonction Quitter à la fin de votre fichier de test.

 browser.quit();

Désormais, lorsque vous exécuterez votre fichier de test JS à l'aide de NodeJS, vous enverrez les instructions de test à un navigateur hébergé sur le service cloud de BrowserStack. Vous pouvez accéder à la section "Automatiser" de BrowserStack et observer le démarrage et l'arrêt des tâches de test. Une fois terminé, vous pouvez parcourir les commandes WebDriver qui ont été envoyées, voir des images de l'écran du navigateur à intervalles réguliers pendant le test et même voir une vidéo de la session du navigateur.

Une capture d'écran de la fonction de journal visuel d'un test exécuté sur le service Automate de BrowserStack
Une capture d'écran de la fonction de journal visuel d'un test exécuté sur le service Automate de BrowserStack

Tester des valeurs avec des assertions

Lorsque vous testez votre site, vous comparez les résultats réels aux résultats attendus. La meilleure façon de le faire est d'utiliser des assertions où une exception sera levée si une condition d'assertion n'est pas remplie. Dans notre exemple, nous utilisons une bibliothèque d'assertions pour exprimer ces assertions et aider à rendre le code plus lisible. Nous avons choisi ChaiJS car il est suffisamment flexible pour être utilisé avec n'importe quelle bibliothèque JavaScript et est assez populaire au moment de la rédaction.

Vous téléchargez et installez Chai en tant que package de nœud à l'aide de npm. Dans le code, vous devez exiger chai :

 var expect = require('chai').expect;

Nous avons décidé d'utiliser l'interface Expect pour utiliser le langage naturel pour enchaîner nos assertions.

Vous pouvez tester la longueur, l'existence, contient une valeur et bien d'autres.

 expect(testElements).to.not.have.lengthOf(0); //make sure that we're comparing the right number of items in each array/collection expect(testElements.length).to.equal(toDoTestItems.length);

Si l'une de ces assertions n'est pas vraie, une exception d'assertion est levée. Notre exemple de code cessera de s'exécuter lorsque l'exception est levée car nous ne gérons pas l'exception. En pratique, vous utiliserez un lanceur de test avec un nœud qui gérera les exceptions et signalera les erreurs de test et les réussites.

Automatisation des passes de test avec un Test Runner

Pour mieux gérer les exceptions d'assertion, un exécuteur de test est associé à un nœud pour encapsuler des blocs de code contenant des assertions de test dans des fonctions de style try/catch qui mappent les exceptions aux cas de test ayant échoué.

Dans cet exemple, nous avons choisi le framework de test MochaJS car il se marie bien avec Chai et c'est quelque chose que nous utilisons pour tester notre code de production.

Pour intégrer le coureur, il y a à la fois du code ajouté au script de test et un changement dans la façon dont vous exécutez le code avec node.

Ajout du code du testeur

Vous encapsulez le code de test dans des fonctions asynchrones avec la fonction de niveau supérieur en utilisant le mot-clé "describe" et la fonction de sous-test en utilisant le mot-clé "it". Les fonctions sont balisées avec une description de ce que les tests recherchent. Cette description correspond à ce qui sera mappé aux résultats des tests.

MochaJS est installé en tant que package de nœud via npm.

Voici la fonction de niveau supérieur dans notre exemple utilisant describe :

 describe('Run four tests against TODOMVC sample', async () => {

Ensuite, regroupez vos tests logiques en groupes avec le mot-clé it :

 it('TEST 3: Delete a TODO item from the list by clicking the X button', async () => {

Les assertions enveloppées dans ces fonctions qui provoquent une exception seront mappées à ces descriptions.

Exécuter le code avec NodeJS et MochaJS

Enfin, vous devez exécuter votre code de test avec un nœud appelant le binaire MochaJS pour gérer correctement les exceptions. Mocha peut recevoir des arguments pour configurer les valeurs de délai d'attente, le dossier à rechercher qui contient vos fichiers de test et plus encore. Voici la configuration que nous avons utilisée pour Visual Studio Code pour attacher le débogueur et utiliser l'inspection de Code et parcourir les fonctionnalités :

 { "type": "node", "request": "launch", "name": "Mocha Tests", "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", "args": [ "-u", "tdd", "--timeout", "999999", "--colors", "${workspaceRoot}/test/**/*.js" ], "internalConsoleOptions": "openOnSessionStart" }

Les tests automatisés sont un excellent moyen de s'assurer que votre site fonctionne de manière cohérente sur une variété de navigateurs, sans les tracas ni les coûts des tests manuels. Les outils que nous avons utilisés ici ne sont que quelques-uns des nombreux choix disponibles, mais illustrent les étapes courantes impliquées dans la configuration et l'exécution de tests automatisés pour vos projets.