So funktioniert Headless Chrome

Aus dem Namen geht bereits hervor, dass ein kopfloser Browser etwas ohne Kopf ist. Im Kontext eines Frontends ist es ein unverzichtbares Werkzeug für einen Entwickler, mit dem Sie den Code testen, die Qualität und Übereinstimmung mit dem Layout überprüfen können. Vitaliy Slobodin von Frontend Conf entschied, dass es notwendig sei, das Gerät dieses Tools näher kennenzulernen.

Unter den Schnittkomponenten und Funktionen von Headless Chrome finden Sie interessante Szenarien für die Verwendung von Headless Chrome. Der zweite Teil über Puppeteer ist eine praktische Node.js-Bibliothek zum Verwalten des Headless-Modus in Google Chrome und Chromium.


Über den Sprecher: Vitaliy Slobodin - ein ehemaliger Entwickler von PhantomJS - derjenige, der es geschlossen und begraben hat. Manchmal hilft es Konstantin Tokarev ( annulen ) in der "wiederbelebten" Version von QtWebKit - dem QtWebKit, in dem ES6, Flexbox und viele andere moderne Standards unterstützt werden.

Vitaliy liebt es, Browser zu erkunden, sich in seiner Freizeit mit WebKit, Chrome usw. zu beschäftigen und vieles mehr. Wir werden heute über Browser sprechen, nämlich über kopflose Browser und ihre gesamte Geisterfamilie.

Was ist ein kopfloser Browser?


Schon aus dem Namen geht hervor, dass dies etwas ohne Kopf ist. In einem Browserkontext bedeutet dies Folgendes.

  1. Es gibt keine echte Wiedergabe des Inhalts , das heißt, es zeichnet alles in Erinnerung.
  2. Aus diesem Grund wird weniger Speicherplatz benötigt , da keine Bilder oder Gigabyte-PNGs gezeichnet werden müssen, die mit einer Bombe in das Backend eingefügt werden sollen.
  3. Es funktioniert schneller, da nichts auf dem realen Bildschirm gerendert werden muss.
  4. Hat eine Programmierschnittstelle für die Verwaltung . Sie fragen - er hat keine Schnittstelle, Schaltflächen, Fenster? Wie geht man damit um? Daher verfügt es natürlich über eine Schnittstelle für die Verwaltung.
  5. Eine wichtige Eigenschaft ist die Möglichkeit, auf einem nackten Linux-Server zu installieren . Dies ist erforderlich, damit Sie bei einem frisch installierten Ubuntu oder Red Hat einfach die Binärdatei löschen oder das Paket dort ablegen können und der Browser sofort funktioniert. Es wird kein Schamanismus oder Voodoo-Magie benötigt.

Dies ist ein typischer WebKit-basierter Browser. Sie können die Komponenten nicht erfassen - dies ist nur ein visuelles Bild.



Wir interessieren uns nur für die oberste Komponente der Browser-Benutzeroberfläche. Dies ist dieselbe Benutzeroberfläche - Fenster, Menüs, Popup-Benachrichtigungen und alles andere.



So sieht der kopflose Browser aus. Beachten Sie den Unterschied? Wir entfernen die Benutzeroberfläche vollständig. Er ist nicht mehr. Es bleibt nur der Browser übrig .

Heute werden wir über Headless Chrome () sprechen. Was ist der Unterschied zwischen ihnen? In der Tat ist Chrome eine Markenversion von Chromium, die proprietäre Codecs, den gleichen H.264, die Integration mit Google-Diensten und alles andere enthält. Chromium ist nur eine Open Source-Implementierung.



Geburtsdatum von Headless Chrome: 2016. Wenn Sie auf ihn stoßen, können Sie mir eine knifflige Frage stellen: „Wie, ich erinnere mich an die Nachrichten von 2017?“ Tatsache ist, dass ein Team von Ingenieuren von Google die PhantomJS-Entwickler bereits 2016 kontaktierte, als sie gerade mit der Implementierung des Headless-Modus in Chrome begannen. Wir haben ganze Google Docks geschrieben, wie wir die Oberfläche implementieren und so weiter. Dann wollte Google eine Schnittstelle voll kompatibel mit PhantomJS machen. Erst dann kam das Ingenieurteam zu der Entscheidung, eine solche Kompatibilität nicht zu tun.

