Headless Chrome
BlinkOn 8, Tokyo
skyostil@, dvallet@, lushnikov@
Outline
Resource interception
Browser
HTTP request
HTTP response
Resource interception
Browser
HTTP request
HTTP response
DevTools client
Mocked response
Modified request
Resource interception
Browser
HTTP request
HTTP response
DevTools client
Mocked response
Modified request
Rendering control
Headless Browser
Virtual
display
Render
Take screenshot
Rendering control
Browser
Renderer B
Renderer A
Renderer C
Display
Rendering control
Browser
Renderer B
Renderer A
Renderer C
Display
Requesting to render
Rendering control
Browser
Renderer B
Renderer A
Renderer C
Display
Requesting to render
Requesting VSYNC
Rendering control
Browser
Display
VSYNC
Renderer A
Renderer B
Renderer C
Rendering control
Browser
Display
VSYNC
BeginFrame
- animation time
- deadline
Renderer A
Renderer B
Renderer C
Rendering control
Browser
Display
VSYNC
BeginFrameAck + new frame
Renderer A
Renderer B
Renderer C
Rendering control
Browser
Display
VSYNC
Composite
Renderer A
Renderer B
Renderer C
BeginFrameAck + new frame
Rendering control
Browser
Renderer A
Renderer B
Renderer C
DevTools client
Rendering control
Browser
Headless.needsBeginFramesChanged
Renderer A
Renderer B
Renderer C
DevTools client
Rendering control
Browser
Headless.needsBeginFramesChanged
Headless.beginFrame(time)
Renderer A
Renderer B
Renderer C
DevTools client
Rendering control
Browser
Headless.needsBeginFramesChanged
Headless.beginFrame(time)
Headless.beginFrame result
Renderer A
Renderer B
Renderer C
DevTools client
Screenshot
Rendering control
C++ embedder utils: Custom fetch behavior
net::URLRequestJob
ExpeditedDispatcher
DeterministicDispatcher
ThrottledDispatcher
C++ embedder utils: TabSocket
JavaScript context
C++ embedder
Renderer
C++ embedder utils: TabSocket
V8 isolated world
C++ embedder
Renderer
V8 main world
DOM
C++ embedder utils: TabSocket
V8 isolated world
C++ embedder
Renderer
JavaScript
TabSocket.send('hello');
TabSocket.onmessage = (message) => {
console.log(message);
};
C++
SendMessageToContext(const std::string& message,
int context_id);
OnMessageFromContext(const std::string& message,
int context_id);
V8 main world
DOM
macOS/Windows support
./path_to_chrome[.exe] --headless --remote-debugging-port=9222 --disable-gpu
./headless_shell[.exe] --remote-debugging-port=9222 --disable-gpu
Selenium/ChromeDriver support
ChromeOptions options = new ChromeOptions();
options.addArguments("headless");
options.addArguments("window-size=1200x600");
Certificate error handling
Coming soon: ChromeDriver support
const CDP = require('chrome-remote-interface');
CDP(async (client) => {
const {Page, Security} = client;
// ignore all the certificate errors
Security.certificateError(({eventId}) => {
Security.handleCertificateError({
eventId,
action: 'continue'
});
});
await Page.enable(); await Security.enable();
await Security.setOverrideCertificateErrors({override: true});
await Page.navigate({url: 'https://cockroach-adriatic-0001.crdb.io:8080'});
)};
Print-to-PDF
TODO: Further PDF customizations (custom headers, CSS styling)
const CDP = require('chrome-remote-interface');
const fs = require('fs');
CDP(async (client) => {
const {Page} = client;
await Page.enable();
await Page.navigate({url: 'https://github.com'});
await Page.loadEventFired();
const {data} = await Page.printToPDF({
landscape: true,
printBackground: true,
marginTop: 0,
marginBottom: 0,
});
fs.writeFileSync('page.pdf', Buffer.from(data, 'base64'));
});
Downloads
const CDP = require('chrome-remote-interface');
CDP(async (client) => {
const {Page} = client;
await Page.enable();
await Page.setDownloadBehavior({behavior : "allow",
downloadPath: "/tmp/download1"});
Page.navigate({url:"http://ipv4.download.thinkbroadband.com/5MB.zip"});
});
Next for Headless
github.com/GoogleChrome/puppeteer
lushnikov@
What is Puppeteer?
A Node.js library for automating headless Chrome
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://github.com',
{waitUntil: 'networkidle'});
await page.pdf({path: 'page.pdf'});
await browser.close();
})();
Chrome DevTools Protocol
Puppeteer
Headless
Chromium
Large developer demand for automation
Why should we invest here?
Already several existing tools
Our interests:
A new API?
How we develop Puppeteer
Demo
Thanks!
headless-dev@chromium.org�crbug.com (Internals>Headless)�github.com/GoogleChrome/puppeteer