monitorlose Chrome-Version-Shell

Die monitorlose Chrome-Version-Shell wurde in Chrome 59 eingeführt. Damit lässt sich der Chrome-Browser in einer monitorlosen Umgebung ausführen. Im Grunde wird Chrome ohne Chrome ausgeführt. Sie bietet alle modernen Webplattformfunktionen von Chromium und der Blink-Rendering-Engine in der Befehlszeile.

Ein monitorloser Browser ist ein hervorragendes Tool für automatisierte Tests und Serverumgebungen, in denen keine sichtbare UI-Shell erforderlich ist. Sie können beispielsweise einige Tests auf einer echten Webseite ausführen, eine PDF-Datei davon erstellen oder einfach prüfen, wie der Browser eine URL rendert.

Monitorlose Version starten (CLI)

Die einfachste Möglichkeit, mit dem monitorlosen Modus zu beginnen, besteht darin, die Chrome-Binärdatei über die Befehlszeile zu öffnen. Wenn Sie Chrome 59 oder höher installiert haben, starten Sie Chrome mit dem Flag --headless:

chrome \
--headless \                   # Runs Chrome in headless mode.
--disable-gpu \                # Temporarily needed if running on Windows.
--remote-debugging-port=9222 \
https://www.chromestatus.com   # URL to open. Defaults to about:blank.

chrome sollte auf Ihre Chrome-Installation verweisen. Der genaue Speicherort variiert je nach Plattform. Da ich einen Mac verwende, habe ich praktische Aliase für jede installierte Chrome-Version erstellt.

Wenn Sie die stabile Version von Chrome verwenden und die Beta-Version nicht erhalten können, verwenden Sie chrome-canary:

alias chrome="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
alias chrome-canary="/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary"
alias chromium="/Applications/Chromium.app/Contents/MacOS/Chromium"

Chrome Canary herunterladen.

Befehlszeilenfunktionen

In einigen Fällen müssen Sie die monitorlose Chrome-Version möglicherweise nicht programmatisch skripten. Es gibt einige nützliche Befehlszeilenflags mit denen Sie häufige Aufgaben ausführen können.

DOM drucken

Mit dem Flag --dump-dom wird document.body.innerHTML an stdout gesendet:

    chrome --headless --disable-gpu --dump-dom https://www.chromestatus.com/


### Create a PDF

The `--print-to-pdf` flag creates a PDF of the page:

