Introduzione a WebDriver Uso dei collegamenti JavaScript

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.

WebDriverJS

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.

promesse

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.

Esempi

Ricapitoliamo su dove siamo così lontani:

  1. Abbiamo installato il file binario di Chromedriver.
  2. Abbiamo installato WebDriverJs tramite NPM.
  3. Con la consapevolezza che quasi tutto è asincrono, sappiamo come usare le promesse per recuperare i valori che vogliamo.

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.

  1. Per prima cosa navighiamo verso una pagina di Wikipedia.
  2. Costruiamo un selettore CSS che corrisponde a elementi che hanno un attributo di href e un valore che inizia con / wiki / (ad es. Collegamenti Wiki interni).
  3. Sempre sulla stessa linea del passaggio n. 2, passiamo il selettore CSS nel findElements metodo che andrà avanti e valuterà asincronamente l'espressione del selettore.
  4. Per osservare gli aggiornamenti alla Promessa, passiamo una funzione di callback al metodo then.
  5. Il primo argomento del callback è un array di elementi corrispondenti, quindi lo recuperiamo e ne registra la lunghezza.
  6. Finalmente, abbiamo lasciato il browser.

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.

In attesa

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.

Modifica del browser

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.

Opzioni alternative

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:

  • Giava
  • Pitone
  • Rubino
  • PHP

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:

  • WD.js - API fluente che utilizza le promesse + concatenamento.
  • Leadfoot - Ora utilizzato dall'ultima versione di Intern.
  • WebDriver.io - Ha un sacco di documentazione da utilizzare con i framework BDD / TDD.
  • Testium: ha una documentazione chiara su esattamente ciò che è supportato.
  • DalekJS - Un sito web dall'aspetto divertente con feedback positivi durante l'esecuzione dei test. Un sacco di DalekJS è stato suddiviso in moduli che possono essere trovati su Github.
  • Nightwatch: un altro strumento con feedback interessanti e un'API fluente.
  • Webdriver-sync - Versione sincrona dell'interazione con WebDriver.

Usare qualcosa come WD.js o Nightwatch può significare un certo numero di cose:

  • API diverse per interagire con. Se le associazioni ufficiali di selenio-web per il selenio JavaScript hanno un'API a cui non sei abituato, controlla le opzioni alternative di cui sopra.
  • Feedback alternativo: può essere a livello di reporter, ma anche semplicemente ciò che viene visualizzato nel terminale dopo che un test ha avuto esito negativo a livello locale.

Conclusione

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.