Responsive Screenshots mit Casper

Das Aufnehmen von Screenshots ist ärgerlich, aber die meiste Zeit muss erledigt werden, und in der Regel müssen Sie - der Entwickler - es tun. Ein paar Screenshots zu machen ist nicht so schlimm, aber zum Beispiel, Sie arbeiten jetzt mit Responsive Web Design auf einer Website und müssen fünfmal so viele Screenshots in verschiedenen Ansichtsfenstern machen. Diese eine, zwei Sekunden lange nervige Aufgabe hat nun angefangen zu essen.


Intro

Heute werde ich ein schnelles und einfaches Skript schreiben, um Screenshots von einer beliebigen Site in verschiedenen Ansichtsfenstern zu erstellen und die Bilder auf einer Disc zu speichern. Dies ist etwas, was ich bei mediaqueri.es zum ersten Mal gesehen und mit dem Implementieren in meinen Build-Prozess begonnen habe. Es ist nicht ideal für echte Tests, da es eher wie ein Sanity-Test ist und einen guten Überblick über alles bietet, an dem ich mit Responsive Web arbeite.

Wenn ein Build ausgeführt wird, kann ein kleines Skript mit PhantomJS und CasperJS einen Screenshot in verschiedenen Ansichtsfenstern erstellen, die ich definiert habe, und mir einen schnellen Überblick über jede gewünschte Seite geben. Dies ist besonders gut, wenn Sie in einem größeren Team arbeiten und möglicherweise nicht vor jedem Build Zeit haben, jede einzelne Seite und jedes Modul auf verschiedene Auflösungen zu überprüfen. Es gibt Ihnen auch etwas, um den Kunden möglicherweise in regelmäßigen Abständen zu zeigen, um anzuzeigen, wie sich seine Site in verschiedenen Ansichtsfenstern verändert.

Hinweis: PhantomJS ist ein WebKit-Browser ohne Headsets und alles, was gerendert wird, würde WebKit-Rendering verwenden. Es handelt sich also nicht um eine tatsächliche Darstellung der Darstellung der Website auf verschiedenen Geräten, auf denen möglicherweise andere Browser ausgeführt werden, und während Sie die Zeichenfolge des Benutzeragenten ändern können, an die gesendet wird Wenn die Site geladen wird, ändert dies nicht die Rendering-Engine.

PhantomJS verfügt über eine großartige JavaScript-API, die für Tests entwickelt wurde. Für eine großartige Einführung in PhantomJS und deren Verwendung zum Testen gibt es hier ein Tutorial zu Nettuts und unbedingt die offizielle Website und Dokumentation.

CasperJS ist ein Toolkit, das sich auf PhantomJS befindet und das Schreiben von Phantom-Skripts vereinfacht, indem Funktionen, Methoden und syntaktischer Zucker bereitgestellt werden.


Installation

Möglicherweise haben Sie Phantom bereits installiert, insbesondere wenn Sie bereits Ihren clientseitigen Code testen. Wenn dies nicht der Fall ist, ist dies ziemlich einfach und Sie können auf der offiziellen Website detailliertere Anweisungen erhalten

Für Windows-Benutzer gibt es eine ausführbare Datei zum Herunterladen und Ausführen.

Für Mac-Benutzer gibt es sowohl die Binärdatei als auch die Installation mit Homebrew:

Brüh-Update && Brüh-Installations-Phantomjs

Für Linux-Benutzer gibt es eine 64-Bit-Binärdatei oder Sie haben die Möglichkeit, PhantomJS aus dem Quellcode zu kompilieren.

Nach der Installation können Sie ein Terminal öffnen und prüfen, ob alles in Ordnung ist, indem Sie Folgendes ausführen:

Phantomjs - Version

was sollte zurückkehren:

1.8.0

Sobald Phantom installiert ist, können Sie auch CasperJS installieren. Für Mac-Benutzer können Sie Homebrew erneut verwenden:

Brew installieren Casperjs

