Skip to content

cactuslab/chrome-devtools-java-client

 
 

Repository files navigation

Chrome DevTools Java Client

Description

Chrome DevTools Java Client is a DevTools client - in Java. (: It can be used for instrumenting, inspecting, debuging and profiling Chromium, Chrome and other Blink-based browsers. [1]

For more information on DevTools, see https://chromedevtools.github.io/devtools-protocol/.

v1.3.6 tested on Google Chrome Version 67.0.3396.87. Protocol files from dev-tools-protocol#1aa7b31ca7

v2.1.0 tested on Google Chrome Version 76.0.3809.100. Protocol files from dev-tools-protocol#e1fb93bd76

v3.0.0 tested on Google Chrome Version 86.0.4240.111. Protocol files from dev-tools-protocol#fcb68d10bc

v4.0.0 tested on Google Chrome Version 90.0.4430.212. Protocol files from dev-tools-protocol#987bbb1124

[1] https://chromedevtools.github.io/devtools-protocol/.

Usage

Add the following dependency to your pom.xml:

<dependency>
  <groupId>com.github.kklisura.cdt</groupId>
  <artifactId>cdt-java-client</artifactId>
  <version>4.0.0</version>
</dependency>

You can use following code, taken from, LogRequestsExample:

package com.github.kklisura.cdt.examples;

import com.github.kklisura.cdt.launch.ChromeLauncher;
import com.github.kklisura.cdt.protocol.commands.Network;
import com.github.kklisura.cdt.protocol.commands.Page;
import com.github.kklisura.cdt.services.ChromeDevToolsService;
import com.github.kklisura.cdt.services.ChromeService;
import com.github.kklisura.cdt.services.types.ChromeTab;

/**
 * Log requests example with DevTools java client.
 *
 * <p>The following example will open chrome, create a tab with about:blank url, subscribe to
 * requestWillBeSent event and then navigate to github.com.
 *
 * @author Kenan Klisura
 */
public class LogRequestsExample {
  public static void main(String[] args) {
    // Create chrome launcher.
    final ChromeLauncher launcher = new ChromeLauncher();

    // Launch chrome either as headless (true) or regular (false).
    final ChromeService chromeService = launcher.launch(false);

    // Create empty tab ie about:blank.
    final ChromeTab tab = chromeService.createTab();

    // Get DevTools service to this tab
    final ChromeDevToolsService devToolsService = chromeService.createDevToolsService(tab);

    // Get individual commands
    final Page page = devToolsService.getPage();
    final Network network = devToolsService.getNetwork();

    // Log requests with onRequestWillBeSent event handler.
    network.onRequestWillBeSent(
        event ->
            System.out.printf(
                "request: %s %s%s",
                event.getRequest().getMethod(),
                event.getRequest().getUrl(),
                System.lineSeparator()));

    network.onLoadingFinished(
        event -> {
          // Close the tab and close the browser when loading finishes.
          chromeService.closeTab(tab);
          launcher.close();
        });

    // Enable network events.
    network.enable();

    // Navigate to github.com.
    page.navigate("http://github.com");

    devToolsService.waitUntilClosed();
  }
}

For more examples, see examples.

Isolating cookies between tabs (browser contexts)

By default every tab you open — whether via chromeService.createTab() or Target.createTarget(...) — lives in Chrome's default browser context. All tabs in the default context share a single cookie jar, local storage, cache and so on, so a cookie set in one tab is visible to every other tab. When a single Chrome instance is reused to run unrelated jobs (for example a print service running many jobs as tabs), that state leaks between them.

To isolate a job, give it its own browser context — the headless equivalent of an incognito profile — and create its tab inside that context:

final ChromeService chromeService = launcher.launch(true);

// A dev tools service connected to the browser endpoint (not a tab), for
// browser-level commands such as Target.createBrowserContext.
final ChromeDevToolsService browserDevToolsService =
    chromeService.createBrowserDevToolsService();
final Target target = browserDevToolsService.getTarget();

// Create an isolated browser context and a page (target) inside it.
final String browserContextId = target.createBrowserContext();
final String targetId =
    target.createTarget(
        new CreateTargetParameters()
            .setUrl("about:blank")
            .setBrowserContextId(browserContextId));

// Attach a dev tools service directly to that target by its id.
try (ChromeDevToolsService devToolsService =
    chromeService.createDevToolsService(targetId)) {
  final Page page = devToolsService.getPage();
  final Network network = devToolsService.getNetwork();

  // ...drive the page; cookies set here are confined to browserContextId...
}

// Disposing the context discards its cookies and storage, and closes its target.
target.disposeBrowserContext(browserContextId);

createDevToolsService(String targetId) attaches to a target created over the protocol, for which there is no ChromeTab entry in /json/list. createBrowserDevToolsService() connects to the browser endpoint itself rather than to a tab.

Each ChromeDevToolsService is AutoCloseable: closing it shuts the WebSocket and removes itself from the ChromeService cache, so per-job services don't accumulate. Use try-with-resources as above, or call close() when the job is done.

Known-issues

API hangs (ie when printing PDFs)

What: If you're using cdt-java-client before version 2.1.0 for printing to PDF or using API which requests large amount of data, API may hang if the requesting data exceeds 4MB.

Why: This is due to underlying WebSocket library having 4MB buffer for receiving data from browser.

How to fix: With the version 2.1.0 and above, this buffer was increased to 8MB and can be further increased if necessary by setting the appropriate configuration property.

Debugging chrome

In order to debug chrome when using this library, set the logger com.github.kklisura.cdt.launch.chrome.output to DEBUG level. See ChromeLoggingExample for more information. Be sure to remove or turn the logger off, when done.

Running unit tests

make verify

Sonar analysis

make sonar-analysis

Download latest protocol

Run following:

make download-latest-protocol

This will download browser_protocol.json and js_protocol.json (protocol definitions) from https://github.com/ChromeDevTools/devtools-protocol repo.

Update protocol (generate Java files from protocol definitions)

Make sure you have correct or latest protocol definitions. See Download latest protocol on how to update protocol definitions to latest version.

Run following:

make update-protocol

This will build the tools for parsing and generating Java files, cdt-java-protocol-builder project. The input for this tool are protocol definitions files: browser_protocol.json and js_protocol.json. The generated Java files will be present in cdt-java-client project. After building Java files, the cdt-java-client will be compiled. If everything goes successfully, consider the protocol updated. :)

Updating copyright license header

To go over each module and each source java file to update copyright license header, run:

make update-copyright-license-header

Publishing

A reminder for how to publish the project to Maven Central.

  • Update the version number in cdt-java-client/pom.xml
cd cdt-java-client
make deploy

License

Chrome DevTools Java Client is licensed under the Apache License, Version 2.0. See LICENSE for the full license text.

About

Chrome DevTools java client.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Java 99.9%
  • Makefile 0.1%