```shell
chrome --headless --disable-gpu --print-to-pdf https://www.chromestatus.com/

Screenshots erstellen

Verwenden Sie das Flag --screenshot, um einen Screenshot einer Seite zu erstellen:

chrome --headless --disable-gpu --screenshot https://www.chromestatus.com/

# Size of a standard letterhead.
chrome --headless --disable-gpu --screenshot --window-size=1280,1696 https://www.chromestatus.com/

# Nexus 5x
chrome --headless --disable-gpu --screenshot --window-size=412,732 https://www.chromestatus.com/

Wenn Sie --screenshot ausführen, wird im aktuellen Arbeitsverzeichnis eine Datei mit dem Namen screenshot.png erstellt. Wenn Sie Screenshots der gesamten Seite erstellen möchten, ist das etwas aufwendiger. In diesem Blogpost von David Schnurr finden Sie alle Informationen dazu. Weitere Informationen finden Sie unter Using headless Chrome as an automated screenshot tool .

REPL-Modus (Read-Eval-Print-Loop)

Mit dem Flag --repl wird die monitorlose Version in einem Modus ausgeführt, in dem Sie JS-Ausdrücke direkt über die Befehlszeile im Browser auswerten können:

$ chrome --headless --disable-gpu --repl --crash-dumps-dir=./tmp https://www.chromestatus.com/
[0608/112805.245285:INFO:headless_shell.cc(278)] Type a Javascript expression to evaluate or "quit" to exit.
>>> location.href
{"result":{"type":"string","value":"https://www.chromestatus.com/features"}}
>>> quit
$

Chrome ohne Browser-UI debuggen

Wenn Sie Chrome mit --remote-debugging-port=9222 ausführen, wird eine Instanz mit aktiviertem DevTools-Protokoll gestartet. Das Protokoll wird verwendet, um mit Chrome zu kommunizieren und die monitorlose Browserinstanz zu steuern. Es wird auch von Tools wie Sublime, VS Code und Node für das Remote-Debugging einer Anwendung verwendet. #synergy

Da Sie keine Browser-UI haben, um die Seite zu sehen, rufen Sie in einem anderen Browser http://localhost:9222 auf, um zu prüfen, ob alles funktioniert. Sie sehen eine Liste der Seiten, die Sie prüfen können. Klicken Sie darauf, um zu sehen, was die monitorlose Version rendert:

DevTools Remote
UI für das Remote-Debugging der Entwicklertools

Hier können Sie die bekannten Funktionen der Entwicklertools verwenden, um die Seite wie gewohnt zu prüfen, zu debuggen und anzupassen. Wenn Sie die monitorlose Version programmatisch verwenden, ist diese Seite auch ein leistungsstarkes Debugging-Tool, mit dem Sie alle Rohbefehle des DevTools-Protokolls sehen können, die über die Verbindung gesendet werden, um mit dem Browser zu kommunizieren.

Programmatisch verwenden (Node)

Puppeteer

Puppeteer ist eine Node-Bibliothek , die vom Chrome-Team entwickelt wurde. Sie bietet eine API auf übergeordneter Ebene zur Steuerung der monitorlosen (oder vollständigen) Chrome-Version. Sie ähnelt anderen automatisierten Testbibliotheken wie Phantom und NightmareJS, funktioniert aber nur mit den neuesten Chrome-Versionen.

Puppeteer kann unter anderem verwendet werden, um ganz einfach Screenshots zu erstellen, PDFs zu erstellen, auf Seiten zu navigieren und Informationen zu diesen Seiten abzurufen. Ich empfehle die Bibliothek, wenn Sie Browsertests schnell automatisieren möchten. Sie verbirgt die Komplexität des DevTools-Protokolls und übernimmt redundante Aufgaben wie das Starten einer Debugging-Instanz von Chrome.

So installieren Sie sie:

npm i --save puppeteer

Beispiel : User-Agent drucken

const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch();
  console.log(await browser.version());
  await browser.close();
})();

Beispiel : Screenshot der Seite erstellen

const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://www.chromestatus.com', {waitUntil: 'networkidle2'});
  await page.pdf({path: 'page.pdf', format: 'A4'});

  await browser.close();
})();

Weitere Informationen zur vollständigen API finden Sie in der Puppeteer-Dokumentation.

Die CRI-Bibliothek

chrome-remote-interface ist eine Bibliothek auf niedrigerer Ebene als die API von Puppeteer. Ich empfehle sie, wenn Sie direkt mit dem DevTools-Protokoll arbeiten möchten.

Chrome starten

chrome-remote-interface startet Chrome nicht für Sie. Das müssen Sie selbst tun.

Im Abschnitt zur Befehlszeile haben wir Chrome manuell gestartet mit --headless --remote-debugging-port=9222. Um Tests vollständig zu automatisieren, sollten Sie Chrome jedoch über Ihre Anwendung starten.

Eine Möglichkeit ist die Verwendung von child_process:

const execFile = require('child_process').execFile;

function launchHeadlessChrome(url, callback) {
  // Assuming MacOSx.
  const CHROME = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome';
  execFile(CHROME, ['--headless', '--disable-gpu', '--remote-debugging-port=9222', url], callback);
}

launchHeadlessChrome('https://www.chromestatus.com', (err, stdout, stderr) => {
  ...
});

Es wird jedoch schwierig, wenn Sie eine portable Lösung benötigen, die auf mehreren Plattformen funktioniert. Sehen Sie sich nur diesen fest codierten Pfad zu Chrome an :(

ChromeLauncher verwenden

Lighthouse ist ein hervorragendes Tool zum Testen der Qualität Ihrer Web-Apps. In Lighthouse wurde ein robustes Modul zum Starten von Chrome entwickelt, das jetzt für die eigenständige Verwendung extrahiert wurde. Das chrome-launcher NPM-Modul sucht nach der Chrome-Installation, richtet eine Debugging-Instanz ein, startet den Browser und beendet ihn, wenn Ihr Programm fertig ist. Das Beste daran ist, dass es dank Node plattformübergreifend funktioniert.

Standardmäßig versucht chrome-launcher Chrome Canary zu starten (falls installiert). Sie können das aber ändern, um manuell auszuwählen, welche Chrome-Version verwendet werden soll. Installieren Sie es zuerst über npm:

npm i --save chrome-launcher

Beispiel : chrome-launcher verwenden, um die monitorlose Version zu starten

const chromeLauncher = require('chrome-launcher');

// Optional: set logging level of launcher to see its output.
// Install it using: npm i --save lighthouse-logger
// const log = require('lighthouse-logger');
// log.setLevel('info');

/**
 * Launches a debugging instance of Chrome.
 * @param {boolean=} headless True (default) launches Chrome in headless mode.
 *     False launches a full version of Chrome.
 * @return {Promise<ChromeLauncher>}
 */
function launchChrome(headless=true) {
  return chromeLauncher.launch({
    // port: 9222, // Uncomment to force a specific port of your choice.
    chromeFlags: [
      '--window-size=412,732',
      '--disable-gpu',
      headless ? '--headless' : ''
    ]
  });
}

launchChrome().then(chrome => {
  console.log(`Chrome debuggable on port: ${chrome.port}`);
  ...
  // chrome.kill();
});

Wenn Sie dieses Skript ausführen, passiert nicht viel. Im Task-Manager sollte jedoch eine Instanz von Chrome angezeigt werden, in der about:blank geladen wurde. Denken Sie daran, dass es keine Browser-UI gibt. Wir verwenden die monitorlose Version.

Um den Browser zu steuern, benötigen wir das DevTools-Protokoll.

Informationen zur Seite abrufen

So installieren Sie die Bibliothek:

npm i --save chrome-remote-interface
Beispiele

Beispiel : User-Agent drucken

const CDP = require('chrome-remote-interface');

...

launchChrome().then(async chrome => {
  const version = await CDP.Version({port: chrome.port});
  console.log(version['User-Agent']);
});

Ergibt etwa: HeadlessChrome/60.0.3082.0

Beispiel : Prüfen, ob die Website ein Web-App-Manifest hat

const CDP = require('chrome-remote-interface');

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page} = protocol;
await Page.enable();

Page.navigate({url: 'https://www.chromestatus.com/'});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const manifest = await Page.getAppManifest();

  if (manifest.url) {
    console.log('Manifest: ' + manifest.url);
    console.log(manifest.data);
  } else {
    console.log('Site has no app manifest');
  }

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

Beispiel : <title> der Seite mit DOM-APIs extrahieren

const CDP = require('chrome-remote-interface');

...

(async function() {

const chrome = await launchChrome();
const protocol = await CDP({port: chrome.port});

// Extract the DevTools protocol domains we need and enable them.
// See API docs: https://chromedevtools.github.io/devtools-protocol/
const {Page, Runtime} = protocol;
await Promise.all([Page.enable(), Runtime.enable()]);

Page.navigate({url: 'https://www.chromestatus.com/'});

// Wait for window.onload before doing stuff.
Page.loadEventFired(async () => {
  const js = "document.querySelector('title').textContent";
  // Evaluate the JS expression in the page.
  const result = await Runtime.evaluate({expression: js});

  console.log('Title of page: ' + result.result.value);

  protocol.close();
  chrome.kill(); // Kill Chrome.
});

})();

Selenium, WebDriver und ChromeDriver verwenden

Derzeit öffnet Selenium eine vollständige Instanz von Chrome. Mit anderen Worten: Es ist eine automatisierte Lösung, aber nicht vollständig monitorlos. Selenium kann jedoch so konfiguriert werden, dass die monitorlose Chrome-Version ausgeführt wird. Ich empfehle den Artikel Running Selenium with monitorlose Chrome-Version , wenn Sie eine vollständige Anleitung zum Einrichten benötigen. Unten finden Sie jedoch einige Beispiele, die Ihnen den Einstieg erleichtern.

ChromeDriver verwenden

ChromeDriver 2.32 verwendet Chrome 61 und funktioniert gut mit der monitorlosen Chrome-Version.

Installieren:

npm i --save-dev selenium-webdriver chromedriver

Beispiel:

const fs = require('fs');
const webdriver = require('selenium-webdriver');
const chromedriver = require('chromedriver');

const chromeCapabilities = webdriver.Capabilities.chrome();
chromeCapabilities.set('chromeOptions', {args: ['--headless']});

const driver = new webdriver.Builder()
  .forBrowser('chrome')
  .withCapabilities(chromeCapabilities)
  .build();

// Navigate to google.com, enter a search.
driver.get('https://www.google.com/');
driver.findElement({name: 'q'}).sendKeys('webdriver');
driver.findElement({name: 'btnG'}).click();
driver.wait(webdriver.until.titleIs('webdriver - Google Search'), 1000);

// Take screenshot of results page. Save to disk.
driver.takeScreenshot().then(base64png => {
  fs.writeFileSync('screenshot.png', new Buffer(base64png, 'base64'));
});

driver.quit();

WebDriverIO verwenden

WebDriverIO ist eine API auf höherer Ebene über Selenium WebDriver.

Installieren:

npm i --save-dev webdriverio chromedriver

Beispiel: CSS-Funktionen auf chromestatus.com filtern

const webdriverio = require('webdriverio');
const chromedriver = require('chromedriver');

const PORT = 9515;

chromedriver.start([
  '--url-base=wd/hub',
  `--port=${PORT}`,
  '--verbose'
]);

(async () => {

const opts = {
  port: PORT,
  desiredCapabilities: {
    browserName: 'chrome',
    chromeOptions: {args: ['--headless']}
  }
};

const browser = webdriverio.remote(opts).init();

await browser.url('https://www.chromestatus.com/features');

const title = await browser.getTitle();
console.log(`Title: ${title}`);

await browser.waitForText('.num-features', 3000);
let numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} total features`);

