Responsive Skjermbilder Med Casper

Det er irriterende å fange skjermbilder, men det meste må det gjøres, og det er vanligvis du - Utvikleren - hvem må gjøre det. Å ta noen skjermbilder er ikke så ille, men vi kan for eksempel si at du nå jobber på et nettsted ved hjelp av Responsive Web Design, og du må ta fem ganger så mange skjermbilder på ulike visningsportaler. Den ene, to sekunder irriterende oppgaven har nå begynt å spise i lunsjen din.


Intro

I dag skal jeg løpe gjennom å skrive et raskt og enkelt skript for å ta noen skjermbilder av et hvilket som helst nettsted på ulike visningsportaler og lagre bildene på disk. Dette er noe jeg først så på mediaqueri.es og begynte å implementere det i byggeprosessen min. Det er ikke ideelt for ekte testing, da det virker mer som en sunnhetstest og gir en god oversikt over alt jeg kan jobbe med med å involvere Responsive Web.

Når et bygg er kjørt, kan et lite skript som bruker PhantomJS og CasperJS gå og ta et skjermbilde på ulike visningsportaler som jeg har definert og gi meg en rask oversikt over hvilken som helst ønsket side. Det er spesielt godt når du jobber i et større lag, og du har kanskje ikke tid før hver bygning skal gå og sjekke hver enkelt side og modul for hvordan det ser på ulike oppløsninger. Det vil også gi deg noe å muligens vise klienten med jevne mellomrom, for å vise hvordan deres nettsted bøyer seg på ulike visningsportaler.

Merk: PhantomJS er en headless WebKit-nettleser, og alt som gjengis, vil bruke WebKit-gjengivelse, så det er ikke en faktisk representasjon av hvordan nettstedet skulle gjengis på ulike enheter som kan kjøre forskjellige nettlesere, og mens du kan endre brukeragentstrengen sendt til siden på last, endrer dette ikke gjengivelsesmotor.

PhantomJS har en flott JavaScript API bygget med testing i tankene. For en flott introduksjon til PhantomJS og bruk av den til testing, er det en opplæring her på nettet og sørg for å sjekke det offisielle nettstedet og dokumentasjonen.

CasperJS er en verktøykasse som sitter på toppen av PhantomJS og letter prosessen med å skrive Phantom-skript ved å gi funksjoner, metoder og syntaktisk sukker.


Installasjon

Du har kanskje allerede Phantom installert, spesielt hvis du allerede tester klientens side kode, hvis ikke, det er ganske rett frem og du kan få mer detaljerte instruksjoner på den offisielle siden

For Windows-brukere er det en kjørbar å laste ned og kjøre.

For Mac-brukere er det både det binære eller du kan installere ved hjelp av Homebrew:

bryg oppdatering & & brygg installasjonsfantomier

For Linux-brukere er det en 64-biters binær eller du har mulighet til å kompilere PhantomJS fra kilde.

Når du er installert, kan du åpne en terminal og kontrollere at alt er greit ved å kjøre:

fantom - versjon

som skal returnere:

1.8.0

Når Phantom er installert, kan du gå videre og installere CasperJS også. For Mac-brukere kan du igjen bruke Homebrew:

brew install casperjs

For Windows-brukere må du legge til din STI filen med "C: \ casperjs \ batchbin" (Endre denne banen, avhengig av hvor du vil lagre CasperJS). Innen batchbin katalog, det er en batchfil kalt casperjs.bat, Dette vil være skriptet som kjører dine Casper-skript uten å måtte trenge Ruby eller Python installert for å kjøre det. Når du trenger å kjøre Casper-skriptet, bruk bare casperjs.bat scriptname.js heller enn casperjs scriptname.js.

Sjekk deretter at:casperjs - versjon avkastning:1.0.0

Begge disse versjonstallene er oppdaterte fra tidspunktet for skriving av denne artikkelen.


Hei PhantomJS

Nå som vi har begge disse løpene, la oss gjøre et par raske Hello Worlds for å sikre at både Phantom og Casper kjører som forventet.

Lag en ny katalog og innsiden av den, lag to JavaScript-filer, hellophantom.js og hellocasper.js. Åpne disse opp i redaktøren etter eget valg og la oss starte med å sørge for at Phantom faktisk kjører riktig.

