Une introduction à WebDriver à l'aide des liaisons JavaScript

Dans ce didacticiel, nous examinerons WebDriverJs, un outil utilisé pour l’automatisation du navigateur. Chrome sera utilisé dans tous les cas. Cependant, les navigateurs modernes ont généralement des pilotes disponibles pour une utilisation avec WebDriver (même mobile). Consultez-les si vous souhaitez automatiser d'autres navigateurs..

Alors que les tests unitaires sont certainement utiles pour les applications Web modernes, à un moment donné, au fur et à mesure que votre application se développe, vous remarquerez l'apparition de bugs qui n'étaient pas détectés par un test unitaire mais auraient théoriquement été détectés par un test d'intégration / acceptation.. 

Si vous souhaitez suivre une stratégie de tests impliquant des tests de navigateur, ce guide vous donnera une introduction initiale aux tests avec WebDriverJs afin que vous disposiez de suffisamment de connaissances pour commencer..

Ce tutoriel suppose que vous connaissez JavaScript et que vous pouvez exécuter du code JavaScript à l'aide de node.js..

WebDriverJS

Si vous souhaitez suivre, n'hésitez pas à acheter cet exemple de projet qui contient quelques exemples de WebDriver à exécuter. Vous devrez également installer Chromedriver et l’avoir disponible dans votre chemin..

Selenium WebDriver a généralement un serveur et un client. Hormis les contributeurs WebDriver, la plupart des gens ne s'intéresseront qu'à l'API client, qui leur permet de contrôler un navigateur par le biais de leur script. Pour commencer, installez les liaisons JavaScript pour WebDriver:

npm install sélénium-webdriver

Une fois que vous avez installé ce module via NPM, vous pouvez exiger le module dans votre code de noeud de la manière suivante:

require ('sélénium-webdriver');

Sinon, si vous extrayez le projet exemple, vous pouvez simplement exécuter un npm installer dans le dossier en tant que module WebDriverJs est répertorié comme une dépendance dans le package.json fichier.

Bien que vous puissiez parcourir la documentation officielle, mon préféré est la source elle-même. Ce fichier webdriver.js répertorie de nombreuses méthodes WebDriver, par exemple. vous remarquerez un getAttribute et un getText. Voici quelques méthodes qui pourraient vous intéresser:

  • obtenir - Naviguer le navigateur vers une URL.
  • findElements - Semblable à document.querySelectorAll dans le navigateur.
  • executeScript - Exécuter du JavaScript brut sur la page en cours.
  • getText - Récupère le contenu textuel d'un élément, y compris ses enfants.
  • est affiché - Savoir si un élément est affiché sur la page.

Promesses

Un facteur concernant les liaisons JavaScript pour WebDriver en particulier est que presque toutes les méthodes sont asynchrones. Cela signifie que le code suivant n'obtient pas le titre de la page Web:

var title = browser.getTitle (); // enregistre alors: [Fonction: puis], annule: [Fonction: annule], est en attente: [Fonction: est en attente] console.log (titre);

Au lieu de cela, ce que vous devez faire, c'est ceci:

var promise = browser.getTitle (); promise.then (function (title) console.log (title););

En effet, WebDriverJs utilise des promesses pour rendre le traitement du code asynchrone un peu plus agréable. Notez que l’implémentation de Promise dans WebDriverJs n’est pas conforme à la norme Promises / A +.

L’essentiel à retenir ici est que la plupart des méthodes WebDriver renverront un puis méthode qui accepte deux arguments optionnels (fonction). Le premier argument est un rappel qui peut recevoir une valeur. 

Dans l'exemple ci-dessus, nous avons demandé un titre. Par conséquent, notre rappel recevra ce titre comme premier argument. Le deuxième argument de fonction optionnel que nous pouvons passer à la méthode then nous permet d’attraper les erreurs, le cas échéant..

Exemples

Récapitulons où nous en sommes jusqu'à présent:

  1. Nous avons installé le binaire Chromedriver.
  2. Nous avons installé WebDriverJs via NPM.
  3. Sachant que presque tout est asynchrone, nous savons utiliser les promesses pour récupérer les valeurs souhaitées..

