Catturare schermate è fastidioso, ma la maggior parte del tempo deve essere fatto e di solito sei tu - lo sviluppatore - chi deve farlo. Prendendo alcuni screenshot non è male, ma diciamo per esempio che ora stai lavorando su un sito web utilizzando Responsive Web Design e devi prendere cinque volte più screenshot in varie finestre. Quel secondo, due secondi compiti noiosi ora ha iniziato a mangiare nella tua ora di pranzo.
Oggi ho intenzione di scrivere attraverso uno script semplice e veloce per fare alcuni screenshot di qualsiasi sito in varie finestre e salvare le immagini sul disco. Questo è qualcosa che ho visto su mediaqueri.es e ho iniziato a implementarlo nel mio processo di compilazione. Non è l'ideale per veri test, in quanto agisce più come un test di sanità mentale e fornisce una buona panoramica per tutto ciò su cui potrei lavorare coinvolgendo Web reattivo.
Quando viene eseguita una build, un piccolo script che utilizza PhantomJS e CasperJS può andare a prendere uno screenshot in varie finestre che ho definito e fornirmi una rapida panoramica di qualsiasi pagina desiderata. È particolarmente utile quando lavori in un team più grande e potresti non avere il tempo prima di ogni build per andare a controllare ogni singola pagina e modulo per vedere come sono le varie risoluzioni. Vi darà anche qualcosa per mostrare il cliente a intervalli regolari, per mostrare come il loro sito si flette in varie finestre.
Nota: PhantomJS è un browser WebKit senza head e qualsiasi cosa renderizzata utilizzerà il rendering di WebKit, quindi non è una rappresentazione reale di come il sito potrebbe eseguire il rendering su vari dispositivi che potrebbero eseguire diversi browser e mentre è possibile modificare la stringa di User Agent inviata a il sito on-load, questo non cambia il motore di rendering.
PhantomJS ha una grande API JavaScript costruita con i test in mente. Per un'ottima introduzione a PhantomJS e utilizzandolo per i test, qui è disponibile un'esercitazione su Nettuts e assicurati di controllare il sito ufficiale e la documentazione.
CasperJS è un toolkit che si trova in cima a PhantomJS e facilita il processo di scrittura degli script Phantom fornendo funzioni, metodi e zucchero sintattico.
Potresti già aver installato Phantom, specialmente se stai già testando il tuo codice lato client, in caso contrario, è abbastanza semplice e puoi ottenere istruzioni più dettagliate sul sito ufficiale
Per gli utenti Windows, c'è un eseguibile da scaricare ed eseguire.
Per gli utenti Mac, c'è sia il binario che puoi installare usando Homebrew:
brew update & brew install phantomjs
Per gli utenti Linux, esiste un binario a 64 bit o un'opzione per compilare PhantomJS dal sorgente.
Una volta installato, è possibile aprire un terminale e verificare che tutto funzioni correttamente eseguendo:
phantomjs --version
che dovrebbe restituire:
1.8.0
Una volta installato Phantom, puoi procedere e installare anche CasperJS. Per gli utenti Mac, puoi usare nuovamente Homebrew:
brew install casperjs
Per gli utenti Windows, è necessario aggiungere il tuo SENTIERO
file con "; C: \ casperjs \ batchbin"
(Modificare questo percorso in base a dove si desidera memorizzare CasperJS). All'interno del batchbin
directory, c'è un file batch chiamato casperjs.bat
, questo sarà lo script che esegue i tuoi script Casper senza bisogno di avere Ruby o Python installati per eseguirlo. Ogni volta che è necessario eseguire lo script Casper, basta usare casperjs.bat scriptname.js
piuttosto che casperjs scriptname.js
.
Quindi verifica che:casperjs --version
ritorna:1.0.0
Entrambi i numeri di versione sono aggiornati al momento della stesura di questo articolo.
Ora che abbiamo entrambi in esecuzione, facciamo un paio di Hello Worlds rapidi per assicurarci che sia Phantom che Casper siano in esecuzione come previsto.
Crea una nuova directory e al suo interno, crea due file JavaScript, hellophantom.js
e hellocasper.js
. Apri questi nell'editor che preferisci e inizia assicurandoti che Phantom funzioni correttamente.
Inizieremo nel hellophantom.js
file e scrivere un test rapido per afferrare il titolo di una pagina web. Non illustrerò dettagliatamente l'API di PhantomJS, questo ti fornirà solo una rapida introduzione e testerà la nostra installazione. Se PhantomJS è già in esecuzione, è possibile saltare questa parte.
Per prima cosa dobbiamo impostare un paio di variabili, una che istanzia il modulo 'pagina web' e un'altra come variabile 'URL'.
var page = require ('webpage'). create (), url = "http://net.tutsplus.com";
Successivamente possiamo creare la funzione che naviga verso la pagina web, passiamo nell'URL come argomento e una funzione di callback. Riceviamo uno stato nella nostra callback (successo o fallimento) sul Aperto
metodo.
page.open (url, function (status) );
Ora possiamo chiamare la funzione di valutazione per ottenere il titolo della pagina. Possiamo restituire il risultato, a una variabile, assegnandogli la funzione:
page.open (url, function (status) var title = page.evaluate (function () return document.title;););
Infine, ci limiteremo a registrarlo in modo che possiamo vedere il risultato nel terminale e quindi uscire dal processo Phantom.
console.log ('Ciao, Mondo! Il titolo della pagina su' + url + 'è' + titolo); phantom.exit ();
Il nostro script finito sarà simile a questo.
var page = require ('webpage'). create (), url = "http://net.tutsplus.com"; page.open (url, function (status) var title = page.evaluate (function () return document.title;); console.log ('Hello, World! Il titolo della pagina su' + url + 'è' + titolo); phantom.exit (););
CD nella directory in cui si trova questo script ed è possibile eseguirlo utilizzando il seguente comando:
phantomjs hellophantom.js
Dopo alcuni secondi, otterrai il seguente risultato nel tuo terminale:
Ciao mondo! Il titolo della pagina su http://net.tutsplus.com è un tutorial di sviluppo Web, dal principiante all'avanzato | Nettuts+
È grandioso, ma prima di andare avanti, possiamo semplicemente rendere questo codice un po 'più flessibile con un rapido ri-fattore. Ci sono alcuni moduli che possiamo usare e uno di questi è il modulo di sistema. Alcune delle proprietà del modulo di sistema ti danno accesso a cose come l'ID di processo su cui PhantomJS è in esecuzione o il sistema operativo in uso, ma quello a cui siamo interessati è il args
proprietà.
Il args
proprietà restituisce una matrice degli argomenti della riga di comando. Il primo elemento dell'array è sempre il nome dello script, ma possiamo passare qualsiasi numero di argomenti dalla riga di comando e usarli nel nostro script. Quindi possiamo passare l'URL che vogliamo aprire, con phantom, nella riga di comando, in modo da poter riutilizzare lo script in qualsiasi momento senza doverlo modificare ogni volta.
Abbiamo solo bisogno di prima richiedere il modulo di sistema e quindi modificare il url
variabile per essere l'argomento che attraversiamo:
system = require ('system'), url = system.args [1];
e ora possiamo eseguire lo script con il seguente comando:
phantomjs hellophantom.js http://net.tutsplus.com
Ora che sappiamo che Phantom sta funzionando, possiamo passare a testare Casper. Noi replicheremo lo stesso script di test, solo che questa volta useremo l'API di Casper.
Per prima cosa dobbiamo istanziare un'istanza casper:
var casper = require ("casper"). create ();
e poi prendi l'URL da uno degli argomenti passati dal terminale. Casper ha un proprio parser da riga di comando che si trova in cima a quello che viene fornito con Phantom e possiamo ottenere l'accesso a qualsiasi argomento passato dalla riga di comando proprio come facevamo in precedenza. L'unica differenza è che il nostro primo argomento sarà il primo che attraverseremo e non il nome dello script (come era con Phantom)
var url = casper.cli.args [0];
L'API CLI di Casper può anche utilizzare opzioni con nome e argomenti posizionali, possiamo usarla se vogliamo impostare alcune opzioni o essere più prolisse con il nostro script, ad esempio:
casperjs hellocasper.js argumentOne argumentTwo --option1 = this --option2 = that
e possiamo ottenere queste opzioni nominate usando cli.get ( 'nomeopzione')
, quindi potremmo fare qualcosa di simile al seguente, per passare sia gli argomenti che le opzioni (se avessimo alcune opzioni di configurazione che dovevano essere impostate):
var argumentOne = casper.cli.args [0]; var argumentTwo = casper.cli.args [1]; var thisOption = casper.cli.get ('opzione'); var thatOption = casper.cli.get ('option2');
Per ora, userò l'argomento posizionale per ottenere l'URL. Quindi eseguiremo il inizio()
metodo per fare qualsiasi tipo di navigazione. Il metodo di avvio accetta una stringa URL e una funzione di callback.
casper.start (url, function () this.echo ('Hello, World! Il titolo della pagina su' + url + 'è'););
Se non vuoi avere tutte le tue funzionalità, puoi usare il poi()
metodo. Ogni poi()
la chiamata al metodo viene aggiunta come un passo nello stack ed è eseguita in modo lineare, quindi piuttosto che sopra, potresti avere:
casper.start (url); casper.then (function () this.echo ('Hello, World! Il titolo della pagina su' + url + 'è'););
Preferisco usare poi()
, come lo trovo più facile da leggere, ma è accettabile e in realtà è solo una questione di gusti.
Per ottenere il titolo della pagina c'è già un getTitle ()
metodo a nostra disposizione, quindi possiamo usarlo nel nostro eco
.
casper.start (url); casper.then (function () this.echo ('Hello, World! Il titolo della pagina su' + url + 'è' + this.getTitle ()););
Finalmente, seguiamo i nostri passi con il correre()
metodo, che è un metodo obbligatorio, necessario per l'esecuzione dello script Casper. Questo metodo può anche avere un optional onComplete
callback da eseguire una volta che tutti i passaggi sono stati completati. Se hai utilizzato il callback, devi assicurarti di uscire dal processo Casper usando il Uscita()
metodo. Ecco un esempio di entrambi:
// questo non ha bisogno di usare il metodo exit. casper.run (); // OR // questo richiede il metodo exit casper.run (function () this.echo ('Tutto nello stack è terminato'); this.exit ();)
In alternativa, è possibile semplicemente concatenare il metodo di uscita dopo l'eco:
casper.run (function () this.echo ('Tutto nella pila è terminato'). exit ();)
Ancora una volta, solo una questione di gusti.
Ora il nostro script HelloCasper.js completo dovrebbe assomigliare a questo:
var casper = require ("casper"). create (); var url = casper.cli.args [0]; casper.start (url, function () this.echo ('Hello, World! Il titolo della pagina su' + url + 'è' + this.getTitle ());); casper.run (function () this.echo ('Tutto nella pila è terminato.'). exit (););
Ora possiamo eseguire lo script Casper con il seguente comando:
casperjs hellocasper.js http://net.tutsplus.com
Non fa nulla di diverso da quello che stavamo già facendo con Phantom, Casper ci fornisce semplicemente una bella API (con alcuni extra aggiunti) per sederci sopra a Phantom e rende il codice che scriviamo un po 'più prolisso e leggibile, questo è particolarmente utile quando si inizia a scrivere script che devono navigare in un sito.
Adesso ci immergiamo nel salvare alcune istantanee del nostro schermo.
Ho intenzione di iniziare con un file chiamato casperscreens.js e istanziare Casper. Quindi imposta una matrice che conterrà le larghezze della finestra di visualizzazione desiderate su cui vogliamo catturare schermate. Ogni elemento dell'array sarà costituito da un altro array che avrà la larghezza e l'altezza che vogliamo impostare.
viewportSizes = [[320,480], [320,568], [600,1024], [1024,768], [1280,800], [1440,900]]
Sto anche andando a impostare una var per ottenere l'URL dalla riga di comando e poi voglio eseguire una regex sull'URL per creare una directory in cui salvare gli screenshot. Sto solo andando a rimuovere il http: //
parte e sostituire i periodi con trattini. Quindi correremo casper.start ()
.
saveDir = url.replace (/ [^ a-zA-Z0-9] / gi, '-'). replace (/ ^ https? - + /, "); casper.start ();
Ora useremo un loop e per ogni dimensione del viewport, prendi uno screenshot dell'URL specificato. Stiamo per impostare la finestra sulle dimensioni definite nell'elemento della matrice su cui ci troviamo - apri l'URL - attendi 5000 millisecondi per assicurarti che la pagina sia caricata - e quindi acquisisci due tipi di screenshot.
Il primo è per l'altezza e la larghezza effettive definite, per questo usiamo il catturare()
metodo che accetta due argomenti: una stringa per il file di output e un argomento oggetto per l'impostazione della parte della pagina da ritagliare. Il secondo è per uno screenshot completo della pagina con solo la larghezza definita e lo facciamo usando il captureSelector ()
metodo che cattura l'area all'interno del selettore definito, nel nostro caso lo stiamo semplicemente usando corpo
e questo metodo prende due argomenti, il primo è il nome del file e il secondo è il selettore.
Sebbene lo screenshot definito sia utile, ho scoperto che è utile avere anche uno screenshot chromeless a pagina intera, in modo che tu possa vedere come scorre l'intera pagina.
casper.each (viewportSizes, function (self, viewportSize, i) // imposta due vars per l'altezza e la larghezza del viewport mentre passiamo attraverso ogni elemento nell'array viewport var width = viewportSize [0], height = viewportSize [1] ; // dare un po 'di tempo per caricare la pagina casper.wait (5000, function () // imposta la vista all'altezza e alla larghezza desiderate this.viewport (larghezza, altezza); casper.thenOpen (url, function () this.echo ('Opening at' + width); // Imposta due vars, una per il salvataggio a pagina intera, una per il viewport effettivo salva var FPfilename = saveDir + '/ fullpage-' + width + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Il selettore di cattura cattura l'intero corpo this.captureSelector (FPfilename, 'body'); // cattura scatta una selezione definita del page this.capture (nomefile, top: 0, left: 0, width: width, height: height); this.echo ('snapshot taken'););););
Alla fine chiamiamo il correre()
metodo e nella funzione di callback mi limiterò a ripetere che l'acquisizione è terminata.
casper.run (function () this.echo ('Finished captures for' + url) .exit (););
Lo script completo dovrebbe ora assomigliare a questo:
var casper = require ("casper"). create (), viewportSizes = [[320,480], [320,568], [600,1024], [1024,768], [1280,800], [1440,900]], url = casper.cli.args [0], saveDir = url.replace (/ [^ a-zA-Z0-9] / gi, '-'). replace (/ ^ https? - + /, "); casper .start (); casper.each (viewportSizes, function (self, viewportSize, i) // imposta due vars per l'altezza e la larghezza del viewport mentre passiamo attraverso ogni elemento dell'array viewport var width = viewportSize [0], altezza = viewportSize [1]; // dedica un po 'di tempo per caricare la pagina casper.wait (5000, function () // imposta la vista sull'altezza e larghezza desiderate this.viewport (larghezza, altezza); casper.thenOpen ( url, function () this.echo ('Opening at' + width); // Imposta due vars, uno per il salvataggio a pagina intera, uno per il reale viewport save var FPfilename = saveDir + '/ fullpage-' + width + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Il selettore di cattura cattura l'intero corpo this.captureSelector (FPfilename, 'body'); // snap snap una selezione definita o f la pagina this.capture (nomefile AC, top: 0, left: 0, width: width, height: height); this.echo ('istantanea acquisita'); ); ); ); casper.run (function () this.echo ('Finished captures for' + url) .exit (););
E ora possiamo eseguire questo script usando il seguente comando:
casperjs casperscreens.js http://todomvc.com
Ho scelto di catturare alcuni schermi da todomvc.com semplicemente perché è un sito reattivo in grado di visualizzare il tipo di risultati che stiamo cercando.
Ora, se navighi nella directory da cui è stato eseguito lo script, vedrai una nuova directory creata e al suo interno ci sono tutti i tuoi PNG.
Quindi siamo riusciti a scrivere un po 'di JavaScript in modo da risparmiare un sacco di problemi, la prossima volta che il capo o il cliente vogliono una serie di schermate, fornendo allo stesso tempo uno script aggiuntivo che possiamo aggiungere alla nostra casella degli strumenti quando eseguiamo alcuni test . Certo, questo ci mostra solo un rendering di WebKit, ma per molti è abbastanza buono.
Ora prova ad integrarlo nel tuo processo di build, eseguilo insieme agli altri test e utilizza la funzionalità di cattura dello schermo per testare non solo la reattività del tuo sito, ma il modo in cui il viaggio degli utenti potrebbe apparire su schermi di diverse dimensioni. Inoltre, controlla il plugin Grunt-casper se Grunt è parte del tuo processo di compilazione.
Se sei un fan di CoffeeScript, puoi anche provare a riscrivere questo script con la sintassi CoffeeScript, ma assicurati che il tuo file termini con .caffè
estensione:
casperjs casperscreen.coffee http://example.com
E non devi nemmeno preoccuparti di pre-compilare il tuo CoffeeScript, script di Casper.
C'è molto di più in CasperJS e PhantomJS, quindi dai un'occhiata ai rispettivi siti e guarda come possono aiutarti con i tuoi test.