Wir werden später über die Verwaltungsschnittstelle (API) sprechen, bei der es sich um das Chrome DevTools-Protokoll handelt, und sehen, was Sie damit tun können.

Dieser Artikel basiert auf dem Prinzip der Puppenspielerpyramide (vom englischen Puppenspieler). Ein guter Name wird gewählt - der Puppenspieler ist derjenige, der alle anderen kontrolliert!



An der Basis der Pyramide befindet sich Headless Chrome - Headless Chrome - was ist das?

Kopfloses Chrom




In der Mitte - Headless Browser - das gleiche Chrom oder Chrome (normalerweise Chrom). Es hat die sogenannten Renderer (RENDERER) - Prozesse, die den Inhalt der Seite (Ihres Fensters) zeichnen. Darüber hinaus benötigt jede Registerkarte einen eigenen Renderer. Wenn Sie also viele Registerkarten öffnen, startet Chrome so viele Prozesse zum Rendern.

Hinzu kommt Ihre Bewerbung. Wenn wir Chromium oder Headless Chrome verwenden, befindet sich Chrome darüber oder eine Anwendung, in die Sie es einbetten können. Das nächstgelegene Analogon kann Steam genannt werden. Jeder weiß, dass Steam im Wesentlichen nur ein Browser für die Steam-Website ist. Er ist natürlich nicht kopflos, aber diesem Schema ähnlich.

Es gibt zwei Möglichkeiten, kopfloses Chrome in Ihre Anwendung einzubetten (oder zu verwenden):

  1. Standard, wenn Sie Puppenspieler nehmen und Headless Chrome verwenden.
  2. Wenn Sie die Headless-Bibliothekskomponente verwenden , dh eine Bibliothek, die den Headless-Modus implementiert und in Ihre Anwendung einbettet, z. B. in C ++.

Sie fragen sich vielleicht, warum C ++ im Frontend ist? Die Antwort ist die DevTools C ++ API. Sie können die Funktionen von Headless Chrome auf verschiedene Arten implementieren und verwenden. Wenn Sie Puppeteer verwenden, erfolgt die Kommunikation mit einem Headless-Browser über Web-Sockets. Wenn Sie die Headless-Bibliothek in eine Desktop-Anwendung einbetten, verwenden Sie die native Schnittstelle, die in C ++ geschrieben ist.

Abgesehen davon haben Sie noch weitere Dinge, darunter:

  • Benutzerdefiniertes Netzwerk - Benutzerdefinierte Implementierung der Interaktion mit dem Netzwerk. Angenommen, Sie arbeiten in einer Bank oder einer Regierungsbehörde, die aus drei Buchstaben besteht und mit "F" beginnt und ein sehr kniffliges Authentifizierungs- oder Autorisierungsprotokoll verwendet, das von Browsern nicht unterstützt wird. Daher benötigen Sie möglicherweise einen benutzerdefinierten Handler für Ihr Netzwerk. Sie können einfach Ihre bereits implementierte Bibliothek nehmen und in Chrome verwenden.
  • Mojo-Module . Das nächste Analogon zu Mojo sind die nativen Ordner in Node.js zu Ihren in C ++ geschriebenen nativen Bibliotheken. Mojo macht dasselbe - Sie nehmen Ihre native Bibliothek, schreiben eine Mojo-Oberfläche dafür und können dann die Methoden Ihrer nativen Bibliothek in Ihrem Browser aufrufen.

Chromkomponenten




Wieder höre ich eine knifflige Frage: „Warum brauche ich dieses schreckliche Schema? Ich schreibe unter (geben Sie den Namen Ihres Lieblings-Frameworks ein). “

Ich glaube, dass ein Entwickler wissen sollte, wie sein Tool funktioniert. Wenn Sie unter React schreiben, sollten Sie wissen, wie React funktioniert. Wenn Sie unter Angular schreiben, sollten Sie wissen, was Angular unter der Haube hat.

Denn bei etwas, zum Beispiel einem schwerwiegenden Fehler oder einem sehr schwerwiegenden Fehler in der Produktion, muss man sich mit den "Eingeweiden" auseinandersetzen, und man kann sich dort einfach verlaufen - wo, was und wie. Wenn Sie beispielsweise Tests schreiben oder Headless Chrome verwenden, können auch einige seiner seltsamen Verhaltensweisen und Fehler auftreten. Daher werde ich Ihnen kurz sagen, welche Chromium-Komponenten enthalten sind. Wenn Sie eine große Stapelverfolgung sehen, wissen Sie bereits, wie Sie graben und wie Sie sie überhaupt reparieren können.

