Chrome DevTools Protocol (CDP) bindings for Selenium WebDriver targeting Chromium version 85
—
Runtime event monitoring for the Chrome DevTools Protocol v85, including console API calls, JavaScript exceptions, and error handling. This functionality allows you to capture browser console output and JavaScript runtime errors in real-time.
The main class for runtime event handling extending the base Events functionality.
/**
* Runtime event monitoring for Chrome DevTools v85
*/
public class V85Events extends Events<ConsoleAPICalled, ExceptionThrown> {
/**
* Creates a new V85Events instance
* @param devtools - DevTools session for sending commands
*/
public V85Events(DevTools devtools);
}Enable and disable the Runtime domain for event monitoring.
/**
* Enables the Runtime domain for event monitoring
* @return Command to enable runtime domain
*/
protected Command<Void> enableRuntime();
/**
* Disables the Runtime domain
* @return Command to disable runtime domain
*/
protected Command<Void> disableRuntime();Monitor console API calls from the browser (console.log, console.error, etc.).
/**
* Event fired when console API is called in the browser
* @return Event for console API calls
*/
protected Event<ConsoleAPICalled> consoleEvent();
/**
* Converts CDP console event to Selenium ConsoleEvent
* @param event - CDP console API called event
* @return Selenium ConsoleEvent with processed data
*/
protected ConsoleEvent toConsoleEvent(ConsoleAPICalled event);Usage Example:
import org.openqa.selenium.devtools.v85.V85Events;
import org.openqa.selenium.devtools.events.ConsoleEvent;
V85Events events = (V85Events) domains.events();
// Listen for console events using high-level API
events.addConsoleListener(event -> {
System.out.printf("[%s] %s: %s%n",
event.getTimestamp(),
event.getType(),
event.getMessages()
);
});
// Now when the browser executes:
// console.log("Hello from browser");
// console.error("An error occurred");
// You'll see the output in JavaMonitor JavaScript exceptions and runtime errors.
/**
* Event fired when a JavaScript exception is thrown
* @return Event for JavaScript exceptions
*/
protected Event<ExceptionThrown> exceptionThrownEvent();
/**
* Converts CDP exception event to Selenium JavascriptException
* @param event - CDP exception thrown event
* @return JavascriptException with stack trace and error details
*/
protected JavascriptException toJsException(ExceptionThrown event);Usage Example:
// Listen for JavaScript exceptions using high-level API
events.addJavascriptExceptionListener(jsException -> {
System.err.println("JavaScript Exception: " + jsException.getMessage());
// Print stack trace
for (StackTraceElement element : jsException.getStackTrace()) {
System.err.println(" at " + element);
}
// Handle the exception (log, notify, etc.)
handleJavaScriptError(jsException);
});import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v85.V85Domains;
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
V85Domains domains = new V85Domains(devTools);
V85Events events = (V85Events) domains.events();
// Set up console monitoring using high-level API
events.addConsoleListener(event -> {
switch (event.getType()) {
case "log":
System.out.println("[LOG] " + event.getMessages());
break;
case "warn":
System.out.println("[WARN] " + event.getMessages());
break;
case "error":
System.err.println("[ERROR] " + event.getMessages());
break;
case "info":
System.out.println("[INFO] " + event.getMessages());
break;
case "debug":
System.out.println("[DEBUG] " + event.getMessages());
break;
}
});
// Set up exception monitoring using high-level API
events.addJavascriptExceptionListener(jsException -> {
System.err.println("Uncaught JavaScript Exception:");
System.err.println("Message: " + jsException.getMessage());
// Log to file or monitoring system
logJavaScriptError(jsException);
});
// Navigate to page - events will be captured automatically
driver.get("https://example.com");
// Execute some JavaScript that will generate events
driver.executeScript("console.log('Test log message');");
driver.executeScript("console.error('Test error message');");
driver.executeScript("throw new Error('Test exception');");Event data for console API calls from the browser.
/**
* Console API call event from Chrome DevTools
*/
public class ConsoleAPICalled {
/**
* Gets the type of console call (log, error, warn, etc.)
* @return Console call type
*/
public ConsoleApiType getType();
/**
* Gets the arguments passed to the console function
* @return List of remote objects representing the arguments
*/
public List<RemoteObject> getArgs();
/**
* Gets the timestamp when the console call occurred
* @return Timestamp of the call
*/
public Timestamp getTimestamp();
/**
* Gets the execution context ID where the call occurred
* @return Execution context ID
*/
public Optional<Integer> getExecutionContextId();
/**
* Gets the stack trace if available
* @return Stack trace information
*/
public Optional<StackTrace> getStackTrace();
}
/**
* Console API call types
*/
public enum ConsoleApiType {
LOG, DEBUG, INFO, ERROR, WARNING, DIR, DIRXML, TABLE, TRACE,
CLEAR, STARTGROUP, STARTGROUPCOLLAPSED, ENDGROUP, ASSERT,
PROFILE, PROFILEEND, COUNT, TIMEEND
}Event data for JavaScript exceptions.
/**
* JavaScript exception event from Chrome DevTools
*/
public class ExceptionThrown {
/**
* Gets the exception details
* @return Exception details with stack trace and error info
*/
public ExceptionDetails getExceptionDetails();
/**
* Gets the timestamp when the exception occurred
* @return Exception timestamp
*/
public Timestamp getTimestamp();
}Detailed information about a JavaScript exception.
/**
* Detailed exception information
*/
public class ExceptionDetails {
/**
* Gets the exception ID
* @return Exception identifier
*/
public Integer getExceptionId();
/**
* Gets the exception text/message
* @return Exception message
*/
public String getText();
/**
* Gets the line number where the exception occurred
* @return Line number
*/
public Integer getLineNumber();
/**
* Gets the column number where the exception occurred
* @return Column number
*/
public Integer getColumnNumber();
/**
* Gets the script ID where the exception occurred
* @return Script ID
*/
public Optional<String> getScriptId();
/**
* Gets the URL where the exception occurred
* @return URL of the script
*/
public Optional<String> getUrl();
/**
* Gets the stack trace for the exception
* @return Stack trace information
*/
public Optional<StackTrace> getStackTrace();
/**
* Gets the exception object details
* @return Remote object representing the exception
*/
public Optional<RemoteObject> getException();
}Stack trace information for exceptions and console calls.
/**
* JavaScript stack trace information
*/
public class StackTrace {
/**
* Gets the description of the stack trace
* @return Stack trace description
*/
public Optional<String> getDescription();
/**
* Gets the call frames in the stack trace
* @return List of call frames from bottom to top
*/
public List<CallFrame> getCallFrames();
/**
* Gets the parent stack trace if available
* @return Parent stack trace for async operations
*/
public Optional<StackTrace> getParent();
}
/**
* Single call frame in a stack trace
*/
public class CallFrame {
/**
* Gets the function name
* @return Function name or empty string for anonymous functions
*/
public String getFunctionName();
/**
* Gets the script ID
* @return Script identifier
*/
public String getScriptId();
/**
* Gets the URL of the script
* @return Script URL
*/
public String getUrl();
/**
* Gets the line number (0-based)
* @return Line number in the script
*/
public Integer getLineNumber();
/**
* Gets the column number (0-based)
* @return Column number in the line
*/
public Integer getColumnNumber();
}Represents a JavaScript object or value from the browser.
/**
* Remote object representation from the browser
*/
public class RemoteObject {
/**
* Gets the object type
* @return Object type (object, function, undefined, string, number, boolean, symbol, bigint)
*/
public RemoteObjectType getType();
/**
* Gets the subtype for objects
* @return Object subtype (array, null, node, regexp, date, map, set, etc.)
*/
public Optional<RemoteObjectSubtype> getSubtype();
/**
* Gets the class name for objects
* @return Class name (e.g., "Object", "Array", "HTMLElement")
*/
public Optional<String> getClassName();
/**
* Gets the primitive value
* @return Value for primitive types
*/
public Optional<Object> getValue();
/**
* Gets the string description of the object
* @return Human-readable description
*/
public Optional<String> getDescription();
/**
* Gets the unique object ID for non-primitive values
* @return Object ID for referencing the object
*/
public Optional<String> getObjectId();
}// Filter console events by type and level
devTools.addListener(events.consoleEvent(), consoleCall -> {
ConsoleEvent event = events.toConsoleEvent(consoleCall);
// Only process errors and warnings
if (event.getType().equals("error") || event.getType().equals("warn")) {
logImportantMessage(event);
}
// Filter by message content
String message = event.getMessages().toString();
if (message.contains("API") || message.contains("network")) {
handleNetworkRelatedLog(event);
}
});
// Filter exceptions by location
devTools.addListener(events.exceptionThrownEvent(), exceptionEvent -> {
JavascriptException jsException = events.toJsException(exceptionEvent);
// Only handle exceptions from our application code
boolean isAppException = Arrays.stream(jsException.getStackTrace())
.anyMatch(frame -> frame.getFileName().contains("app.js") ||
frame.getFileName().contains("main.js"));
if (isAppException) {
handleApplicationError(jsException);
}
});Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v85