CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-seleniumhq-selenium--selenium-devtools-v110

Chrome DevTools Protocol (CDP) bindings for Java - version 110, enabling advanced browser automation features like network interception, console event handling, JavaScript execution, and target management.

Pending
Overview
Eval results
Files

javascript.mddocs/

JavaScript Operations

JavaScript evaluation, runtime bindings, and script injection capabilities for advanced browser interaction using Chrome DevTools Protocol v110.

Capabilities

JavaScript Domain Wrapper

High-level wrapper for CDP JavaScript/Runtime functionality providing type-safe access to script execution and runtime bindings.

/**
 * JavaScript domain wrapper for CDP v110 runtime operations
 */
public class v110Javascript extends Javascript<ScriptIdentifier, BindingCalled> {
    /**
     * Initialize JavaScript domain with DevTools session
     * @param devtools Active DevTools session
     */
    public v110Javascript(DevTools devtools);
}

Runtime Domain Control

Enable and disable runtime domain for JavaScript operations.

/**
 * Enable runtime domain for JavaScript execution
 * @return Command to enable runtime
 */
protected Command<Void> enableRuntime();

/**
 * Disable runtime domain
 * @return Command to disable runtime
 */
protected Command<Void> disableRuntime();

JavaScript Bindings

Create bidirectional communication between Java and JavaScript through runtime bindings.

/**
 * Add JavaScript binding to runtime
 * @param scriptName Name of binding in JavaScript global scope
 * @return Command to add binding
 */
protected Command<Void> doAddJsBinding(String scriptName);

/**
 * Remove JavaScript binding from runtime
 * @param scriptName Name of binding to remove
 * @return Command to remove binding
 */
protected Command<Void> doRemoveJsBinding(String scriptName);

/**
 * Get binding called events
 * @return Event stream for binding calls
 */
protected Event<BindingCalled> bindingCalledEvent();

/**
 * Extract payload from binding event
 * @param event Binding called event
 * @return String payload from JavaScript
 */
protected String extractPayload(BindingCalled event);

Usage Example:

import org.openqa.selenium.devtools.v110.v110Javascript;
import org.openqa.selenium.devtools.v110.runtime.model.BindingCalled;

v110Javascript javascript = new v110Javascript(devTools);

// Enable runtime and add binding
devTools.send(javascript.enableRuntime());
devTools.send(javascript.doAddJsBinding("javaCallback"));

// Listen for binding calls
devTools.addListener(javascript.bindingCalledEvent(), event -> {
    String payload = javascript.extractPayload(event);
    System.out.println("JavaScript called Java with: " + payload);
    
    // Process the call and potentially respond
    handleJavaScriptCallback(payload);
});

// Navigate to page and use binding
driver.get("https://example.com");
driver.executeScript("javaCallback('Hello from JavaScript!');");

Page Domain Control

Enable page domain for script injection and page-level operations.

/**
 * Enable page domain
 * @return Command to enable page domain
 */
protected Command<Void> enablePage();

/**
 * Disable page domain
 * @return Command to disable page domain
 */
protected Command<Void> disablePage();

Script Injection

Inject JavaScript code to be evaluated on new document creation.

/**
 * Add script to evaluate on new document
 * @param script JavaScript code to inject
 * @return Command returning script identifier
 */
protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);

/**
 * Remove previously added script
 * @param id Script identifier to remove
 * @return Command to remove script
 */
protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);

Usage Example:

import org.openqa.selenium.devtools.v110.page.model.ScriptIdentifier;

// Enable page domain
devTools.send(javascript.enablePage());

// Add script that runs on every page load
String initScript = """
    window.myApp = {
        initialized: true,
        version: '1.0.0',
        log: function(msg) {
            console.log('[MyApp] ' + msg);
        }
    };
    window.myApp.log('Application initialized');
""";

ScriptIdentifier scriptId = devTools.send(
    javascript.addScriptToEvaluateOnNewDocument(initScript)
);

// Navigate - script will run automatically
driver.get("https://example.com");

// Later remove the script
devTools.send(javascript.removeScriptToEvaluateOnNewDocument(scriptId));

High-Level JavaScript Operations

Convenient methods for common JavaScript operations (inherited from base Javascript class).