Regardez cet exemple de code:

var webdriver = require ('sélénium-webdriver'); var browser = new webdriver.Builder (). usingServer (). withCapabilities ('browserName': 'chrome'). build (); browser.get ('http://en.wikipedia.org/wiki/Wiki'); browser.findElements (webdriver.By.css ('[href ^ = "/ wiki /"]')). then (fonction (liens) console.log ('Trouvé', links.length, 'Liens de wiki.') navigateur.quit (););

Exécutez l'exemple Wiki comme ceci:

$ node Wiki.js trouvé 367 liens Wiki.

Dans l'exemple de code, les premières lignes sont essentiellement des références passe-partout. Il initialise l'objet de navigateur et spécifie une configuration initiale, telle que le navigateur à utiliser. En commençant par l'appel à browser.get, nous avons le code qui nous intéresse vraiment.

  1. D'abord, nous naviguons vers une page Wikipedia.
  2. Nous construisons un sélecteur CSS qui correspond aux éléments ayant un attribut href et une valeur commençant par / wiki / (par exemple, des liens wiki internes)..
  3. Toujours sur la même ligne que l’étape 2, nous passons le sélecteur CSS dans le findElements méthode qui va aller de l'avant et évaluer de manière asynchrone l'expression de sélecteur.
  4. Pour observer les mises à jour de la promesse, nous passons une fonction de rappel à la méthode then.
  5. Le premier argument du rappel est un tableau d’éléments correspondants. Nous le récupérons et enregistrons la longueur..
  6. Enfin, nous avons quitté le navigateur.

Trouver des éléments sur la page est une pièce du puzzle. Jetons un coup d’œil à un autre exemple qui montre comment effectuer une recherche Google et cliquer sur le résultat que nous espérons voir apparaître sur la page..