Vi skal begynne i hellophantom.js fil og skriv en rask test for å hente tittelen på en nettside. Jeg kommer ikke til å dekke PhantomJS API i detalj, dette vil bare gi deg en rask introduksjon og teste vår installasjon. Hvis du har PhantomJS allerede, kan du hoppe over denne delen.

Først må vi sette opp et par variabler, en som instanserer modulen "Webside" og en annen som en "URL" -variabel.

var side = krever ('webside'). opprett (), url = "http://net.tutsplus.com";

Deretter kan vi opprette funksjonen som navigerer til nettsiden, vi sender inn URL-en som et argument og en tilbakeringingsfunksjon. Vi mottar en status i tilbakekallingen (suksess eller feil) på åpen metode.

 page.open (url, funksjon (status) );

Nå kan vi ringe evalueringsfunksjonen for å få tittelen på siden. Vi kan returnere resultatet til en variabel ved å tildele funksjonen til den:

page.open (url, funksjon (status) var title = page.evaluate (function () return document.title;););

Til slutt skal vi bare logge det slik at vi kan se resultatet i terminalen og deretter gå ut av Phantom-prosessen.

 console.log ('Hei, verden! Sidetittelen på' + url + 'er' + tittel); phantom.exit ();

Vårt ferdige skript vil se noe ut som dette.

 var side = krever ('webside'). opprett (), url = "http://net.tutsplus.com"; page.open (url, funksjon (status) var title = page.evaluate (function () return document.title;); console.log ('Hei, verden! Sidetittelen på' + url + 'er' + tittel); phantom.exit (););

cd inn i katalogen hvor dette skriptet er plassert, og du kan kjøre det ved hjelp av følgende kommando:

fantomier hellophantom.js

Etter noen få sekunder får du følgende resultat i terminalen din:

 Hei Verden! Sidetittelen på http://net.tutsplus.com er veiledning for webutvikling, fra nybegynner til avansert | Nettuts+

Det er flott, men før vi går videre, kan vi bare gjøre denne koden litt mer fleksibel med en rask re-faktor. Det er noen moduler som er tilgjengelige for oss å bruke, og en av dem er systemmodulen. Noen av egenskapene til systemmodulen gir deg tilgang til ting som prosess-IDen som PhantomJS kjører på eller operativsystemet brukes, men det vi er interessert i, er args eiendom.

De args Egenskapen returnerer en rekke av kommandolinjeparametrene. Det første elementet i arrayet er alltid skriptnavnet, men vi kan passere et hvilket som helst antall argumenter fra kommandolinjen og bruke dem i vårt skript. Så vi kan passere nettadressen vi vil åpne, med fantom, i kommandolinjen, slik at vi kan bruke skriptet til enhver tid uten å måtte redigere det hver gang.

Vi trenger bare å først kreve systemmodulen og deretter endre url variabel for å være argumentet vi passerer gjennom:

system = krever ('system'), url = system.args [1];

og nå kan vi kjøre skriptet med følgende kommando:

phantomjs hellophantom.js http://net.tutsplus.com

Hei Casper

Nå som vi vet at Phantom jobber, kan vi fortsette å teste ut Casper. Vi vil gjenta det samme testskriptet, bare denne gangen bruker vi Casper API.

Først må vi instansere en casper-forekomst:

var casper = krever ("casper"). opprett ();

og deretter ta URLen fra en av argumentene som er sendt fra terminalen. Casper har sin egen kommandolinjeparser som sitter på toppen av den som kommer med Phantom, og vi kan få tilgang til alle argumenter som går gjennom kommandolinjen, akkurat som vi gjorde tidligere. Den eneste forskjellen er at vårt første argument vil være den første vi passerer gjennom og ikke skriptnavnet (som det var med Phantom)

var url = casper.cli.args [0];

Casper CLI API kan også ta opp navngitte alternativer samt posisjonsargumenter, vi kan bruke dette hvis vi ønsket å sette opp noen alternativer eller være mer verbose med skriptet vårt, for eksempel:

casperjs hellocasper.js argumentOne argumentTwo --option1 = dette --option2 = det

og vi kan få disse navngitte alternativene ved hjelp av cli.get ( 'optionName'), slik at vi kunne gjøre noe som følger, for å passere i både argumenter og alternativer (hvis vi hadde noen config-alternativer som måtte settes):

 var argumentOne = casper.cli.args [0]; var argumentTwo = casper.cli.args [1]; var thisOption = casper.cli.get ('option'); var thatOption = casper.cli.get ('option2');