/**
 * Add JavaScript binding with automatic event handling
 * @param bindingName Name for JavaScript binding
 * @param handler Function to handle binding calls
 */
public void addJsBinding(String bindingName, Consumer<String> handler);

/**
 * Remove JavaScript binding
 * @param bindingName Name of binding to remove
 */
public void removeJsBinding(String bindingName);

/**
 * Pin script for evaluation on new documents
 * @param scriptName Name/identifier for script
 * @param script JavaScript code to pin
 */
public void pin(String scriptName, String script);

/**
 * Unpin previously pinned script
 * @param scriptName Name of script to unpin
 */
public void unpin(String scriptName);

CDP Domain Classes

Runtime Domain

Direct access to CDP Runtime domain for low-level JavaScript operations.

import org.openqa.selenium.devtools.v110.runtime.Runtime;

/**
 * Enable runtime domain
 */
public static Command<Void> enable();

/**
 * Disable runtime domain
 */
public static Command<Void> disable();

/**
 * Add runtime binding
 */
public static Command<Void> addBinding(
    String name,
    Optional<ExecutionContextId> executionContextId,
    Optional<String> executionContextName
);

/**
 * Remove runtime binding
 */
public static Command<Void> removeBinding(String name);

/**
 * Binding called event
 */
public static Event<BindingCalled> bindingCalled();

/**
 * Evaluate JavaScript expression
 */
public static Command<EvaluateResponse> evaluate(
    String expression,
    Optional<String> objectGroup,
    Optional<Boolean> includeCommandLineAPI,
    Optional<Boolean> silent,
    Optional<ExecutionContextId> contextId,
    Optional<Boolean> returnByValue,
    Optional<Boolean> generatePreview,
    Optional<Boolean> userGesture,
    Optional<Boolean> awaitPromise,
    Optional<Boolean> throwOnSideEffect,
    Optional<TimeDelta> timeout,
    Optional<Boolean> disableBreaks,
    Optional<Boolean> replMode,
    Optional<Boolean> allowUnsafeEvalBlockedByCSP
);

Page Domain

Direct access to CDP Page domain for page-level script operations.

import org.openqa.selenium.devtools.v110.page.Page;

/**
 * Enable page domain
 */
public static Command<Void> enable();

/**
 * Disable page domain
 */
public static Command<Void> disable();

/**
 * Add script to evaluate on new document
 */
public static Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(
    String source,
    Optional<String> worldName,
    Optional<Boolean> includeCommandLineAPI
);

/**
 * Remove script to evaluate on new document
 */
public static Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier identifier);

Model Classes

Script and Binding Models

import org.openqa.selenium.devtools.v110.page.model.*;
import org.openqa.selenium.devtools.v110.runtime.model.*;

/**
 * Script identifier for page-level scripts
 */
public class ScriptIdentifier {
    String toString();
}

/**
 * Runtime binding called event
 */
public class BindingCalled {
    /**
     * Binding name that was called
     */
    String getName();
    
    /**
     * Payload sent from JavaScript
     */
    String getPayload();
    
    /**
     * Execution context where binding was called
     */
    ExecutionContextId getExecutionContextId();
}

/**
 * JavaScript evaluation response
 */
public class EvaluateResponse {
    /**
     * Evaluation result as remote object
     */
    RemoteObject getResult();
    
    /**
     * Exception details if evaluation threw
     */
    Optional<ExceptionDetails> getExceptionDetails();
}

/**
 * JavaScript execution context identifier
 */
public class ExecutionContextId {
    Integer getValue();
    String toString();
}

Runtime Object Models

/**
 * Remote object representing JavaScript values
 */
public class RemoteObject {
    /**
     * Object type (object, function, undefined, string, number, boolean, symbol, bigint)
     */
    RemoteObjectType getType();
    
    /**
     * Object subtype for more specific type information
     */
    Optional<RemoteObjectSubtype> getSubtype();
    
    /**
     * Primitive value (for strings, numbers, booleans)
     */
    Optional<Object> getValue();
    
    /**
     * String description of the object
     */
    Optional<String> getDescription();
    
    /**
     * Unique object identifier for further operations
     */
    Optional<RemoteObjectId> getObjectId();
}

/**
 * Exception details from JavaScript evaluation
 */