/ * * Effectuer une recherche Google * / "use strict"; var webdriver = require ('sélénium-webdriver'); var browser = new webdriver.Builder (). usingServer (). withCapabilities ('browserName': 'chrome'). build (); function logTitle () browser.getTitle (). then (function (title) console.log ('Titre de la page actuelle:' + titre););  fonction clickLink (lien) link.click ();  function handleFailure (err) console.error ('Une erreur s'est produite \ n', err.stack, '\ n'); closeBrowser ();  function findTutsPlusLink () return browser.findElements (webdriver.By.css ('[href = "http://code.tutsplus.com/"]'))). then (function (result) return result [0] ;);  function closeBrowser () browser.quit ();  browser.get ('https://www.google.com'); browser.findElement (webdriver.By.name ('q')). sendKeys ('tuts + code'); browser.findElement (webdriver.By.name ('btnG')). click (); navigateur.wait (findTutsPlusLink, 2000) .then (clickLink) .then (logTitle) .then (closeBrowser, handleFailure);

Exécuter le code ci-dessus:

$ node GoogleSearch.js Titre de la page actuelle: Tuts + Code Tutorials

Quelques extraits intéressants sont présentés ici. Premièrement, nous pouvons avoir une idée de ce que ça fait d’utiliser des déclarations de fonction - au lieu des rappels de fonction anonymes (qui sont passés à puis), le résultat est quelque chose comme une API fluide (voir la dernière ligne). De plus, comme nous sommes en mesure de créer des promesses personnalisées (différées), nous pouvons parler aussi couramment que nous le souhaitons.! 

Notez que nous attachons un rappel d'erreur lors du dernier appel à puis, même si une erreur survient plus tôt, ça va encore se propager.

Nous accédons à la page d'accueil de Google et recherchons "tuts + code". Étant donné que nous opérons sur l’objet de navigateur, le mécanisme interne de contrôle du flux de WebDriver sait que chaque commande doit être programmée pour se dérouler l’une après l’autre. findElement, l'un après l'autre, sans avoir à être enchaînés.

Attendre

Lorsque nous effectuons la recherche Google à partir de la page d'accueil, il n'y a pas de rechargement de page. WebDriver essaiera immédiatement de rechercher les éléments que nous avons indiqués dans la page de résultats de recherche. Savoir quand attendre des éléments est une partie essentielle de l'automatisation du navigateur. 

La vieille et méchante façon de faire les choses était d’utiliser un dormir. Étant donné que le moment où un élément apparaît peut fortement dépendre de facteurs externes (par exemple, la vitesse de connexion réseau), les développeurs peuvent parfois demander à WebDriver d'attendre un laps de temps déterminé avant de continuer. Ceci, bien sûr, est criblé de problèmes. 

Heureusement, le attendre Cette méthode rend l’automatisation des pages Web modernes bien plus agréable. Vous appelez wait avec deux arguments, le premier est une fonction qui doit être évaluée à true par une période définie comme second argument à attendre. WebDriver appelle régulièrement votre rappel jusqu'à ce qu'il renvoie true ou que le temps soit écoulé, auquel cas une erreur est générée..

Modification du navigateur

Bien qu'il existe de nombreuses méthodes pour appeler le contexte des éléments DOM, vous pouvez également appeler des méthodes sur le navigateur lui-même pour vous donner davantage de contrôle sur l'état du navigateur. Voici quelques exemples simples pour vous donner une meilleure idée:

Définir les dimensions de la fenêtre du navigateur

browser.manage (). window (). setSize (1280, 720)

Connectez le navigateur à un proxy:

var proxy = require ('sélénium-webdriver / proxy'); browser = new webdriver.Builder () .usingServer () .withCapabilities ('browserName': 'chrome') .setProxy (proxy.manual (http: '127.0.0.1:9000')) .build ();

Vous pouvez également lire, écrire et supprimer des cookies, prendre une capture d’écran de la fenêtre, définir certains paramètres de navigateur, etc..

Options alternatives

Un certain nombre d'options sont disponibles lorsque vous souhaitez contrôler un navigateur par programme. Tout d’abord, nous avons examiné les liaisons JavaScript pour WebDriver, mais il en existe d’autres:

  • Java
  • Python
  • Rubis
  • PHP

WebDriverJs, par exemple la version que nous avons installée en utilisant npm install sélénium-webdriver n'est qu'une version d'une API client WebDriver écrite en JavaScript. Si vous souhaitez contrôler les navigateurs via un programme via JavaScript, il existe également d'autres options:

  • WD.js - API fluide utilisant des promesses + chaînage.
  • Leadfoot - Maintenant utilisé par la dernière version de Intern.
  • WebDriver.io - contient de la documentation à utiliser avec les frameworks BDD / TDD.
  • Testium - A une documentation claire sur exactement ce qui est pris en charge.
  • DalekJS - Un site Web amusant avec de jolis commentaires lors de l'exécution de tests. Beaucoup de DalekJS ont été divisés en modules qui peuvent être trouvés sur Github.
  • Nightwatch - Un autre outil avec de jolis commentaires et une API fluide.
  • Webdriver-sync - Version synchrone de l'interaction avec WebDriver.

Utiliser quelque chose comme WD.js ou Nightwatch peut signifier plusieurs choses:

  • Différentes API avec lesquelles interagir. Si les liaisons JavaScript sélénium-webdriver officielles ont une API que vous n’êtes pas habituée, consultez les autres options ci-dessus..
  • Rétroaction alternative - cela peut être au niveau du rapporteur, mais aussi simplement ce que vous voyez dans le terminal après l'échec d'un test localement.

Conclusion

Si vous souhaitez commencer à utiliser WebDriver à des fins de test, c'est très bien. Vous devez également garder à l'esprit que l'automatisation du navigateur ne doit pas s'arrêter aux tests, pourquoi ne pas automatiser une tâche répétitive? 

Par exemple, consultez cet article sur Getting to Philosophy, qui explique essentiellement comment cliquer continuellement sur le premier lien dans les articles de Wiki vous mènera finalement à l'article sur la philosophie! 

Cela en fait une tâche amusante à automatiser! Commander ce gif animé ou la source pour le voir en action.