In questo tutorial, daremo un'occhiata a WebDriverJs, uno strumento utilizzato per l'automazione del browser. Chrome verrà utilizzato in tutti i browser moderni ma tendono ad avere driver disponibili per l'utilizzo con WebDriver (anche mobile), quindi controllali se desideri automatizzare altri browser.
Mentre i test unitari sono certamente preziosi per le moderne applicazioni web, ad un certo punto, man mano che la tua applicazione cresce, scoprirai bug che non sono stati catturati da un test unitario ma che sarebbero stati teoricamente catturati da un test di integrazione / accettazione.
Se desideri seguire una strategia di test che coinvolge i test del browser, questa guida ti fornirà un'introduzione iniziale ai test con WebDriverJs in modo da disporre di conoscenze sufficienti per iniziare.
Questo tutorial presume che tu abbia familiarità con JavaScript e possa eseguire codice JavaScript utilizzando node.js.
Se vuoi seguire, sentiti libero di dare un'occhiata a questo progetto di esempio che contiene alcuni esempi di WebDriver da eseguire. Devi anche installare Chromedriver e averlo a disposizione nel tuo percorso.
Selenium WebDriver ha in genere un server e un client. A parte i contributori di WebDriver, la maggior parte delle persone sarà interessata solo all'API client che consente loro di controllare un browser attraverso il loro script. Per iniziare, installa i collegamenti JavaScript per WebDriver:
npm installa selenium-webdriver
Una volta installato quel modulo tramite NPM, puoi richiedere il modulo nel tuo codice nodo in questo modo:
require ( 'selenio WebDriver');
In alternativa, se controlli il progetto di esempio, puoi semplicemente eseguire un installazione di npm
all'interno della cartella poiché il modulo WebDriverJs è elencato come una dipendenza in package.json
file.
Mentre puoi consultare la documentazione ufficiale, il mio preferito è la fonte stessa. Questo file webdriver.js elenca molti metodi di WebDriver, ad es. noterai un getAttribute e un getText. Ecco alcuni metodi che possono essere di interesse:
ottenere
- Naviga nel browser fino a un URL.findElements
- Simile a document.querySelectorAll
nel browser.executeScript
- Esegui JavaScript non elaborato nella pagina corrente.getText
- Ottieni il contenuto del testo di un elemento inclusi i suoi figli.È visualizzato
- Scopri se un elemento è visualizzato sulla pagina.Un fattore che riguarda i collegamenti JavaScript per WebDriver in particolare è che quasi tutti i metodi sono asincroni. Significa che il seguente codice in realtà non ottiene il titolo della pagina web:
var title = browser.getTitle (); // logs then: [Funzione: then], cancel: [Funzione: cancel], isPending: [Funzione: isPending] console.log (titolo);
Invece quello che devi fare è questo:
var promise = browser.getTitle (); promise.then (function (title) console.log (title););
Questo perché WebDriverJs utilizza le promesse per rendere più piacevole la gestione del codice asincrono. Si noti che l'implementazione di promessa come parte di WebDriverJs non è conforme allo standard Promises / A +.
La cosa fondamentale da portare via qui è che la maggior parte dei metodi di WebDriver restituirà a poi
metodo che accetta due argomenti opzionali (funzione). Il primo argomento è un callback che può ricevere un valore.
Nell'esempio sopra abbiamo chiesto un titolo, quindi il nostro callback riceverà questo titolo come primo argomento. Il secondo argomento di funzione opzionale che possiamo passare al metodo then ci consente di rilevare gli errori, se non del tutto.
Ricapitoliamo su dove siamo così lontani:
Dai un'occhiata a questo esempio di codice:
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 (function (links) console.log ('Found', links.length, 'collegamenti Wiki.') browser.quit (););
Esegui l'esempio Wiki come questo:
$ node Wiki.js Trovati 367 collegamenti Wiki.
Nell'esempio di codice, le prime poche righe sono essenzialmente boilerplate. Inizializza l'oggetto browser e specifica una configurazione iniziale, come il browser che effettivamente utilizza. Iniziando con la chiamata a browser.get
, abbiamo il codice che ci interessa davvero.
findElements
metodo che andrà avanti e valuterà asincronamente l'espressione del selettore.Trovare elementi sulla pagina è un pezzo del puzzle, diamo un'occhiata a un altro esempio che dimostra la realizzazione di una ricerca su Google e cliccando sul risultato che ci aspettiamo di essere sulla pagina.
/ * * Esegui una ricerca su Google * / "usa rigorosamente"; var webdriver = require ('selenium-webdriver'); var browser = new webdriver.Builder (). usingServer (). withCapabilities ('browserName': 'chrome'). build (); function logTitle () browser.getTitle (). then (function (title) console.log ('Current Page Title:' + title);); function clickLink (link) link.click (); function handleFailure (err) console.error ('Qualcosa è andato storto \ 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')) clicca (); browser.wait (findTutsPlusLink, 2000) .then (clickLink) .then (logTitle) .then (closeBrowser, handleFailure);
Esecuzione del codice precedente:
$ nodo GoogleSearch.js Titolo della pagina corrente: Tuts + Esercitazioni sui codici
Alcuni frammenti interessanti sono mostrati qui. In primo luogo, possiamo avere un'idea di cosa vuol dire usare le dichiarazioni di funzione - invece dei callback di funzioni anonime (che vengono passati a poi
), il risultato è qualcosa di simile a un'API fluente (vedi l'ultima riga). Inoltre, poiché abbiamo la capacità di creare promesse personalizzate (differite), possiamo essere fluenti come desideriamo!
Tieni presente che alle richiamiamo un messaggio di errore nell'ultima chiamata a poi
, anche se si verifica un errore in precedenza, si propagherà ancora.
Navighiamo alla home page di Google e cerchiamo "tuts + code". Dal momento che stiamo operando sull'oggetto browser, il meccanismo di controllo del flusso interno di WebDriver sa che ogni comando si verifica uno dopo l'altro, questo ci risparmia il fastidio di dover concatenare tutto insieme e spiega anche perché ci sono due chiamate a findElement
, uno dopo l'altro, senza dover essere incatenati l'uno all'altro.
Quando eseguiamo la ricerca su Google dalla homepage, non si verifica alcuna ricarica della pagina, pertanto WebDriver proverà immediatamente a trovare gli elementi a cui l'abbiamo indicato nella pagina dei risultati di ricerca. Sapere quando aspettare elementi è una parte fondamentale dell'automazione del browser.
Il modo vecchio e cattivo di fare le cose era usare a dormire
. Poiché il punto in cui un elemento appare può dipendere fortemente da fattori esterni (ad esempio la velocità della connessione di rete), gli sviluppatori possono a volte indicare a WebDriver di attendere un determinato periodo di tempo prima di continuare. Questo, ovviamente, è pieno di problemi.
Fortunatamente, il aspettare
metodo rende molto più bello automatizzare le pagine Web moderne. Si chiama wait con due argomenti, il primo è una funzione che deve essere valutata su true per un periodo di tempo definito come il secondo argomento da attendere. WebDriver chiama regolarmente il tuo callback fino a quando non restituisce true, o il tempo è scaduto nel qual caso viene generato un errore.
Mentre ci sono molti metodi per chiamare il contesto degli elementi DOM, puoi anche chiamare metodi sul browser stesso per darti più controllo sullo stato del browser. Ecco alcuni semplici esempi per darti un'idea migliore:
Imposta le dimensioni della finestra del browser
browser.manage (). window (). setSize (1280, 720)
Connetti il browser a un proxy:
var proxy = require ('selenium-webdriver / proxy'); browser = new webdriver.Builder () .usingServer () .withCapabilities ('browserName': 'chrome') .setProxy (proxy.manual (http: '127.0.0.1:9000')) .build ();
Puoi anche leggere, scrivere ed eliminare i cookie, fare uno screenshot della finestra, impostare alcune impostazioni del browser e altro.
Ci sono un certo numero di opzioni disponibili quando si desidera controllare un browser in modo programmatico. Prima di tutto, abbiamo dato un'occhiata ai collegamenti JavaScript per WebDriver, tuttavia ce ne sono altri:
WebDriverJs, ad es. la versione che abbiamo installato usando npm installa selenium-webdriver
è solo una versione di un'API Client WebDriver scritta in JavaScript. Se desideri controllare i browser in modo programmatico tramite JavaScript, esistono anche altre opzioni:
Usare qualcosa come WD.js o Nightwatch può significare un certo numero di cose:
Se si desidera iniziare a utilizzare WebDriver per motivi di prova, è fantastico. Tieni anche presente che l'automazione del browser non deve fermarsi al test, ma solo automatizzare un'attività ripetitiva?
Per esempio, leggi questo articolo su Getting to Philosophy, in pratica spiega come il click continuo sul primo link negli articoli della Wiki finisca per finire sull'articolo di Philosophy!
Questo rende un compito divertente da automatizzare! Scopri questa gif animata o la fonte per vederla in azione.