Java bindings for Chrome DevTools Protocol v133, enabling advanced browser automation capabilities through Selenium WebDriver.
—
The v133Log class provides comprehensive browser log monitoring and management capabilities, enabling developers to capture, filter, and process browser logs in real-time.
Main log management class that implements the idealized Log interface with v133-specific implementations.
/**
* v133-specific log management implementation
* Implements org.openqa.selenium.devtools.idealized.log.Log for browser log operations
*/
public class v133Log implements org.openqa.selenium.devtools.idealized.log.Log {
/**
* Creates a new v133Log instance
* Uses default constructor - no parameters required as operations are static
*/
}Methods for enabling and controlling browser log collection.
/**
* Enable log domain to start collecting browser logs
* @return Command to enable log collection
*/
public Command<Void> enable();
/**
* Clear all existing browser logs
* @return Command to clear browser logs
*/
public Command<Void> clear();Usage Example:
import org.openqa.selenium.devtools.v133.v133Log;
v133Log log = new v133Log();
// Enable log collection
devTools.send(log.enable());
// Clear existing logs
devTools.send(log.clear());Monitor browser log entries as they are created in real-time.
/**
* Get the log entry added event for monitoring new log entries
* @return Event for monitoring browser log entries
*/
public Event<org.openqa.selenium.devtools.idealized.log.model.LogEntry> entryAdded();Usage Example:
import org.openqa.selenium.devtools.idealized.log.model.LogEntry;
import java.util.logging.Level;
// Listen for log entries
devTools.addListener(log.entryAdded(), (LogEntry entry) -> {
System.out.printf("[%s] %s: %s%n",
entry.getSource(),
entry.getLogEntry().getLevel(),
entry.getLogEntry().getMessage()
);
});
// Now browse to pages and logs will be captured automatically
driver.get("https://example.com");Internal methods for converting CDP log levels to Java logging levels.
/**
* Convert CDP log level to Java logging Level
* @param level CDP LogEntry.Level
* @return Java logging Level equivalent
*/
private Level fromCdpLevel(LogEntry.Level level);
/**
* Convert CDP timestamp to Java long timestamp
* @param timestamp CDP Timestamp
* @return Java long timestamp in milliseconds
*/
private long fromCdpTimestamp(Timestamp timestamp);Raw CDP log entry from the browser log domain.
// From org.openqa.selenium.devtools.v133.log.model.LogEntry
public class LogEntry {
public String getSource(); // Source of the log entry (javascript, network, etc.)
public Level getLevel(); // Log level (verbose, info, warning, error)
public String getText(); // Log message text
public Timestamp getTimestamp(); // When the log entry was created
}
// Log levels from CDP
public enum Level {
VERBOSE, // Detailed debugging information
INFO, // General information
WARNING, // Warning messages
ERROR // Error messages
}Processed log entry converted to Selenium's standard format.
// From org.openqa.selenium.devtools.idealized.log.model.LogEntry
public class LogEntry {
public LogEntry(String source, org.openqa.selenium.logging.LogEntry logEntry);
public String getSource(); // Source of the log entry
public org.openqa.selenium.logging.LogEntry getLogEntry(); // Standard Selenium log entry
}
// From org.openqa.selenium.logging.LogEntry
public class LogEntry {
public LogEntry(Level level, long timestamp, String message);
public Level getLevel(); // Java logging level
public long getTimestamp(); // Timestamp in milliseconds
public String getMessage(); // Log message
}Filter logs by severity level to focus on important messages:
import java.util.logging.Level;
devTools.addListener(log.entryAdded(), (LogEntry entry) -> {
Level level = entry.getLogEntry().getLevel();
// Only process warnings and errors
if (level.intValue() >= Level.WARNING.intValue()) {
System.err.printf("⚠️ [%s] %s: %s%n",
entry.getSource(),
level.getName(),
entry.getLogEntry().getMessage()
);
// Take action on errors
if (level == Level.SEVERE) {
handleCriticalError(entry);
}
}
});Filter logs by their source to focus on specific types of browser activity:
devTools.addListener(log.entryAdded(), (LogEntry entry) -> {
String source = entry.getSource();
String message = entry.getLogEntry().getMessage();
switch (source) {
case "javascript":
System.out.println("🔶 JS: " + message);
break;
case "network":
System.out.println("🌐 NET: " + message);
break;
case "security":
System.out.println("🔒 SEC: " + message);
break;
case "deprecation":
System.out.println("⚠️ DEP: " + message);
break;
default:
System.out.println("📝 " + source.toUpperCase() + ": " + message);
}
});Collect and analyze logs for patterns:
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public class LogAnalyzer {
private final Map<String, Integer> errorCounts = new ConcurrentHashMap<>();
private final List<LogEntry> criticalErrors = Collections.synchronizedList(new ArrayList<>());
public void setupLogAnalysis(v133Log log, DevTools devTools) {
devTools.addListener(log.entryAdded(), this::analyzeLogEntry);
}
private void analyzeLogEntry(LogEntry entry) {
Level level = entry.getLogEntry().getLevel();
String message = entry.getLogEntry().getMessage();
// Count errors by type
if (level == Level.SEVERE) {
String errorType = extractErrorType(message);
errorCounts.merge(errorType, 1, Integer::sum);
criticalErrors.add(entry);
}
// Detect patterns
if (message.contains("Uncaught")) {
System.err.println("🚨 Uncaught JavaScript error detected: " + message);
}
if (message.contains("404") || message.contains("Failed to load")) {
System.err.println("📁 Resource loading error: " + message);
}
}
private String extractErrorType(String message) {
if (message.contains("TypeError")) return "TypeError";
if (message.contains("ReferenceError")) return "ReferenceError";
if (message.contains("SyntaxError")) return "SyntaxError";
if (message.contains("NetworkError")) return "NetworkError";
return "Unknown";
}
public void printSummary() {
System.out.println("\n=== Log Analysis Summary ===");
System.out.println("Error counts by type:");
errorCounts.forEach((type, count) ->
System.out.printf("%s: %d occurrences%n", type, count));
System.out.printf("Total critical errors: %d%n", criticalErrors.size());
}
}Save logs to files for later analysis:
import java.io.*;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
public class LogPersistence {
private final PrintWriter logWriter;
public LogPersistence(String filename) throws IOException {
this.logWriter = new PrintWriter(new FileWriter(filename, true));
}
public void setupLogPersistence(v133Log log, DevTools devTools) {
devTools.addListener(log.entryAdded(), this::persistLogEntry);
}
private void persistLogEntry(LogEntry entry) {
String timestamp = DateTimeFormatter.ISO_INSTANT
.format(Instant.ofEpochMilli(entry.getLogEntry().getTimestamp()));
logWriter.printf("[%s] %s/%s: %s%n",
timestamp,
entry.getSource(),
entry.getLogEntry().getLevel().getName(),
entry.getLogEntry().getMessage()
);
logWriter.flush();
}
public void close() {
logWriter.close();
}
}The v133Log class maps CDP log levels to Java logging levels:
| CDP Level | Java Level | Description |
|---|---|---|
verbose | FINEST | Detailed debugging information |
info | INFO | General informational messages |
warning | WARNING | Potential problems or deprecations |
error | SEVERE | Error conditions and exceptions |
Browser logs come from various sources:
javascript: JavaScript runtime errors, console calls, and exceptionsnetwork: Network request failures, CORS errors, and connectivity issuessecurity: Security policy violations and certificate problemsdeprecation: Usage of deprecated APIs and featuresrendering: Layout and rendering warningsstorage: Local storage, session storage, and database errorsLog management includes error handling for:
Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v133