# chrome-remote-interface [![Build Status][]][travis]
[Build Status]: https://app.travis-ci.com/cyrus-and/chrome-remote-interface.svg?branch=master
[travis]: https://app.travis-ci.com/cyrus-and/chrome-remote-interface
[Chrome Debugging Protocol] interface that helps to instrument Chrome (or any
other suitable [implementation](#implementations)) by providing a simple
abstraction of commands and notifications using a straightforward JavaScript
API.
This module is one of the many [third-party protocol clients][3rd-party].
[3rd-party]: https://developer.chrome.com/devtools/docs/debugging-clients#chrome-remote-interface
## Sample API usage
The following snippet loads `https://github.com` and dumps every request made:
```js
const CDP = require('chrome-remote-interface');
async function example() {
let client;
try {
// connect to endpoint
client = await CDP();
// extract domains
const {Network, Page} = client;
// setup handlers
Network.requestWillBeSent((params) => {
console.log(params.request.url);
});
// enable events then start!
await Network.enable();
await Page.enable();
await Page.navigate({url: 'https://github.com'});
await Page.loadEventFired();
} catch (err) {
console.error(err);
} finally {
if (client) {
await client.close();
}
}
}
example();
```
Find more examples in the [wiki]. You may also want to take a look at the [FAQ].
[wiki]: https://github.com/cyrus-and/chrome-remote-interface/wiki
[async-await-example]: https://github.com/cyrus-and/chrome-remote-interface/wiki/Async-await-example
[FAQ]: https://github.com/cyrus-and/chrome-remote-interface#faq
## Installation
npm install chrome-remote-interface
Install globally (`-g`) to just use the [bundled client](#bundled-client).
## Implementations
This module should work with every application implementing the
[Chrome Debugging Protocol]. In particular, it has been tested against the
following implementations:
Implementation | Protocol version | [Protocol] | [List] | [New] | [Activate] | [Close] | [Version]
---------------------------|--------------------|------------|--------|-------|------------|---------|-----------
[Chrome][1.1] | [tip-of-tree][1.2] | yes¹ | yes | yes | yes | yes | yes
[Opera][2.1] | [tip-of-tree][2.2] | yes | yes | yes | yes | yes | yes
[Node.js][3.1] ([v6.3.0]+) | [node][3.2] | yes | no | no | no | no | yes
[Safari (iOS)][4.1] | [*partial*][4.2] | no | yes | no | no | no | no
[Edge][5.1] | [*partial*][5.2] | yes | yes | no | no | no | yes
[Firefox (Nightly)][6.1] | [*partial*][6.2] | yes | yes | no | yes | yes | yes
¹ Not available on [Chrome for Android][chrome-mobile-protocol], hence a local version of the protocol must be used.
[chrome-mobile-protocol]: https://bugs.chromium.org/p/chromium/issues/detail?id=824626#c4
[1.1]: #chromechromium
[1.2]: https://chromedevtools.github.io/devtools-protocol/tot/
[2.1]: #opera
[2.2]: https://chromedevtools.github.io/devtools-protocol/tot/
[3.1]: #nodejs
[3.2]: https://chromedevtools.github.io/devtools-protocol/v8/
[4.1]: #safari-ios
[4.2]: http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/inspector/protocol
[5.1]: #edge
[5.2]: https://docs.microsoft.com/en-us/microsoft-edge/devtools-protocol/0.1/domains/
[6.1]: #firefox-nightly
[6.2]: https://firefox-source-docs.mozilla.org/remote/index.html
[v6.3.0]: https://nodejs.org/en/blog/release/v6.3.0/
[Protocol]: #cdpprotocoloptions-callback
[List]: #cdplistoptions-callback
[New]: #cdpnewoptions-callback
[Activate]: #cdpactivateoptions-callback
[Close]: #cdpcloseoptions-callback
[Version]: #cdpversionoptions-callback
The meaning of *target* varies according to the implementation, for example,
each Chrome tab represents a target whereas for Node.js a target is the
currently inspected script.
## Setup
An instance of either Chrome itself or another implementation needs to be
running on a known port in order to use this module (defaults to
`localhost:9222`).
### Chrome/Chromium
#### Desktop
Start Chrome with the `--remote-debugging-port` option, for example:
google-chrome --remote-debugging-port=9222
##### Headless
Since version 59, additionally use the `--headless` option, for example:
google-chrome --headless --remote-debugging-port=9222
#### Android
Plug the device and enable the [port forwarding][adb], for example:
adb forward tcp:9222 localabstract:chrome_devtools_remote
Note that in Android, Chrome does not have its own protocol available, a local
version must be used. See [here](#chrome-debugging-protocol-versions) for more information.
[adb]: https://developer.chrome.com/devtools/docs/remote-debugging-legacy
##### WebView
In order to be inspectable, a WebView must
be [configured for debugging][webview] and the corresponding process ID must be
known. There are several ways to obtain it, for example:
adb shell grep -a webview_devtools_remote /proc/net/unix
Finally, port forwarding can be enabled as follows:
adb forward tcp:9222 localabstract:webview_devtools_remote_<pid>
[webview]: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/webviews#configure_webviews_for_debugging
### Opera
Start Opera with the `--remote-debugging-port` option, for example:
opera --remote-debugging-port=9222
### Node.js
Start Node.js with the `--inspect` option, for example:
node --inspect=9222 script.js
### Safari (iOS)
Install and run the [iOS WebKit Debug Proxy][iwdp]. Then use it with the `local`
option set to `true` to use the local version of the protocol or pass a custom
descriptor upon connection (`protocol` option).
[iwdp]: https://github.com/google/ios-webkit-debug-proxy
### Edge
Start Edge with the `--devtools-server-port` option, for example:
MicrosoftEdge.exe --devtools-server-port 9222 about:blank
Please find more information [here][edge-devtools].
[edge-devtools]: https://docs.microsoft.com/en-us/microsoft-edge/devtools-protocol/
### Firefox (Nightly)
Start Firefox with the `--remote-debugging-port` option, for example:
firefox --remote-debugging-port 9222
Bear in mind that this is an experimental feature of Firefox.
## Bundled client
This module comes with a bundled client application that can be used to
interactively control a remote instance.
### Target management
The bundled client exposes subcommands to interact with the HTTP frontend
(e.g., [List](#cdplistoptions-callback), [New](#cdpnewoptions-callback), etc.),
run with `--help` to display the list of available options.
Here are some examples:
```js
$ chrome-remote-interface new 'http://example.com'
{
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01",
"id": "b049bb56-de7d-424c-a331-6ae44cf7ae01",
"thumbnailUrl": "/thumb/b049bb56-de7d-424c-a331-6ae44cf7ae01",
"title": "",
"type": "page",
"url": "http://example.com/",
"webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/b049bb56-de7d-424c-a331-6ae44cf7ae01"
}
$ chrome-remote-interface close 'b049bb56-de7d-424c-a331-6ae44cf7ae01'
```
### Inspection
Using the `inspect` subcommand it is possible to perform [command execution](#clientdomainmethodparams-callback)
and [event binding](#clientdomaineventcallback) in a REPL fashion that provides completion.
Here is a sample session:
```js
$ chrome-remote-interface inspect
>>> Runtime.evaluate({expression: 'window.location.toString()'})
{ result: { type: 'string', value: 'about:blank' } }
>>> Page.enable()
{}
>>> Page.loadEventFired(console.log)
[Function]
>>> Page.navigate({url: 'https://github.com'})