Chrome DevTools Protocol (CDP) client library for Chrome version 105, providing Java bindings for browser automation and debugging capabilities
—
JavaScript evaluation capabilities with support for bindings, script injection, and runtime interaction. Enables advanced JavaScript automation beyond standard WebDriver execute_script functionality.
Manage JavaScript capabilities including bindings, script injection, and runtime interaction.
/**
* Initialize JavaScript handler for runtime operations
* @param devtools DevTools session instance
*/
public V105Javascript(DevTools devtools);
/**
* Disable JavaScript handler and clean up all bindings and scripts
*/
public void disable();
/**
* Pin a script to be evaluated on new document creation
* @param exposeScriptAs Name to expose the script binding as
* @param script JavaScript code to inject
* @return ScriptId for managing the pinned script
*/
public ScriptId pin(String exposeScriptAs, String script);Usage Examples:
import org.openqa.selenium.devtools.v105.V105Javascript;
import org.openqa.selenium.devtools.v105.runtime.Runtime;
// Initialize JavaScript handler
V105Javascript javascript = new V105Javascript(devTools);
// Pin a script that runs on new document creation
ScriptId scriptId = javascript.pin("testBinding",
"window.testMode = true; console.log('Test script loaded');");
// For direct JavaScript evaluation, use CDP directly
devTools.send(Runtime.enable());
devTools.send(Runtime.evaluate("return document.title"));
devTools.send(Runtime.evaluate("console.log('Hello from DevTools')"));
// Clean up
javascript.disable();
devTools.send(Runtime.disable());Create bidirectional communication between Java and JavaScript through named bindings.
/**
* Add JavaScript binding for communication with Java
* @param scriptName Name of the binding function
*/
public void addJsBinding(String scriptName);
/**
* Remove JavaScript binding
* @param scriptName Name of the binding to remove
*/
public void removeJsBinding(String scriptName);
/**
* Add listener for binding calls from JavaScript
* @param listener Consumer that receives payload strings from JavaScript
*/
public void addBindingCalledListener(Consumer<String> listener);Usage Examples:
import org.openqa.selenium.devtools.v105.runtime.model.BindingCalled;
// Set up binding listener first
javascript.bindingCalledEvent().addListener(bindingCalled -> {
String payload = javascript.extractPayload(bindingCalled);
System.out.println("Received from JavaScript: " + payload);
// Process the payload and potentially respond
if (payload.equals("request-data")) {
// Execute JavaScript to respond
devTools.send(Runtime.evaluate("window.javaResponse = 'Data from Java'"));
}
});
// Add binding
devTools.send(javascript.doAddJsBinding("javaBinding"));
// Inject JavaScript that uses the binding
devTools.send(Runtime.evaluate(
"window.javaBinding('Hello from JavaScript');" +
"window.javaBinding('request-data');"
));
// Remove binding when done
devTools.send(javascript.doRemoveJsBinding("javaBinding"));Inject JavaScript code that runs automatically on new document creation.
/**
* Add script to evaluate on new document creation
* @param script JavaScript code to inject
* @return Command returning script identifier for later removal
*/
protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);
/**
* Remove previously injected script
* @param id Script identifier from addScriptToEvaluateOnNewDocument
* @return Command to remove injected script
*/
protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);Usage Examples:
import org.openqa.selenium.devtools.v105.page.model.ScriptIdentifier;
// Inject script that runs on every new page
String injectedScript =
"window.testMode = true;" +
"console.log('Test script loaded');" +
"document.addEventListener('DOMContentLoaded', () => {" +
" document.body.setAttribute('data-test', 'true');" +
"});";
ScriptIdentifier scriptId = devTools.send(
javascript.addScriptToEvaluateOnNewDocument(injectedScript)
);
// Navigate to pages - script will run automatically
driver.get("https://example.com");
driver.get("https://another-site.com");
// Verify script execution
Boolean testMode = (Boolean) devTools.send(Runtime.evaluate("window.testMode"));
System.out.println("Test mode active: " + testMode);
// Remove script when no longer needed
devTools.send(javascript.removeScriptToEvaluateOnNewDocument(scriptId));Combine bindings, script injection, and evaluation for complex scenarios.
Usage Examples:
// Complex automation scenario
public class JavaScriptAutomation {
private V105Javascript javascript;
private DevTools devTools;
public void setupAdvancedJavaScript() {
javascript = new V105Javascript(devTools);
// Enable domains
devTools.send(javascript.enableRuntime());
devTools.send(javascript.enablePage());
// Set up bidirectional communication
setupBindings();
// Inject monitoring script
injectMonitoringScript();
}
private void setupBindings() {
// Listen for messages from JavaScript
javascript.bindingCalledEvent().addListener(this::handleJavaScriptMessage);
// Add multiple bindings for different purposes
devTools.send(javascript.doAddJsBinding("reportError"));
devTools.send(javascript.doAddJsBinding("reportMetrics"));
devTools.send(javascript.doAddJsBinding("requestData"));
}
private void injectMonitoringScript() {
String monitoringScript =
"// Error reporting" +
"window.addEventListener('error', (e) => {" +
" window.reportError(JSON.stringify({" +
" message: e.message," +
" filename: e.filename," +
" lineno: e.lineno" +
" }));" +
"});" +
"// Performance monitoring" +
"window.addEventListener('load', () => {" +
" setTimeout(() => {" +
" const perfData = {" +
" loadTime: performance.timing.loadEventEnd - performance.timing.navigationStart," +
" domReady: performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart" +
" };" +
" window.reportMetrics(JSON.stringify(perfData));" +
" }, 1000);" +
"});";
devTools.send(javascript.addScriptToEvaluateOnNewDocument(monitoringScript));
}
private void handleJavaScriptMessage(BindingCalled event) {
String payload = javascript.extractPayload(event);
// Route messages based on binding name
switch (event.getName()) {
case "reportError":
handleError(payload);
break;
case "reportMetrics":
handleMetrics(payload);
break;
case "requestData":
provideData(payload);
break;
}
}
}// JavaScript handler implementation
public class V105Javascript extends Javascript<ScriptIdentifier, BindingCalled> {
public V105Javascript(DevTools devtools);
}
// Script identifier for injected scripts
public class ScriptIdentifier {
ScriptIdentifier(String id);
String toString();
}// JavaScript binding call event
public class BindingCalled {
String getName();
String getPayload();
Optional<ExecutionContextId> getExecutionContextId();
}
// Execution context identifier
public class ExecutionContextId {
ExecutionContextId(Integer id);
Integer toJson();
}// Runtime evaluation result
public class EvaluateResponse {
RemoteObject getResult();
Optional<ExceptionDetails> getExceptionDetails();
}
// Remote object from JavaScript
public class RemoteObject {
RemoteObject.Type getType();
Optional<Object> getValue();
Optional<String> getDescription();
Optional<String> getObjectId();
}
// Exception details from evaluation
public class ExceptionDetails {
String getText();
int getLineNumber();
int getColumnNumber();
Optional<String> getUrl();
Optional<StackTrace> getStackTrace();
}// Script addition options
public class AddScriptToEvaluateOnNewDocumentRequest {
String getSource();
Optional<String> getWorldName();
Optional<Boolean> getIncludeCommandLineAPI();
}
// Frame navigation types
public class FrameId {
FrameId(String id);
String toString();
}
// Navigation events
public class FrameNavigated {
Frame getFrame();
NavigationType getType();
}Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v105