public class ExceptionDetails {
    String getText();
    Optional<String> getUrl();
    Integer getLineNumber();
    Integer getColumnNumber();
    Optional<RemoteObject> getException();
}

Advanced Usage Examples

Bidirectional Communication

v110Javascript javascript = new v110Javascript(devTools);
devTools.send(javascript.enableRuntime());

// Set up bidirectional communication
javascript.addJsBinding("sendToJava", payload -> {
    System.out.println("Received from JavaScript: " + payload);
    
    // Send response back to JavaScript  
    String response = processPayload(payload);
    driver.executeScript("window.javaResponse = arguments[0];", response);
});

// Navigate and establish communication
driver.get("https://example.com");

// JavaScript can now call: sendToJava("some data")
// And receive responses via: window.javaResponse

Script Injection for Testing

// Enable page domain
devTools.send(javascript.enablePage());

// Inject testing utilities
String testingScript = """
    window.testUtils = {
        waitForElement: function(selector, timeout = 5000) {
            return new Promise((resolve, reject) => {
                const startTime = Date.now();
                const check = () => {
                    const element = document.querySelector(selector);
                    if (element) {
                        resolve(element);
                    } else if (Date.now() - startTime > timeout) {
                        reject(new Error('Element not found: ' + selector));
                    } else {
                        setTimeout(check, 100);
                    }
                };
                check();
            });
        },
        
        simulateEvent: function(element, eventType) {
            const event = new Event(eventType, { bubbles: true });
            element.dispatchEvent(event);
        }
    };
""";

ScriptIdentifier testUtilsScript = devTools.send(
    javascript.addScriptToEvaluateOnNewDocument(testingScript)
);

// Now all pages will have testUtils available

Runtime Evaluation

import org.openqa.selenium.devtools.v110.runtime.Runtime;
import org.openqa.selenium.devtools.v110.runtime.model.EvaluateResponse;

// Enable runtime
devTools.send(Runtime.enable());

// Evaluate JavaScript expression
EvaluateResponse response = devTools.send(Runtime.evaluate(
    "document.title + ' - ' + location.href",
    Optional.empty(), // objectGroup
    Optional.empty(), // includeCommandLineAPI
    Optional.of(false), // silent
    Optional.empty(), // contextId
    Optional.of(true), // returnByValue
    Optional.empty(), // generatePreview
    Optional.empty(), // userGesture
    Optional.empty(), // awaitPromise
    Optional.empty(), // throwOnSideEffect
    Optional.empty(), // timeout
    Optional.empty(), // disableBreaks
    Optional.empty(), // replMode
    Optional.empty()  // allowUnsafeEvalBlockedByCSP
));

if (response.getExceptionDetails().isPresent()) {
    System.err.println("JavaScript error: " + 
        response.getExceptionDetails().get().getText());
} else {
    Object result = response.getResult().getValue().orElse(null);
    System.out.println("JavaScript result: " + result);
}

Error Handling

JavaScript operations may encounter various error conditions:

import org.openqa.selenium.devtools.DevToolsException;
import org.openqa.selenium.JavascriptException;

// Handle runtime enablement failures
try {
    devTools.send(javascript.enableRuntime());
} catch (DevToolsException e) {
    System.err.println("Failed to enable runtime: " + e.getMessage());
}

// Handle binding setup failures
try {
    javascript.addJsBinding("myBinding", payload -> {
        // Handle binding call
    });
} catch (DevToolsException e) {
    System.err.println("Failed to add binding: " + e.getMessage());
}

// Handle JavaScript evaluation errors
devTools.addListener(Runtime.evaluate("invalid.javascript.code", 
    Optional.empty(), Optional.empty(), Optional.of(false),
    Optional.empty(), Optional.of(true), Optional.empty(),
    Optional.empty(), Optional.empty(), Optional.empty(),
    Optional.empty(), Optional.empty(), Optional.empty(),
    Optional.empty()), response -> {
    
    if (response.getExceptionDetails().isPresent()) {
        ExceptionDetails details = response.getExceptionDetails().get();
        System.err.printf("JavaScript Error at %s:%d - %s%n",
            details.getUrl().orElse("unknown"),
            details.getLineNumber(),
            details.getText());
    }
});

Install with Tessl CLI

npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v110

docs

events.md

index.md

javascript.md

logging.md

network.md

target.md

tile.json