await browser.setValue('input[type="search"]', 'CSS');
console.log('Filtering features...');
await browser.pause(1000);

numFeatures = await browser.getText('.num-features');
console.log(`Chrome has ${numFeatures} CSS features`);

const buffer = await browser.saveScreenshot('screenshot.png');
console.log('Saved screenshot...');

chromedriver.stop();
browser.end();

})();

Alte monitorlose Chrome-Version als chrome-headless-shell herunterladen

Ab Chrome Version 112 ist der neue monitorlose Modus von Chrome (--headless=new) verfügbar. In diesem Modus können Entwickler Chrome selbst anstelle einer separaten Binärdatei in einer unbeaufsichtigten Umgebung ohne sichtbare UI ausführen. Das ist nützlich für Tests und Automatisierungsanwendungsfälle.

Es gibt unterschiedliche Anwendungsfälle für die alte monitorlose Shell und den neuen monitorlosen Modus:

  1. Die alte monitorlose Shell ist ein einfacher Wrapper um das Modul //content von Chromium und hat daher deutlich weniger Abhängigkeiten. Insbesondere sind X11/Wayland und D-Bus nicht erforderlich und sie ist in mancher Hinsicht leistungsstärker als der vollständig ausgestattete Chrome-Browser. Dadurch eignet sie sich für Anwendungsfälle wie automatisierte Screenshots oder Web-Scraping.
  2. Der neue monitorlose Modus hingegen ist der echte Chrome-Browser und daher authentischer, zuverlässiger und bietet mehr Funktionen. Dadurch eignet er sich besser für End-to-End-Tests von Web-Apps mit hoher Genauigkeit oder für Tests von Browsererweiterungen.