Für Windows-Benutzer müssen Sie Ihre anhängen PFAD Datei mit "; C: \ casperjs \ batchbin" (Ändern Sie diesen Pfad abhängig davon, wo Sie CasperJS speichern möchten.) Innerhalb des Batchbin Verzeichnis gibt es eine Batch-Datei casperjs.bat, Dies ist das Skript, mit dem Ihre Casper-Skripts ausgeführt werden, ohne dass Ruby oder Python installiert werden muss. Wann immer Sie das Casper-Skript ausführen müssen, verwenden Sie einfach casperjs.bat scriptname.js eher, als casperjs scriptname.js.

Dann überprüfen Sie das:casperjs --version kehrt zurück:1.0.0

Beide Versionsnummern sind zum Zeitpunkt der Erstellung dieses Artikels auf dem neuesten Stand.


Hallo PhantomJS

Nun, da wir beide laufen haben, wollen wir ein paar schnelle Hello Worlds machen, um sicherzustellen, dass sowohl Phantom als auch Casper wie erwartet laufen.

Erstellen Sie ein neues Verzeichnis und darin zwei JavaScript-Dateien, hellophantom.js und hellocasper.js. Öffnen Sie diese in einem Editor Ihrer Wahl und stellen Sie sicher, dass Phantom tatsächlich ordnungsgemäß ausgeführt wird.

Wir werden im starten hellophantom.js Datei und schreiben Sie einen kurzen Test, um den Titel einer Webseite zu erhalten. Ich werde die PhantomJS API nicht ausführlich behandeln, dies wird Ihnen nur eine kurze Einführung geben und unsere Installation testen. Wenn Sie bereits PhantomJS ausführen, können Sie diesen Teil überspringen.

Zuerst müssen wir einige Variablen einrichten, eine, die das 'Webseiten'-Modul instanziiert, und eine andere nur als' URL'-Variable.

var page = required ('Webseite'). create (), url = "http://net.tutsplus.com";

Als Nächstes können wir die Funktion erstellen, die zur Webseite navigiert, die URL als Argument und eine Rückruffunktion übergeben. Wir erhalten einen Status in unserem Callback (Erfolg oder Misserfolg) im öffnen Methode.

 page.open (URL, Funktion (Status) );

Jetzt können wir die Auswertefunktion aufrufen, um den Titel der Seite zu erhalten. Wir können das Ergebnis an eine Variable zurückgeben, indem wir ihr die Funktion zuweisen:

page.open (URL, Funktion (Status) var title = page.evaluate (function () return document.title;););

Zum Schluss werden wir dies nur abmelden, damit wir das Ergebnis im Terminal sehen und den Phantom-Prozess verlassen können.

 console.log ('Hallo, Welt! Der Seitentitel auf' + url + 'lautet' + title); phantom.exit ();

Unser fertiges Skript wird in etwa so aussehen.

 var page = required ('Webseite'). create (), url = "http://net.tutsplus.com"; page.open (url, function (status) var title = page.evaluate (function () return document.title;); console.log ('Hallo, Welt! Der Seitentitel auf' + url + 'ist' + title); phantom.exit (););

CD in das Verzeichnis, in dem sich dieses Skript befindet, und Sie können es mit dem folgenden Befehl ausführen:

phantomjs hellophantom.js

Nach wenigen Sekunden erhalten Sie in Ihrem Terminal folgendes Ergebnis:

 Hallo Welt! Der Seitentitel auf http://net.tutsplus.com umfasst Webentwicklungs-Tutorials vom Anfänger bis zum Fortgeschrittenen Nettuts+

Das ist großartig, aber bevor wir fortfahren, können wir diesen Code einfach mit einem schnellen Refaktor etwas flexibler machen. Es gibt einige Module, die wir verwenden können, und eines davon ist das Systemmodul. Einige der Eigenschaften des Systemmoduls geben Ihnen Zugriff auf Dinge wie die Prozess-ID, auf der PhantomJS ausgeführt wird, oder auf das verwendete Betriebssystem, aber die, an der wir interessiert sind, ist die args Eigentum.