Die unterste Ebene der Plattformebene . Seine Komponenten:

  • Mit Ozone , dem abstrakten Fenstermanager in Chrome, interagiert der Fenstermanager des Betriebssystems. Unter Linux ist es entweder ein X-Server oder Wayland. Unter Windows ist es ein Windows-Fenstermanager.
  • Scheduler ist derselbe Scheduler, ohne den wir nirgendwo sind, da wir alle wissen, dass Chrome eine Multiprozessanwendung ist und wir irgendwie alle Threads, Prozesse und alles andere auflösen müssen.
  • Netz - Der Browser sollte immer eine Komponente für die Arbeit mit dem Netzwerk haben, z. B. zum Parsen von HTTP, Erstellen von Headern, Bearbeiten usw.

Die Content-Ebene ist die größte Komponente von Chrome. Es beinhaltet:

  • Blink ist eine WebCore-basierte Web-Engine von WebKit. Es kann HTML als Zeichenfolge verwenden, analysieren, JavaScript ausführen - und das war's. Er weiß nicht mehr, wie man etwas macht: weder mit dem Netzwerk arbeiten noch zeichnen - all dies geschieht zusätzlich zu Blink.
    Blink enthält: eine stark modifizierte Version von WebCore - eine Web-Engine für die Arbeit mit HTML und CSS; V8 (JavaScript-Engine); sowie eine API für alle in Chrome verwendeten Erweiterungen, z. B. einen Werbeblocker. Es enthält auch das DevTools-Protokoll.
  • Die Inhalts-API ist eine Schnittstelle, mit der Sie alle Funktionen der Web-Engine ganz einfach nutzen können. Da es in Blink so viele Dinge gibt (wahrscheinlich mehr als eine Million Schnittstellen), benötigen Sie eine Inhalts-API, um nicht in all diesen Methoden und Funktionen verloren zu gehen. Sie geben HTML ein, die Engine verarbeitet es automatisch, analysiert das DOM, erstellt CSS OM, führt JavaScript aus, führt Timer, Handler und alles andere aus.

Ebene ohne Kopf - Ebene ohne Browser: Kopf ohne Ebene:

  • Kopflose Bibliothek .
  • Embedder-API- Schnittstelle zum Einbetten der Headless-Bibliothek in die Anwendung.
  • Die Client-API ist eine Schnittstelle, die Puppeteer verwendet.

Anwendungsschicht Anwendungsschicht :

  • Ihre Anwendung ( Embedding App );
  • Gadgets, zum Beispiel Headless Shell .

Lassen Sie uns jetzt etwas höher aus den Tiefen aufsteigen, aktivieren - jetzt geht das Frontend.



Chrome DevTools-Protokoll


Wir sind alle auf das Chrome DevTools-Protokoll gestoßen, weil wir das Entwicklerfenster in Chrome oder den Remote-Debugger verwenden - dieselben Entwicklungstools. Wenn Sie die Entwicklertools remote ausführen, erfolgt die Kommunikation mit dem Browser über das DevTools-Protokoll. Wenn Sie den Debugger installieren, lesen Sie die Codeabdeckung, verwenden Sie die Geolokalisierung oder etwas anderes - all dies wird mit DevTools gesteuert.



Tatsächlich verfügt das DevTools-Protokoll selbst über eine Vielzahl von Methoden. Ihr Entwicklertool hat keinen Zugriff, wahrscheinlich auf 80% von ihnen. Wirklich, Sie können dort alles tun!

Mal sehen, worum es in diesem Protokoll geht. In der Tat ist es sehr einfach. Es hat 2 Komponenten:

  1. DevTools-Ziel - die Registerkarte, die Sie untersuchen;
  2. DevTools-Client - Nehmen wir an, dies ist ein Entwicklerpanel, das remote gestartet wird.



Sie kommunizieren mit einfachem JSON:

  • Es gibt eine Kennung für den Befehl, den Namen der auszuführenden Methode und einige Parameter.
  • Wir senden eine Anfrage und erhalten eine Antwort, die ebenfalls sehr einfach aussieht: eine Kennung, die benötigt wird, weil alle Befehle, die mit dem Protokoll ausgeführt werden, asynchron sind. Damit wir immer vergleichen können, welche Antwort auf welches Team wir erhalten haben, benötigen wir eine Kennung.
  • Es gibt ein Ergebnis. In unserem Fall handelt es sich um ein Ergebnisobjekt mit den folgenden Attributen: Typ: "Nummer", Wert: 2, Beschreibung: "2" , es wurde keine Ausnahme ausgelöst: wasThrown: false.

