RemoteWebDriver BiDirectional API (CDP implementation)

The following examples demonstrate how to leverage BiDi APIs with Remote WebDriver.

Register Basic Auth

Some applications make use of browser authentication to secure pages. With Selenium, you can automate the input of basic auth credentials whenever they arise.

    AtomicReference<DevTools> devToolsAtomicReference = new AtomicReference<>();

    driver = new Augmenter()
            .addDriverAugmentation("chrome",
                    HasAuthentication.class,
                    (caps, exec) -> (whenThisMatches, useTheseCredentials) -> {
                      devToolsAtomicReference.get()
                              .createSessionIfThereIsNotOne();
                      devToolsAtomicReference.get().getDomains()
                              .network()
                              .addAuthHandler(whenThisMatches,
                                      useTheseCredentials);
                    }).augment(driver);

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();
    devToolsAtomicReference.set(devTools);
    ((HasAuthentication) driver).
            register(UsernameAndPassword.of("admin", "admin"));

Mutation Observation

Mutation Observation is the ability to capture events via WebDriver BiDi when there are DOM mutations on a specific element in the DOM.

    AtomicReference<DomMutationEvent> seen = new AtomicReference<>();
    AtomicReference<WebDriver> augmentedDriver = new AtomicReference<>();
    CountDownLatch latch = new CountDownLatch(1);

    driver = new Augmenter()
            .addDriverAugmentation("chrome",
                    HasLogEvents.class,
                    (caps, exec) -> new HasLogEvents() {
                      @Override
                      public <X> void onLogEvent(EventType<X> kind) {

                        kind.initializeListener(augmentedDriver.get());
                      }
                    }).augment(driver);

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();
    augmentedDriver.set(driver);
    ((HasLogEvents) driver).onLogEvent(domMutation(mutation -> {
      if ("cheese".equals(mutation.getAttributeName())) {
        seen.set(mutation);
        latch.countDown();
      }
    }));

Listen to console.log events

Listen to the console.log events and register callbacks to process the event.

    CountDownLatch latch = new CountDownLatch(4);
    driver = new Augmenter().augment(driver);
    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(org.openqa.selenium.devtools.v85.runtime.Runtime.enable());
    devTools.send(Log.enable());

    devTools.addListener(Log.entryAdded(),
                         logEntry -> {
                           System.out.println("log: " + logEntry.getText());
                           System.out.println("level: " + logEntry.getLevel());
                           latch.countDown();
                         });

    devTools.addListener(org.openqa.selenium.devtools.v85.runtime.Runtime.consoleAPICalled(),
                         consoleLog -> System.out.println("Type: " + consoleLog.getType()));

Actions causing JS exceptions

    driver = new Augmenter().augment(driver);
    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    List<JavascriptException> jsExceptionsList = new ArrayList<>();
    devTools.getDomains().events().addJavascriptExceptionListener(jsExceptionsList::add);
    CompletableFuture<JavascriptException> futureJsExc = new CompletableFuture<>();
    devTools.getDomains().events().addJavascriptExceptionListener(futureJsExc::complete);

Network Interception

If you want to capture network events coming into the browser and you want manipulate them you are able to do it with the following examples.

    driver = new Augmenter().augment(driver);
    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    try (NetworkInterceptor interceptor = new NetworkInterceptor(
      driver,
      Route.matching(req -> req.getUri().contains("google"))
        .to(() -> req -> new HttpResponse()
          .setStatus(200)
          .addHeader("Content-Type", MediaType.HTML_UTF_8.toString())
          .setContent(utf8String("Creamy, delicious cheese!"))))) {