Das args Die Eigenschaft gibt ein Array der Befehlszeilenargumente zurück. Das erste Element im Array ist immer der Skriptname, aber wir können beliebig viele Argumente von der Befehlszeile aus übergeben und in unserem Skript verwenden. So können wir die URL, die wir mit Phantom öffnen möchten, in der Befehlszeile übergeben, sodass wir das Skript jederzeit wieder verwenden können, ohne es jedes Mal bearbeiten zu müssen.

Wir brauchen nur das Systemmodul und dann das Systemmodul url Variable, um das Argument zu sein, durch das wir gehen:

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

und jetzt können wir das Skript mit dem folgenden Befehl ausführen:

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

Hallo Casper

Nun, da wir wissen, dass Phantom funktioniert, können wir Casper testen. Wir werden dasselbe Testskript replizieren, nur dieses Mal verwenden wir die Casper-API.

Zuerst müssen wir eine Casper-Instanz instanziieren:

var casper = requir ("casper"). create ();

und greifen Sie dann die URL aus einem der vom Terminal übergebenen Argumente auf. Casper verfügt über einen eigenen Befehlszeilen-Parser, der sich über dem mit Phantom gelieferten befindet, und wir können auf die Argumente zugreifen, die von der Befehlszeile weitergegeben werden, genau wie zuvor. Der einzige Unterschied ist, dass unser erstes Argument das erste ist, das wir durchlaufen, und nicht der Skriptname (wie bei Phantom).

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

Die Casper CLI-API kann auch benannte Optionen sowie Positionsargumente verwenden. Wir können dies verwenden, wenn wir einige Optionen einrichten möchten oder mit unserem Skript ausführlicher sein möchten, zum Beispiel:

casperjs hellocasper.js argumentOne argumentTwo --option1 = this --option2 = das

und wir können diese benannten Optionen mit verwenden cli.get ('optionName'), Wir könnten also etwas wie das Folgende tun, um sowohl Argumente als auch Optionen zu übergeben (wenn wir einige Konfigurationsoptionen hatten, die eingestellt werden mussten):

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

Im Moment werde ich nur das Positionsargument verwenden, um die URL zu erhalten. Als nächstes werden wir das ausführen Start() Methode, um jede Art von Navigation durchzuführen. Die Startmethode benötigt eine String-URL und eine Rückruffunktion.

casper.start (url, function () this.echo ('Hallo, Welt! Der Seitentitel bei' + url + 'ist'););

Wenn Sie nicht alle Funktionen nutzen möchten, können Sie das verwenden dann() Methode. Jeder dann() Der Methodenaufruf wird als Schritt im Stack hinzugefügt und linear ausgeführt. Statt den oben genannten könnten Sie Folgendes haben:

 casper.start (url); casper.then (function () this.echo ('Hallo, Welt! Der Seitentitel auf' + url + 'ist'););

Ich bevorzuge es zu benutzen dann(), Ich finde es einfacher zu lesen, aber beide sind akzeptabel und es ist alles nur eine Frage des Geschmacks.

Um den Titel der Seite zu erhalten, gibt es bereits ein getTitle () Methode zur Verfügung, so können wir das einfach in unserem verwenden Echo.

 casper.start (url); casper.then (function () this.echo ('Hallo, Welt! Der Seitentitel auf' + url + 'lautet' + this.getTitle ()););

Zum Schluss machen wir unsere Schritte mit dem Lauf() Diese Methode ist zwingend erforderlich, damit das Casper-Skript ausgeführt werden kann. Diese Methode kann auch optional sein onComplete Callback wird ausgeführt, sobald alle Schritte abgeschlossen sind. Wenn Sie den Rückruf verwendet haben, müssen Sie sicherstellen, dass Sie den Casper-Prozess mithilfe von beenden Ausfahrt() Methode. Hier ist ein Beispiel von beiden:

 // Dies muss nicht die Exit-Methode verwenden. casper.run (); // ODER // dies erfordert die Exit-Methode casper.run (function () this.echo ('Alles im Stapel ist beendet'); this.exit ();)