For nå skal jeg bare bruke posisjonsargumentet for å få nettadressen. Deretter skal vi løpe start() metode for å gjøre noen form for navigering. Startmetoden tar en strengadresse og en tilbakeringingsfunksjon.

casper.start (url, funksjon () this.echo ('Hei, verden! Sidetittelen på' + url + 'er'););

Hvis du ikke vil ha all funksjonalitet, kan du bruke deretter() metode. Hver deretter() Metodeanrop blir lagt til som et trinn i stabelen og utføres på lineær måte, så i stedet for ovenfor, kan du ha:

 casper.start (url); casper.then (funksjon () this.echo ('Hei, verden! Sidetittelen på' + url + 'er'););

Jeg foretrekker å bruke deretter(), som jeg finner det lettere å lese, men enten er akseptabelt og egentlig er det bare et spørsmål om smak.

For å få tittelen på siden er det allerede a getTitle () metode tilgjengelig for oss, så vi kan bare bruke det i vår ekko.

 casper.start (url); casper.then (funksjon () this.echo ('Hello, World! Sidetittelen på' + url + 'er' + this.getTitle ()););

Til slutt løper vi trinnene våre med løpe() metode, som er en obligatorisk metode som trengs for at Casper-skriptet skal løpe. Denne metoden kan også ha en valgfri onComplete tilbakeringing for å kjøre når alle trinn er fullført. Hvis du brukte tilbakeringingen, må du sørge for at du avslutter Casper-prosessen ved å bruke exit() metode. Her er et eksempel på begge:

 // dette trenger ikke å bruke utgangsmetoden. casper.run (); // ELLER // dette trenger utgangsmetoden casper.run (funksjon () this.echo ('Alt i stakken er avsluttet'); this.exit ();)

Alternativt kan du bare koble utgangsmetoden etter ekkoet:

casper.run (funksjon () this.echo ('Alt i stakken er avsluttet'). exit ();)

Igjen, bare et spørsmål om smak.

Nå skal vårt komplette HelloCasper.js-skript se slik ut:

var casper = krever ("casper"). opprett (); var url = casper.cli.args [0]; casper.start (url, funksjon () this.echo ('Hei, verden! Sidetittelen på' + url + 'er' + this.getTitle ());); casper.run (funksjon () this.echo ('Alt i stakken er avsluttet.'). exit (););

Vi kan nå kjøre Casper-skriptet med følgende kommando:

casperjs hellocasper.js http://net.tutsplus.com

Det gjør ikke noe annet enn det vi allerede gjorde med Phantom, gir Casper oss bare en fin API (med noen ekstra tillegg) å sitte på toppen av Phantom og gjør koden vi skriver litt mer ordentlig og lesbar, dette er spesielt nyttig når du kommer inn i skript som må navigere på et nettsted.

Lar deg dykke inn i å lagre noen stillbilder av skjermen.


Snapshot Basics

Jeg skal begynne med en fil kalt casperscreens.js og instantiate Casper. Sett deretter opp en matrise som vil inneholde våre ønskede visningsbredder som vi vil fange skjermbilder på. Hvert element i gruppen vil bestå av en annen matrise som vil ha bredden og høyden vi ønsker å sette.

viewportSizes = [[320,480], [320,568], [600,1024], [1024,768], [1280,800], [1440,900]]

