In deze zelfstudie bekijken we WebDriverJs, een tool die wordt gebruikt voor browserautomatisering. Chrome wordt overal gebruikt, hoewel moderne browsers over de neiging beschikken om beschikbare stuurprogramma's voor gebruik met WebDriver (zelfs mobiel) te gebruiken, dus controleer ze als u andere browsers wilt automatiseren.
Hoewel unit-tests zeker waardevol zijn voor moderne webapplicaties, zul je op een bepaald moment, naarmate je applicatie groeit, bugs tegenkomen die niet door een unit-test werden gepakt, maar theoretisch door een integratie- / acceptatietest zouden zijn betrapt.
Als u een teststrategie wilt volgen die browsertests omvat, geeft deze gids u een eerste inleiding tot testen met WebDriverJs, zodat u voldoende kennis heeft om aan de slag te gaan.
In deze zelfstudie wordt ervan uitgegaan dat u bekend bent met JavaScript en JavaScript-code kunt uitvoeren met node.js.
Als u mee wilt doen, kunt u dit voorbeeldproject uitchecken dat enkele WebDriver-voorbeelden bevat die u kunt uitvoeren. U moet Chromedriver ook installeren en op uw pad beschikbaar hebben.
Selenium WebDriver heeft meestal een server en een client. Afgezien van de bijdragen van WebDriver, zullen de meeste mensen alleen geïnteresseerd zijn in de client-API waarmee ze via hun script een browser kunnen besturen. Installeer de JavaScript-bindingen voor WebDriver om aan de slag te gaan:
npm installeer selenium-webdriver
Zodra u die module via NPM hebt geïnstalleerd, kunt u de module in uw knooppuntcode als volgt nodig hebben:
require ( 'selenium-WebDrive');
Als alternatief, als u het voorbeeldproject bekijkt, kunt u gewoon een npm installeren
in de map als de WebDriverJs-module wordt vermeld als een dependance in de package.json
het dossier.
Terwijl je door de officiële documentatie kunt bladeren, is mijn persoonlijke favoriet de bron zelf. Dit bestand webdriver.js bevat een groot aantal WebDriver-methoden, bijvoorbeeld je zult een getAttribute en een getText opmerken. Hier zijn enkele methoden die van belang kunnen zijn:
krijgen
- Navigeer door de browser naar een URL.findElements
- Gelijkwaardig aan document.querySelectorAll
in de browser.executeScript
- Voer raw JavaScript uit op de huidige pagina.getText
- Verkrijg de tekstinhoud van een element inclusief zijn kinderen.is weergegeven
- Zoek uit of een element op de pagina wordt weergegeven.Een aspect van de JavaScript-bindingen voor met name WebDriver is dat bijna elke methode asynchroon is. Dit betekent dat de volgende code niet echt de titel van de webpagina krijgt:
var title = browser.getTitle (); // logs then: [Function: then], cancel: [Function: cancel], isPending: [Function: isPending] console.log (title);
In plaats daarvan wat u moet doen, is dit:
var promise = browser.getTitle (); promise.then (functie (titel) console.log (title););
Dit komt omdat WebDriverJs beloften gebruikt om het omgaan met asynchrone code een beetje aangenamer te maken. Merk op dat de implementatie van de belofte als onderdeel van WebDriverJs niet exact overeenkomt met de Promises / A + -standaard.
Het belangrijkste om hier weg te nemen, is dat de meeste WebDriver-methoden a terugkeren dan
methode die twee optionele (functie) argumenten accepteert. Het eerste argument is een callback die mogelijk een waarde ontvangt.
In het bovenstaande voorbeeld hebben we om een titel gevraagd, daarom ontvangt onze callback die titel als het eerste argument. Het tweede optionele functieargument dat we kunnen doorgeven aan de toenmalige methode stelt ons in staat om fouten te vangen, of helemaal niet.
Laten we samenvatten waar we tot nu toe zijn:
Bekijk dit codevoorbeeld:
var webdriver = require ('selenium-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 (functie (links) console.log ('Found', links.length, 'Wiki-links.') browser.quit (););
Voer het Wiki-voorbeeld als volgt uit:
$ node Wiki.js Gevonden 367 Wiki-links.
In het codevoorbeeld zijn de eerste paar regels in wezen boilerplate. Het initialiseert het browserobject en specificeert een initiële configuratie, zoals welke browser daadwerkelijk gebruikt. Beginnend met de oproep naar browser.get
, we hebben de code waar we echt om geven.
findElements
methode die doorgaat en asynchroon de selectorexpressie evalueert.Het vinden van elementen op de pagina is een stukje van de puzzel, laten we een ander voorbeeld bekijken dat aantoont dat we een Google-zoekopdracht uitvoeren en klikken op het resultaat dat we op de pagina verwachten te zijn.
/ * * Voer een Google-zoekopdracht * / "gebruik strikt" uit; var webdriver = require ('selenium-webdriver'); var browser = new webdriver.Builder (). usingServer (). withCapabilities ('browserName': 'chrome'). build (); function logTitle () browser.getTitle (). then (function (title) console.log ('Huidige paginatitel:' + title);); functie clickLink (link) link.click (); function handleFailure (err) console.error ('Er is iets fout gegaan \ n', err.stack, '\ n'); closeBrowser (); function findTutsPlusLink () return browser.findElements (webdriver.By.css ('[href = "http://code.tutsplus.com/]')). then (functie (resultaat) retourresultaat [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')) klik (); browser.wait (findTutsPlusLink, 2000) .then (clickLink) .then (logTitle) .then (closeBrowser, handleFailure);
De bovenstaande code uitvoeren:
$ knoop GoogleSearch.js Huidige paginatitel: Tuts + Code Tutorials
Een paar interessante fragmenten worden hier getoond. Ten eerste kunnen we een idee krijgen van hoe het is om functie-verklaringen te gebruiken - in plaats van anonieme functie-callbacks (die worden doorgegeven aan dan
), het resultaat is zoiets als een vloeiende API (zie de laatste regel). Omdat we de mogelijkheid hebben om beloftes op maat te maken (uitstel), kunnen we zo vloeiend zijn als we willen!
Merk op dat we een fout terugbellen in de laatste oproep aan dan
, zelfs als er eerder een fout optreedt, wordt deze nog steeds doorgegeven.
We navigeren naar de Google-startpagina en zoeken naar 'tuts + code'. Omdat we werken met het browserobject, weet het interne Control Flow-mechanisme van WebDriver dat elke opdracht één na één moet plaatsvinden, dit bespaart ons het gedoe om alles met elkaar te moeten ketenen en verklaart ook waarom er twee oproepen zijn naar findElement
, de een na de ander, zonder aan elkaar vastgeketend te zijn.
Wanneer we de Google-zoekopdracht uitvoeren vanaf de startpagina, wordt er geen pagina opnieuw geladen, daarom zal WebDriver onmiddellijk proberen de elementen te vinden die we hebben aangegeven op de pagina met zoekresultaten. Weten wanneer te wachten op elementen is een cruciaal onderdeel van browserautomatisering.
De oude en ondeugende manier om dingen te doen was om a te gebruiken slaap
. Aangezien het punt waarop een element wordt weergegeven sterk afhankelijk kan zijn van externe factoren (zoals de netwerkverbindingssnelheid), kunnen ontwikkelaars WebDriver soms opdracht geven een vaste periode te wachten alvorens verder te gaan. Dit zit natuurlijk boordevol problemen.
Gelukkig is de Wacht
methode maakt het automatiseren van moderne webpagina's een stuk leuker. Je roept wachten met twee argumenten, de eerste is een functie die moet worden geëvalueerd als waar voor een tijdsperiode die is gedefinieerd als het tweede argument om te wachten. WebDriver roept regelmatig uw callback op totdat het resultaat true is of de tijd is verstreken, in welk geval er een fout wordt gegenereerd.
Hoewel er veel methoden zijn om de context van DOM-elementen aan te roepen, kunt u ook methoden in de browser zelf bellen om u meer controle te geven over de browserstatus. Hier zijn een paar eenvoudige voorbeelden om u een beter idee te geven:
Stel de afmetingen van het browservenster in
browser.manage (). window (). setSize (1280, 720)
Verbind de browser met een proxy:
var proxy = require ('selenium-webdriver / proxy'); browser = nieuwe webdriver.Builder () .usingServer () .withCapabilities ('browserName': 'chrome') .setProxy (proxy.handmatig (http: '127.0.0.1:9000')) .build ();
U kunt ook cookies lezen, schrijven en verwijderen, een screenshot van het venster maken, een aantal individuele browserinstellingen instellen en meer.
Er zijn een aantal opties beschikbaar als u een browser programmatisch wilt bedienen. Eerst en vooral hebben we de JavaScript-bindingen voor WebDriver bekeken, maar er zijn er nog meer:
WebDriverJs, b.v. de versie die we hebben geïnstalleerd met npm installeer selenium-webdriver
is slechts één versie van een WebDriver Client API geschreven in JavaScript. Als u browsers graag via JavaScript wilt beheren, zijn er ook andere opties:
Het gebruik van iets als WD.js of Nightwatch kan een aantal dingen betekenen:
Als u WebDriver wilt gaan gebruiken voor het testen, dan is dat geweldig. Houd er ook rekening mee dat browserautomatisering niet hoeft te stoppen bij het testen, hoe zit het met het automatiseren van een repetitieve taak?
Bekijk bijvoorbeeld dit artikel over Getting To Philosophy, waarin in essentie wordt uitgelegd hoe doorlopend klikken op de eerste link in Wiki-artikelen je uiteindelijk op het artikel Philosophy brengt.!
Dit zorgt voor een leuke taak om te automatiseren! Bekijk deze geanimeerde gif of de bron om het in actie te zien.