Alternativ können Sie die Exit-Methode auch nach dem Echo verketten:

casper.run (function () this.echo ('Alles im Stapel ist beendet'). exit ();)

Wieder nur eine Frage des Geschmacks.

Nun sollte unser komplettes HelloCasper.js-Skript so aussehen:

var casper = requir ("casper"). create (); var url = casper.cli.args [0]; casper.start (url, function () this.echo ('Hallo, Welt! Der Seitentitel auf' + url + 'lautet' + this.getTitle ());); casper.run (function () this.echo ('Alles im Stapel ist beendet.'). exit (););

Wir können das Casper-Skript jetzt mit dem folgenden Befehl ausführen:

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

Es macht nichts anderes als das, was wir bereits mit Phantom gemacht haben. Casper gibt uns nur eine nette API (mit ein paar zusätzlichen Extras), um auf Phantom zu sitzen, und macht den Code, den wir schreiben, etwas ausführlicher und lesbarer Besonders hilfreich, wenn Sie Skripts schreiben, die auf einer Website navigieren müssen.

Jetzt können wir einige Schnappschüsse unseres Bildschirms speichern.


Schnappschuss-Grundlagen

Ich werde mit einer Datei namens casperscreens.js beginnen und Casper instanziieren. Richten Sie dann ein Array ein, das unsere gewünschten Ansichtsfenster-Breiten enthält, mit denen wir Screenshots aufnehmen möchten. Jedes Element im Array besteht aus einem anderen Array, dessen Breite und Höhe wir einstellen möchten.

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

Ich werde auch eine Variable zum Abrufen der URL aus der Befehlszeile festlegen und dann eine Regex für die URL ausführen, um ein Verzeichnis zu erstellen, in dem die Screenshots gespeichert werden. Ich werde nur die http: // Teil und ersetzen Sie die Punkte durch Bindestriche. Dann werden wir rennen casper.start ().

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

Jetzt werden wir eine Schleife verwenden und für jede Größe des Darstellungsbereichs einen Screenshot der angegebenen URL erstellen. Wir setzen das Ansichtsfenster auf die Größen, die in dem Arrayelement definiert sind, in dem wir uns befinden - öffnen Sie die URL - warten Sie 5000 Millisekunden, um sicherzustellen, dass die Seite geladen wurde - und erfassen Sie dann zwei Arten von Screenshots.

Die erste ist für die tatsächliche Höhe und Breite definiert, hierfür verwenden wir die Erfassung() Methode, die zwei Argumente akzeptiert - eine Zeichenfolge für die Ausgabedatei und ein Objektargument, um festzulegen, welcher Teil der Seite abgeschnitten werden soll. Die zweite ist für einen kompletten Seiten-Screenshot mit nur der definierten Breite, und wir verwenden dazu die captureSelector () Methode, die den Bereich innerhalb des definierten Selektors erfasst, in unserem Fall verwenden wir nur Karosserie und diese Methode benötigt zwei Argumente, wobei das erste der Dateiname und das zweite der Selektor ist.

Obwohl der tatsächlich definierte Screenshot nützlich ist, habe ich festgestellt, dass es hilfreich ist, auch einen vollständigen, chromlosen Screenshot zu haben, damit Sie sehen können, wie die gesamte Seite fließt.

