About
The Chrome DevTool protocol (CDP) is a API that permits to call browsers implementing the CDP api (chrome of course but also any other browser implementation 1)) via json RPC.
The protocol is used to communicate with Chrome and drive the headless browser instance.
Usage
- IDE like Sublime, VS Code, and Node use it to remote debugging an application.
- Automate the browser
- Test application
This is a low level api. The webdriver API or puppeteer like API are higher level API based on this protocol that are easier to use to control a browser.
API
The API is divided into a number of domains (DOM, Debugger, Network etc.). Chrome DevTools protocol has APIs to interact with many different parts of the browser. These parts are called Targets such as:
- …
where:
- Each domain defines a number of commands it supports and events it generates.
- Both commands and events are serialized JSON objects of a fixed structure.
- Each command is a JavaScript struct with:
- an id, (It must be unique, the responses will have the same 'id')
- a method,
- and an optional params.
Start Sequence
Enabling the DevTools protocol
To enable the DevTools protocol, you need to start chrome with the –remote-debugging-port flag
- In Headless mode (without the UI)
google-chrome-stable --headless --remote-debugging-port=9222 &
# With the UI
google-chrome --remote-debugging-port=9222
If the port is 0, the CDP server prints its WebSocket URL to stdout and the client need to parses it to get the port.
Example:
DevTools listening on ws://127.0.0.1:36775/devtools/browser/a292f96c-7332-4ce8-82a9-7411f3bd280a
Test that it's up
Since you don't have browser UI to see the page, you can navigate to http://localhost:9222 in another browser to check that everything is working.
You should see a list of inspectable pages where you can click through and see what Headless is rendering.
Client Connection and request
- The client create a WebSocket to connect to the URL
- The client start sending CDP commands (based on JSONRPC)
Example
Directly via Websocket
Create a websocket and issue CDP commands. 2)
const ws = new WebSocket(browser.wsEndpoint(), {perMessageDeflate: false});
await new Promise(resolve => ws.once('open', resolve));
console.log('connected!');
ws.on('message', msg => console.log(msg));
console.log('Sending Target.setDiscoverTargets');
ws.send(JSON.stringify({
id: 1,
method: 'Target.setDiscoverTargets',
params: {
discover: true
},
}));
With a CDP driver library
With the chrome-remote-interface CDP driver 3)
- Launch chrome with CDP enabled if needed
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) => {
...
});
- Use the chrome-remote-interface library
const CDP = require('chrome-remote-interface');
CDP((client) => {
// Extract used DevTools domains.
const {Page, Runtime} = client;
// Enable events on domains we are interested in.
Promise.all([
Page.enable()
]).then(() => {
return Page.navigate({url: 'https://example.com'});
});
// Evaluate outerHTML after page has loaded.
Page.loadEventFired(() => {
Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
console.log(result.result.value);
client.close();
});
});
}).on('error', (err) => {
console.error('Cannot connect to browser:', err);
});
Tools
Cli / Repl
The chrome-remote-interface has a client 4) that permits to run as a client.
yarn global add chrome-remote-interface
# or
npm install -g chrome-remote-interface
It is possible to perform command execution (repl) and event binding, using the chrome-remote-interface inspect inspect subcommand
Protocol Monitor
To see all CDP command that performs the chrome browser, you can use the protocol-monitor. It provides a way to view all the CDP requests and responses made by DevTools.
Library
Protocol Driver Library
Library are language wrapper around the chrome devtool protocol
Node:
Php:
C++ library:
More:
Higher Library
Higher level library based on the Protocol Driver Library
- Puppeteer: Node library developed by the Chrome team - use a bundled version of Chromium instead of the one installed on your system.