Mit anderen Worten: Es gibt einen Kompromiss zwischen Leistung und Authentizität. Welcher monitorlose Modus ist für Sie am besten geeignet? Das hängt von Ihrem Anwendungsfall ab.

Ein Diagramm, das die Informationen aus der vorherigen Liste veranschaulicht.

Entwickler und Tester, die für ihre Automatisierungsanwendungsfälle nicht die vollständige Chrome-Funktionalität benötigen, können die alte monitorlose Version verwenden. Andernfalls ist die neue monitorlose Version wahrscheinlich die beste Wahl.

Damit Entwickler und Tester weiterhin zwischen diesen beiden Optionen wählen können, ist die alte monitorlose Implementierung jetzt als eigenständige Binärdatei chrome-headless-shell verfügbar. Diese neuen chrome-headless-shell Binärdateien werden für jede Chrome-Version für Nutzer generiert und sind über die Chrome for Testing-Infrastruktur ab Chrome 120 zum Download verfügbar.

Wie erhalte ich chrome-headless-shell-Binärdateien?

Wie bei anderen Chrome for Testing-Binärdateien ist die einfachste Möglichkeit, chrome-headless-shell für Ihre Plattform herunterzuladen, die Verwendung unseres @puppeteer/browsers Befehlszeilentools, das mit npm verfügbar ist. Hier einige Beispiele:

# Download the latest available `chrome-headless-shell` binary corresponding to the Stable channel.
npx @puppeteer/browsers install chrome-headless-shell@stable

# Download a specific `chrome-headless-shell` version.
npx @puppeteer/browsers install chrome-headless-shell@120.0.6098.0

Wenn Sie lieber eigene automatisierte Skripts zum Herunterladen von chrome-headless-shell-Binärdateien erstellen möchten, sind Sie bei uns genau richtig. Chrome for Testing bietet JSON-API-Endpunkte mit den neuesten verfügbaren Versionen pro Chrome-Release-Version (stabil, Beta, Entwickler und Canary). Eine schnelle Übersicht über den aktuellen Status finden Sie im Dashboard zur Verfügbarkeit von Chrome for Testing.

Feedback

Wir freuen uns auf Ihr Feedback zu chrome-headless-shell. Wenn Sie Probleme haben, können Sie sie gerne melden.

Weitere Ressourcen

Hier finden Sie einige nützliche Ressourcen für den Einstieg:

Docs

Tools

  • chrome-remote-interface – Node Modul, das das DevTools-Protokoll umschließt
  • Lighthouse – automatisiertes Tool zum Testen der Qualität von Web-Apps, das das Protokoll intensiv nutzt
  • chrome-launcher – Node-Modul zum Starten von Chrome, bereit für die Automatisierung

Demos

  • The Headless Web“ – Paul Kinlans hervorragender Blog post zur Verwendung der monitorlosen Version mit api.ai.

FAQ

Benötige ich das Flag --disable-gpu?

Nur unter Windows. Für andere Plattformen ist es nicht mehr erforderlich. Das Flag --disable-gpu ist eine temporäre Problemumgehung für einige Fehler. In zukünftigen Chrome-Versionen ist dieses Flag nicht mehr erforderlich. Weitere Informationen finden Sie unter crbug.com/737678.

Benötige ich also immer noch Xvfb?

Nein. Die monitorlose Chrome-Version verwendet kein Fenster, daher ist kein Anzeigeserver wie Xvfb mehr erforderlich. Sie können Ihre automatisierten Tests problemlos ohne sie ausführen.

Was ist Xvfb? Xvfb ist ein In-Memory-Anzeigeserver für Unix-ähnliche Systeme, mit dem Sie grafische Anwendungen (z. B. Chrome) ohne angeschlossenes physisches Display ausführen können. Viele Nutzer verwenden Xvfb, um ältere Chrome-Versionen für „monitorlose“ Tests auszuführen.

Wie erstelle ich einen Docker-Container, in dem die monitorlose Chrome-Version ausgeführt wird?

Weitere Informationen finden Sie unter lighthouse-ci. Dort finden Sie ein Beispiel für ein Dockerfile, das node:8-slim als Basis-Image verwendet und Lighthouse in App Engine Flex installiert und ausführt.

Kann ich das mit Selenium / WebDriver / ChromeDriver verwenden?

Ja. Weitere Informationen finden Sie unter Selenium, WebDriver und ChromeDriver verwenden.

Wie hängt das mit PhantomJS zusammen?

Die monitorlose Chrome-Version ähnelt Tools wie PhantomJS. Beide können für automatisierte Tests in einer monitorlosen Umgebung verwendet werden. Der Hauptunterschied zwischen den beiden besteht darin, dass Phantom eine ältere Version von WebKit als Rendering-Engine verwendet, während die monitorlose Chrome-Version die neueste Version von Blink verwendet.

Derzeit bietet Phantom auch eine API auf höherer Ebene als das DevTools-Protokoll.

Wo melde ich Fehler?

Fehler in der monitorlosen Chrome-Version können Sie unter crbug.com melden.

Fehler im DevTools-Protokoll können Sie unter github.com/ChromeDevTools/devtools-protocol melden.