casper.each (viewportSizes, function (self, viewportSize, i) // Legen Sie zwei Werte für die Höhe und Breite des Viewports fest, während wir jedes Element im Viewport-Array durchlaufen. var width = viewportSize [0], height = viewportSize [1] ; // etwas Zeit zum Laden der Seite geben casper.wait (5000, function () // Setzt den Viewport auf die gewünschte Höhe und Breite. this.viewport (width, height); casper.thenOpen (url, function () this.echo ('Opening at' + width); // Setze zwei vars ein, eine für das ganzseitige Speichern, eine für das aktuelle Ansichtsfenster. save var FPfilename = saveDir + '/ fullpage-' + width + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Der Capture-Selektor erfasst den gesamten Körper this.captureSelector (FP-Dateiname, 'body'); // Capture fängt eine definierte Auswahl der page this.capture (AC-Dateiname, oben: 0, links: 0, Breite: Breite, Höhe: Höhe); this.echo ('Momentaufnahme aufgenommen'););););

Zum Schluss nennen wir das Lauf() Methode und in der Rückruffunktion werde ich nur sagen, dass die Erfassung abgeschlossen ist.

casper.run (function () this.echo ('Fertige Captures für' + url) .exit (););

Das vollständige Skript sollte jetzt so aussehen:

 var casper = required ("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, '-'). ersetzen (/ ^ https? - + /, "); casper .start (); casper.each (viewportSizes, function (self, viewportSize, i) // Legen Sie zwei Vars für die Höhe und Breite des Viewports fest, während wir jedes Element im Viewport-Array durchlaufen. var width = viewportSize [0], height) = viewportSize [1]; // Zeit für die Seite zum Laden von casper.wait (5000, function () ). // Setzen Sie den Viewport auf die gewünschte Höhe und Breite. this.viewport (width, height); casper.thenOpen ( url, function () this.echo ('Opening at' + width); // Richten Sie zwei vars ein, eine für das ganzseitige Speichern, eine für den aktuellen Viewport. save var FPfilename = saveDir + '/ fullpage-' + width + ".png"; var ACfilename = saveDir + '/' + width + '-' + height + ".png"; // Der Capture-Selektor erfasst den gesamten Körper this.captureSelector (FP-Dateiname, 'body'); // erfasst Snaps eine definierte Auswahl o f der Seite this.capture (AC-Dateiname, oben: 0, links: 0, Breite: Breite, Höhe: Höhe); this.echo ("Momentaufnahme"); ); ); ); casper.run (function () this.echo ('Fertige Captures für' + url) .exit (););

Und jetzt können wir dieses Skript mit dem folgenden Befehl ausführen:

casperjs casperscreens.js http://todomvc.com

Ich habe mich dazu entschieden, einige Bildschirme von todomvc.com aufzunehmen, einfach weil es eine responsive Seite ist, auf der die Ergebnisse angezeigt werden, nach denen wir suchen.

Wenn Sie nun zu dem Verzeichnis navigieren, von dem aus das Skript ausgeführt wurde, wird ein neues Verzeichnis erstellt, in dem sich alle PNG-Dateien befinden.



Einpacken

Wir haben es also geschafft, ein kleines bisschen JavaScript zu schreiben, das eine Menge Ärger erspart. Das nächste Mal, wenn der Chef oder der Kunde ein paar Screenshots wünscht, und ein zusätzliches Skript zur Verfügung stellt, das wir in unsere Toolbox aufnehmen können, wenn wir ein paar Tests durchführen . Sicher, dies zeigt uns nur ein WebKit-Rendering, aber für viele ist das gut genug.

Versuchen Sie nun, dies in Ihren Build-Prozess zu integrieren, führen Sie es zusammen mit Ihren anderen Tests aus und verwenden Sie die Bildschirmaufnahmefunktion, um nicht nur die Reaktionsfähigkeit Ihrer Website zu testen, sondern auch, wie die Reise eines Benutzers auf den Bildschirmen unterschiedlicher Größe aussehen kann. Überprüfen Sie auch das Grunt-Plugin Grunt-Casper, wenn Grunt Teil Ihres Build-Prozesses ist.

Wenn Sie ein Fan von CoffeeScript sind, können Sie sogar versuchen, dieses Skript in der CoffeeScript-Syntax neu zu schreiben. Stellen Sie nur sicher, dass Ihre Datei mit der Endung endet .Kaffee Erweiterung:

 casperjs casperscreen.coffee http://example.com

Sie müssen sich nicht einmal Gedanken machen, Ihre CoffeeScript-Casper-Skripts vorab zu kompilieren.

Sowohl CasperJS als auch PhantomJS bieten so viel mehr. Sehen Sie sich also die jeweiligen Websites an und erfahren Sie, wie sie bei Ihren Tests helfen können.