Jeg skal også sette en var for å få nettadressen fra kommandolinjen og da vil jeg kjøre en regex på nettadressen for å lage en katalog for å lagre skjermbildene i. Jeg skal bare fjerne http: // del og erstatt perioder med bindestreker. Så skal vi løpe casper.start ().

 saveDir = url.replace (/ [^ a-zA-Z0-9] / gi, '-'). erstatte (/ ^ https? - + /, "); casper.start ();

Nå skal vi bruke en sløyfe og for hver visningsstørrelse, ta en skjermdump av den angitte nettadressen. Vi skal sette visningsporten til størrelsene som er definert i matteelementet vi er på - åpne nettadressen - vent 5000 millisekunder for å sikre at siden har lastet inn - og ta deretter to typer skjermbilder.

Den første er for den faktiske høyden og bredden som er definert, for dette bruker vi fange () metode som tar to argumenter - en streng for utdatafilen og et objektargument for å angi hvilken del av siden som skal klippes. Den andre er for et komplett side skjermbilde med bare den definerte bredden, og vi gjør dette ved hjelp av captureSelector () metode som fanger området innenfor den definerte väljeren, i vårt tilfelle bruker vi bare kropp og denne metoden tar to argumenter, den første er filnavnet og det andre er selektoren.

Selv om det faktiske definerte skjermbildet er nyttig, har jeg funnet ut at det er nyttig å også ha et fullstendig kromløs skjermbilde, slik at du kan se hvordan hele siden flyter.

casper.each (viewportSize, function (self, viewportSize, i) // sett to vars for visningsporten høyde og bredde som vi sløyfe gjennom hvert element i visningsfeltet array var width = viewportSize [0], height = viewportSize [1] ; // gi litt tid til siden å laste casper.wait (5000, funksjon () // sett visningsporten til ønsket høyde og bredde this.viewport (bredde, høyde); casper.thenOpen (url, funksjon () this.echo ('Åpner på' + bredde); // Sett opp to vars, en for fullsiden lagre, en for den faktiske visningsporten lagre var FPfilnavn = lagreDir + '/ fullside-' + bredde + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Capture selector fanger hele kroppen this.captureSelector (FPfilnavn, 'body'); // fanger snaps et definert utvalg av side this.capture (ACfilnavn, topp: 0, venstre: 0, bredde: bredde, høyde: høyde); this.echo ('stillbilde tatt'););););

Til slutt kaller vi løpe() metode og i tilbakekallingsfunksjonen, skal jeg bare ekko at fangingen er ferdig.

casper.run (funksjon () this.echo ('Ferdig fangst for' + url) .exit (););

Hele scriptet skal nå se slik ut:

 var casper = krever ("casper"). opprett (), 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, '-'). erstatte (/ ^ https? - + /, "); casper .start (); casper.each (viewportSize, function (self, viewportSize, i) // sett to vars for visningsportens høyde og bredde som vi sløyfe gjennom hvert element i visningsporten array var width = viewportSize [0], height = viewportSize [1]; // gi litt tid til siden å laste casper.wait (5000, funksjon () // sett visningsporten til ønsket høyde og bredde this.viewport (bredde, høyde); casper.thenOpen (casper.thenOpen url, funksjon () this.echo ('Åpning på' + bredde); // Sett opp to vars, en for fullsiden lagre, en for den faktiske visningsfeltet lagre var FPfilnavn = lagreDir + '/ fullside-' + bredde + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Capture selector fanger hele kroppen this.captureSelector (FPfilnavn, 'body'); // fange snaps et definert utvalg o f siden this.capture (ACfilename, topp: 0, venstre: 0, bredde: bredde, høyde: høyde); this.echo ('stillbilde tatt'); ); ); ); casper.run (funksjon () this.echo ('Ferdig fangst for' + url) .exit (););

Og nå kan vi kjøre dette skriptet ved å bruke følgende kommando:

casperjs casperscreens.js http://todomvc.com

Jeg har valgt å fange noen skjermer fra todomvc.com rett og slett fordi det er et responsivt nettsted som kan vise hva slags resultater vi leter etter.

Nå, hvis du navigerer til katalogen hvor skriptet ble kjørt fra, vil du se at en ny katalog er opprettet og inne er alle dine PNGs.



Wrap Up

Så vi har klart å skrive en ganske liten bit av JavaScript som vil spare mye problemer, neste gang sjefen eller klienten ønsker en rekke skjermbilder, samtidig som vi gir et ekstra skript vi kan legge til i verktøykassen vår når vi gjør noen test . Visst, dette viser oss bare en WebKit-gjengivelse, men for mange er det bra nok.

Prøv nå å integrere dette i byggeprosessen din, kjør den sammen med andre tester, og bruk skjermopptaksfunksjonaliteten til ikke bare å teste responsiviteten til nettstedet ditt, men hvordan en brukers reise kan se på forskjellige størrelsesskjermer. Også, se Grunt-plugin grunt-casper hvis Grunt er en del av byggeprosessen.

Hvis du er en fan av CoffeeScript, kan du til og med prøve å skrive om dette skriptet i CoffeeScript-syntaksen, bare sørg for at filen din slutter med .kaffe forlengelse:

 casperjs casperscreen.coffee http://example.com

Og du trenger ikke engang å bekymre deg om å forhåndskompilere CoffeeScript, Casper-skriptene.

Det er så mye mer til både CasperJS og PhantomJS, så sjekk ut deres respektive nettsteder og se hvordan de kan hjelpe deg med testing.