Unter anderem kann Ihre Registerkarte Ereignisse an Sie zurücksenden. Angenommen, wenn ein Ereignis auf einer Seite aufgetreten ist oder eine Ausnahme auf einer Seite aufgetreten ist, erhalten Sie über dieses Protokoll eine Benachrichtigung.





Puppenspieler


Sie können Puppeteer mit Ihrem bevorzugten Paketmanager installieren - sei es Garn, npm oder einem anderen.

Die Verwendung ist ebenfalls einfach - fordern Sie es einfach in Ihrem Node.js-Skript an, und Sie können es bereits verwenden.



Über den Link https://try-puppeteer.appspot.com können Sie ein Skript direkt auf der Site schreiben, ausführen und das Ergebnis direkt im Browser abrufen. All dies wird mit Headless Chrome implementiert.

Betrachten Sie das einfachste Skript unter Node.js:

const puppeteer = require('puppeteer'); (async() => { const browser = await puppeteer.launch() ; const page = await browser.newPage(); await page.goto('http://devconf.ru/') ; await page.emulateMedia('screen') ; await page.pdf({ path: './devconf.pdf, printBackground: true }); await browser.close() ; })(); 

Hier öffnen wir einfach die Seite und drucken sie als PDF aus. Sehen wir uns die Funktionsweise dieses Skripts in Echtzeit an:


Alles wird cool sein, aber es ist nicht klar, was drin ist. Natürlich haben wir einen kopflosen Browser, aber wir sehen nichts. Daher hat Puppenspieler eine spezielle Flagge namens kopflos: false:

 const browser = await puppeteer.launch({ headless: false }); 

Es ist erforderlich, den Headless-Browser im Headful-Modus zu starten, wenn Sie ein Fenster sehen und in Echtzeit sehen können, was mit Ihrer Seite passiert, dh wie Ihr Skript mit Ihrer Seite interagiert.



Dies sieht genauso aus, wenn wir dieses Flag hinzufügen. Links erscheint ein Browserfenster - deutlicher.


Vorteile des Puppenspielers:

+ Dies ist die Node.js-Bibliothek für Chrome Headless.
+ Unterstützung für ältere Versionen von Node.js> = 6.
+ Einfache Installation.
+ High-Level-API für die Verwaltung dieser gesamten riesigen Maschine.

Headless Chrome lässt sich einfach und ohne Systemintervention installieren. Bei der ersten Installation lädt Puppeteer die Version von Chromium herunter und installiert sie direkt im Ordner node_modules, speziell für Ihre Architektur und Ihr Betriebssystem. Sie müssen nichts extra herunterladen, dies geschieht automatisch. Sie können auch Ihre Lieblingsversion von Chrome verwenden, die auf Ihrem System installiert ist. Sie können dies auch tun - Puppeteer bietet Ihnen eine solche API.

Leider gibt es auch Nachteile, wenn wir nur die Grundinstallation nehmen.

Nachteile Puppenspieler :

- Keine Funktionen der obersten Ebene : Synchronisation von Lesezeichen und Passwörtern; Profilunterstützung; Hardwarebeschleunigung etc.
- Software-Rendering ist das wichtigste Minus. Alle Berechnungen und Renderings finden auf Ihrer CPU statt. Aber hier werden uns die Google-Ingenieure bald überraschen - die Arbeiten zur Implementierung der Hardwarebeschleunigung sind bereits im Gange. Schon jetzt können Sie versuchen, es zu benutzen, wenn Sie mutig und mutig sind.
- Bis vor kurzem gab es keine Unterstützung für Erweiterungen - jetzt gibt es! Wenn Sie ein schlauer Entwickler sind, können Sie Ihren bevorzugten AdBlock verwenden, angeben, wie Puppeteer ihn verwenden soll, und alle Anzeigen werden blockiert.
- Keine Audio / Video-Unterstützung . Denn nun, warum Headless-Browser Audio und Video.

Was kann Puppenspieler:

  • Isolationssitzungen.
  • Virtuelle Timer.
  • Abfangen von Netzwerkanforderungen.

Und ein paar coole Dinge, die ich etwas weiter zeigen werde.

Sitzungsisolation


Was ist es, womit wird es gegessen und werden wir nicht ersticken? - Nicht ersticken!

Die Sitzungsisolation ist ein separates „Repository“ für jede Registerkarte . Wenn Sie Puppeteer starten, können Sie eine neue Seite erstellen und jede neue Seite kann ein eigenes Repository haben, einschließlich:

  • kocht
  • lokaler Speicher;
  • Cache.

Alle Seiten werden unabhängig voneinander leben. Dies ist beispielsweise erforderlich, um die Atomizität der Tests aufrechtzuerhalten.

Die Sitzungsisolation spart Ressourcen und Zeit beim Starten paralleler Sitzungen . Angenommen, Sie testen eine Site, die im Entwicklungsmodus erstellt wird, dh das Bundle wird nicht minimiert und wiegt 20 MB. Wenn Sie es nur zwischenspeichern möchten, können Sie Puppeteer anweisen, einen Cache zu verwenden, der allen erstellten Seiten gemeinsam ist. Dieses Bundle wird zwischengespeichert.

Sie können Sitzungen für die spätere Verwendung serialisieren . Sie schreiben einen Test, der eine bestimmte Aktion auf Ihrer Site überprüft. Sie haben jedoch ein Problem - die Website muss autorisiert werden. Sie werden nicht ständig in jedem Test für die Autorisierung auf der Website hinzufügen. Mit Puppeteer können Sie sich einmal bei der Site anmelden und diese Sitzung in Zukunft wiederverwenden.

Virtuelle Timer


Möglicherweise verwenden Sie bereits virtuelle Timer. Wenn Sie den Schieberegler in einem Entwicklertool verschoben haben, das die Animation beschleunigt oder verlangsamt (und danach natürlich Ihre Hände gewaschen hat!), Haben Sie in diesem Moment virtuelle Timer im Browser verwendet.

Der Browser kann virtuelle Timer anstelle von realen verwenden, um die Zeit vorwärts zu scrollen , um das Laden der Seite zu beschleunigen oder die Animation abzuschließen. Angenommen, Sie haben den gleichen Test, gehen zur Hauptseite und dort die Animation für 30 Sekunden. Es ist für niemanden von Vorteil, den Test die ganze Zeit warten zu lassen. Daher können Sie die Animation einfach beschleunigen, sodass sie beim Laden der Seite sofort abgeschlossen wird und Ihr Test fortgesetzt wird.

Sie können die Zeit anhalten, während die Netzwerkanforderung ausgeführt wird . Sie testen beispielsweise die Reaktion Ihrer Anwendung, wenn die Ausführung einer Anforderung, die an das Backend gesendet wurde, sehr lange dauert oder mit einem Fehler zurückgegeben wird. Sie können die Zeit anhalten - Puppenspieler erlaubt es.

Auf der Folie unten gibt es eine weitere Option: Stoppen Sie den Renderer und fahren Sie fort . Im experimentellen Modus konnte der Browser angewiesen werden, nicht zu rendern, und später, falls erforderlich, einen Screenshot anfordern. Dann würde kopfloses Chrome schnell alles rendern, einen Screenshot geben und wieder aufhören, etwas zu zeichnen. Leider ist es den Entwicklern bereits gelungen, das Funktionsprinzip dieser API zu ändern, und es gibt keine solche Funktion mehr.

Eine schematische Ansicht der virtuellen Timer unten.



Die oberste Zeile hat zwei reguläre Timer: Der erste startet in der ersten Zeiteinheit und läuft in einer Zeiteinheit, der zweite startet in der dritten Zeiteinheit und läuft in drei Zeiteinheiten.

Timer beschleunigen - sie starten nacheinander. Wenn wir sie anhalten, haben wir eine Zeitspanne, nach der alle Timer starten.

Betrachten Sie dies als Beispiel. Unten finden Sie einen abgeschnittenen Code, der im Wesentlichen nur die Animationsseite von codepen.io lädt und wartet:

 (async() => { const browser = await puppeteer.launch(); const page = await browser.newPage(); const url = 'https ://codepen.o/ajerez/full/EaEEOW/'; // # 1 await page.goto(url, { waitUnitl: 'load' }); // # 2 })(); 


Diese Demonstration der Implementierung während der Präsentation ist nur eine Animation.

Unter Verwendung des Chrome DevTools-Protokolls senden wir jetzt eine Methode namens Animation.setPlaybackRate. Übergeben Sie ihr eine Wiedergaberate mit dem Wert 12 als Parameter:

 const url = 'https://codepen.o/ajerez/full/EaEEOW/'; // # 1 await page._client.send('Animation.setPlaybackRate', { playbackRate: 12 }); // # 3 await page.goto(url, { waitUntil: 'load' }); // # 2 

Wir laden den gleichen Link und die Animashka begann viel schneller zu arbeiten. Dies liegt an der Tatsache, dass wir einen virtuellen Timer verwendet und die Wiedergabe von Animationen um das 12-fache beschleunigt haben.

Lassen Sie uns jetzt ein Experiment durchführen - PlaybackRate: 0 übergeben - und sehen, was passiert. Und hier wird dies sein: Es gibt überhaupt keine Animation, es wird nicht abgespielt. Null- und negative Werte unterbrechen einfach die gesamte Animation vollständig.

Arbeiten Sie mit Netzwerkanforderungen


Sie können Netzwerkanforderungen abfangen, indem Sie das folgende Flag setzen:

 await page.setRequestlnterception(true); 

In diesem Modus wird ein zusätzliches Ereignis angezeigt, das ausgelöst wird, wenn eine Netzwerkanforderung gesendet oder empfangen wird.

Sie können die Anfrage im laufenden Betrieb ändern . Dies bedeutet, dass Sie den gesamten Inhalt (Text) und die Überschriften vollständig ändern, die Anforderung überprüfen und sogar abbrechen können.

Dies ist erforderlich, um die Autorisierung oder Authentifizierung zu verarbeiten , einschließlich der Basisauthentifizierung über HTTP.

Sie können auch Codeabdeckung (JS / CSS) durchführen . Mit Puppeteer können Sie all dies automatisieren. Wir alle kennen Dienstprogramme, die eine Seite laden, zeigen können, welche Klassen darin verwendet werden usw. Aber sind wir mit ihnen zufrieden? Ich denke nicht.

Der Browser weiß besser, welche Selektoren und Klassen verwendet werden - es ist ein Browser! Er weiß immer, welches JavaScript ausgeführt wird, welches nicht, welches CSS verwendet wird, welches nicht.

Das Chrome DevTools-Protokoll hilft dabei:

 await Promise.all ( [ page.coverage.startJSCoverage(), page.coverage.startCSSCoverage() ]); await page.goto('https://example.com'); const [jsCoverage, cssCoverage] = await Promise,all([ page.coverage.stopJSCoverage(), page.coverage.stopCSSCoverage() ]): 

In den ersten beiden Zeilen starten wir eine relativ neue Funktion, mit der Sie die Codeabdeckung ermitteln können. Führen Sie JS und CSS aus, gehen Sie zu einer Seite und sagen Sie - Stopp - und wir können die Ergebnisse sehen. Und dies sind keine imaginären Ergebnisse, sondern solche, die der Browser aufgrund der Engine sieht.

Unter anderem gibt es bereits ein Plugin, das für Puppenspieler alles nach Istanbul exportiert.

Oben in der Puppenspieler-Pyramide befindet sich ein Skript, das Sie auf Node.js geschrieben haben - es ist wie der Pate in allen unteren Punkten.



Aber ... "im dänischen Königreich ist nicht alles ruhig ..." - wie William Shakespeare schrieb.

Was ist los mit kopflosen Browsern?


Headless-Browser haben Probleme, obwohl all ihre coolen Funktionen so viel können.

Unterschied beim Rendern von Seiten auf verschiedenen Plattformen


Ich liebe diesen Artikel wirklich und rede ständig darüber. Schauen wir uns dieses Bild an.



Hier ist eine reguläre Seite mit einfachem Text: rechts - Rendern in Chrome unter Linux, links - unter Windows. Diejenigen, die mit Screenshots testen, wissen, dass immer ein Wert festgelegt wird, der als "Fehlerquote" bezeichnet wird und bestimmt, wann der Screenshot als identisch angesehen wird und wann nicht.

Tatsächlich besteht das Problem darin, dass unabhängig davon, wie Sie versuchen, diesen Schwellenwert festzulegen, der Fehler immer über diese Linie hinausgeht und Sie immer noch falsch positive Ergebnisse erhalten. Dies liegt daran, dass alle Seiten und sogar Web-Schriftarten auf allen drei Plattformen unterschiedlich gerendert werden - unter Windows nach einem Algorithmus, unter MacOS anders, unter Linux im Allgemeinen einem Zoo. Sie können nicht einfach Screenshots erstellen und testen .

Sie werden sagen: "Ich brauche nur eine Referenzmaschine, auf der ich all diese Tests ausführen und Screenshots vergleichen kann." Tatsächlich ist dies jedoch äußerst unpraktisch, da Sie auf CI warten müssen und hier auf Ihrem Computer lokal überprüfen möchten, ob Sie etwas kaputt gemacht haben. Wenn Sie Referenz-Screenshots auf einem Linux-Computer und einen Mac haben, werden falsche Ergebnisse angezeigt.

Deshalb sage ich, dass man überhaupt nicht mit Screenshots testen sollte - vergiss es.

Übrigens, wenn Sie noch mit Screenshots testen möchten, gibt es einen wunderbaren Artikel von Roman Dvornov: „ Unit-Test mit Screenshots: Durchbrechen der Schallmauer “. Das ist reine Krimis.

Schlösser


Viele große Inhaltsanbieter mögen es nicht, wenn Sie kratzen oder ihre Inhalte auf illegale Weise erhalten. Stellen Sie sich vor, ich bin ein bedeutender Inhaltsanbieter und möchte dasselbe Spiel mit Ihnen spielen. Es gibt zwei GET-Anforderungen in zwei verschiedenen Browsern.


Können Sie sich vorstellen, wo Chrome hier ist? Die Option "beides" wird nicht akzeptiert - Chrome ist nur eine. Höchstwahrscheinlich können Sie diese Frage nicht beantworten, und ich als wichtiger Inhaltsanbieter kann: rechts - PhantomJS und links - Chrome.


Ich kann den Punkt erreichen, an dem ich Ihre Browser erkennen werde (was genau Chrome oder FireFox ist), indem ich die Reihenfolge der HTTP-Header in Ihren Anforderungen anpasse. Wenn der Host zuerst geht - ich weiß ganz genau - ist dies Chrome. Dann kann ich nicht vergleichen. Ja, natürlich gibt es komplexere Algorithmen - wir überprüfen nicht nur die Reihenfolge, sondern auch die Werte usw. usw. Aber es ist wichtig, dass ich Ihre Überschriften besetzen, überprüfen kann, wer Sie sind, und Sie dann einfach blockieren oder nicht blockieren kann.

Einige Funktionen können nicht implementiert werden (Flash)


Haben Sie jemals vertieft, direkt Hardcore, Flash in Browsern studiert? Irgendwie habe ich reingeschaut - dann habe ich sechs Monate lang nicht geschlafen.

Wir alle erinnern uns, wie wir YouTube gesehen haben, als es noch Flash gab: Das Video dreht sich, alles ist in Ordnung. In dem Moment, in dem ein eingebettetes Objekt auf einer Seite wie Flash erstellt wird, fordert es immer ein echtes Fenster von Ihrem Betriebssystem an. Das heißt, zusätzlich zu Ihrem Browserfenster gab es ein weiteres Fenster Ihres Betriebssystems im Flash YouTube-Fenster. Flash kann nur funktionieren, wenn Sie ihm ein echtes Fenster geben - nicht nur ein echtes Fenster, sondern ein Fenster, das auf Ihrem Bildschirm sichtbar ist. Daher können einige Funktionen in Headless-Browsern, einschließlich Flash, nicht implementiert werden.

Vollautomatisierung und Bots


Wie ich bereits sagte, haben große Inhaltsanbieter große Angst, wenn Sie Spinnen oder Grabbings schreiben, die einfach Informationen stehlen, die gegen eine Gebühr bereitgestellt werden.

Es werden verschiedene Tricks angewendet. Es gibt Artikel darüber, wie man kopflose Browser immer noch erkennt. Ich kann sagen, dass Sie keine kopflosen Browser erkennen können . Alle dort beschriebenen Methoden werden umgangen. Zum Beispiel gab es Erkennungsmethoden mit Canvas. Ich erinnere mich, dass es sogar ein Skript gab, das beobachtete, wie sich die Maus über den Bildschirm bewegte und die Leinwand füllte. Wir sind Menschen und bewegen die Maus ziemlich langsam, und Headless Chrome ist viel schneller. Das Skript hat verstanden, dass sich Canvas zu schnell füllt - was bedeutet, dass es sich höchstwahrscheinlich um kopfloses Chrome handelt. Wir haben dies auch umgangen, nur das Verlangsamen des Browsers ist kein Problem.

Es gibt keine Standard-API (Einzel-API)


Wenn Sie kopflose Implementierungen in anderen Browsern gesehen haben - sei es Safari oder FireFox -, wird alles mithilfe der Webdriver-API implementiert. Chrome verfügt über das Chrome DevTools-Protokoll. In Edge ist überhaupt nichts klar - was da ist, was nicht.

WebGL?


Die Leute fragen auch nach WebGL im Headless-Modus. Über diesen Link können Sie auf den Google Chrome Bug Tracker zugreifen. Dort stimmen Entwickler aktiv für die Implementierung des Headless-Modus für WebGL, und schon kann er etwas zeichnen. Sie werden jetzt einfach durch Hardware-Rendering eingeschränkt. Sobald die Implementierung des Hardware-Renderings abgeschlossen ist, ist WebGL automatisch verfügbar, dh es kann etwas im Hintergrund getan werden.

Aber nicht alles ist so schlimm!

Wir haben einen zweiten Player auf dem Markt - am 11. Mai 2018 gab es Neuigkeiten, dass Microsoft in seinem Edge-Browser beschlossen hat, fast dasselbe Protokoll zu implementieren, das in Google Chrome verwendet wird. Sie haben speziell ein Konsortium gegründet, in dem sie ein Protokoll diskutieren, das sie auf einen Industriestandard bringen möchten, damit Sie Ihr Skript unter Edge, Chrome und FireFox ausführen können.

Aber es gibt ein "aber" - Microsoft Edge hat leider keinen Headless-Modus. Sie haben eine Stimmabgabe, in der die Leute schreiben: "Gib uns einen kopflosen Modus!" - aber sie schweigen. Wahrscheinlich etwas im Verborgenen sägen.

TODO (Fazit)


Ich habe das alles gesagt, damit Sie zu Ihrem Manager oder, wenn Sie ein Manager sind, zum Entwickler kommen und sagen können: „Das war's! Wir wollen kein Selen mehr - gib uns Puppenspieler! Wir werden es testen. " In diesem Fall werde ich mich freuen.

Aber wenn Sie wie ich Browser mit Puppeteer lernen, Fehler aktiv posten oder eine Pull-Anfrage senden können, werde ich mich noch mehr freuen. Dieses Tool in OpenSource liegt auf GitHub und ist in Node.js geschrieben. Sie können es einfach ausleihen und dazu beitragen.

Der Fall mit Puppeteer ist insofern einzigartig, als in Google zwei Teams arbeiten: eines befasst sich speziell mit Puppeteer, das andere mit Headless-Modus. Wenn ein Benutzer einen Fehler findet und auf GitHub darüber schreibt, geht der Fehler nicht in Puppeteer, sondern in Headless Chrome an den Befehl Headless Chrome. Wenn sie es dort beheben, wird Puppenspieler sehr schnell aktualisiert. Dies führt zu einem einzigen Ökosystem, wenn die Community zur Verbesserung des Browsers beiträgt.

Daher fordere ich Sie dringend auf, zur Verbesserung des Tools beizutragen, das nicht nur von Ihnen, sondern auch von anderen Entwicklern und Testern verwendet wird.

Kontaktdaten:

  • github.com/vitallium
  • vk.com/vitallium
  • twitter.com/vitalliumm

Frontend Conf Moscow - Eine Fachkonferenz von Front-End-Entwicklern findet am 4. und 5. Oktober in Moskau im Infospace statt. Eine Liste der akzeptierten Berichte wurde bereits auf der Konferenzwebsite veröffentlicht.

In unserem Newsletter führen wir regelmäßig thematische Überprüfungen von Reden durch, sprechen über die veröffentlichten Transkripte und zukünftige Ereignisse - melden Sie sich an, um die Nachrichten zuerst zu erhalten.

Und dies ist ein Link zu unserem Youtube-Kanal im Frontend, der alle Reden enthält, die sich auf die Entwicklung des Client-Teils der Projekte beziehen.

Source: https://habr.com/ru/post/de421137/


All Articles