Chrome DevTools Protocol (CDP) bindings for Selenium WebDriver targeting Chromium version 85
—
Browser target (tab/window) management and session handling for the Chrome DevTools Protocol v85. This functionality allows you to create, attach to, and manage browser contexts and targets for multi-tab automation scenarios.
The main class for target management implementing the idealized Target interface.
/**
* Target management functionality for Chrome DevTools v85
*/
public class V85Target implements org.openqa.selenium.devtools.idealized.target.Target {
/**
* Creates a new V85Target instance
*/
public V85Target();
}Get information about available browser targets (tabs, windows, workers, etc.).
/**
* Gets a list of all available targets
* @return Command that returns list of target information
*/
public Command<List<org.openqa.selenium.devtools.idealized.target.model.TargetInfo>> getTargets();Usage Example:
import org.openqa.selenium.devtools.v85.V85Target;
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;
V85Target target = domains.target();
// Get all available targets
List<TargetInfo> targets = devTools.send(target.getTargets());
// Iterate through targets
for (TargetInfo targetInfo : targets) {
System.out.printf("Target: %s (%s) - %s%n",
targetInfo.getTitle(),
targetInfo.getType(),
targetInfo.getUrl()
);
if (targetInfo.getType().equals("page")) {
System.out.println(" This is a web page target");
}
}Attach to and detach from specific browser targets to control them.
/**
* Attaches to a target for control
* @param targetId - ID of the target to attach to
* @return Command that returns a session ID for the attached target
*/
public Command<SessionID> attachToTarget(TargetID targetId);
/**
* Detaches from a target
* @param sessionId - Session ID to detach (optional)
* @param targetId - Target ID to detach from (optional)
* @return Command to detach from target
*/
public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);Usage Example:
// Find a specific target and attach to it
List<TargetInfo> targets = devTools.send(target.getTargets());
TargetInfo pageTarget = targets.stream()
.filter(t -> t.getType().equals("page") && t.getUrl().contains("example.com"))
.findFirst()
.orElseThrow(() -> new RuntimeException("Target not found"));
// Attach to the target
SessionID sessionId = devTools.send(target.attachToTarget(pageTarget.getTargetId()));
System.out.println("Attached to target with session: " + sessionId);
// Later, detach from the target
devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.of(pageTarget.getTargetId())));Configure automatic attachment to new targets as they are created.
/**
* Sets up automatic attachment to new targets
* @return Command to enable auto-attach for new targets
*/
public Command<Void> setAutoAttach();Usage Example:
// Enable auto-attachment to new targets
devTools.send(target.setAutoAttach());
// Listen for detachment events
devTools.addListener(target.detached(), detachedTargetId -> {
System.out.println("Target detached: " + detachedTargetId);
});Monitor target lifecycle events.
/**
* Event fired when a target is detached
* @return Event for target detachment
*/
public Event<TargetID> detached();Usage Example:
// Monitor target detachment
devTools.addListener(target.detached(), targetId -> {
System.out.println("Target detached: " + targetId);
// Clean up any resources associated with this target
cleanupTargetResources(targetId);
});import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v85.V85Domains;
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;
ChromeDriver driver = new ChromeDriver();
DevTools devTools = driver.getDevTools();
devTools.createSession();
V85Domains domains = new V85Domains(devTools);
V85Target target = domains.target();
// Enable auto-attachment for new targets
devTools.send(target.setAutoAttach());
// Monitor target detachment
devTools.addListener(target.detached(), targetId -> {
System.out.println("Target detached: " + targetId);
});
// Open a new tab
driver.executeScript("window.open('https://example.com', '_blank');");
// Wait a moment for the new target to be created
Thread.sleep(1000);
// Get all targets
List<TargetInfo> targets = devTools.send(target.getTargets());
System.out.println("Available targets:");
Map<TargetID, SessionID> attachedSessions = new HashMap<>();
for (TargetInfo targetInfo : targets) {
System.out.printf("- %s: %s (%s)%n",
targetInfo.getTargetId(),
targetInfo.getTitle(),
targetInfo.getType()
);
// Attach to page targets
if (targetInfo.getType().equals("page")) {
try {
SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
attachedSessions.put(targetInfo.getTargetId(), sessionId);
System.out.println(" Attached with session: " + sessionId);
} catch (Exception e) {
System.err.println(" Failed to attach: " + e.getMessage());
}
}
}
// Later, detach from all sessions
for (Map.Entry<TargetID, SessionID> entry : attachedSessions.entrySet()) {
devTools.send(target.detachFromTarget(
Optional.of(entry.getValue()),
Optional.of(entry.getKey())
));
}Information about a browser target.
/**
* Information about a browser target
*/
public class org.openqa.selenium.devtools.idealized.target.model.TargetInfo {
/**
* Creates target information
* @param targetId - Unique target identifier
* @param type - Target type (page, background_page, service_worker, etc.)
* @param title - Target title
* @param url - Target URL
* @param attached - Whether target is currently attached
* @param openerId - ID of the target that opened this target (if any)
* @param browserContextId - Browser context ID (if any)
*/
public TargetInfo(
TargetID targetId,
String type,
String title,
String url,
Boolean attached,
Optional<TargetID> openerId,
Optional<BrowserContextID> browserContextId
);
/**
* Gets the target ID
* @return Unique target identifier
*/
public TargetID getTargetId();
/**
* Gets the target type
* @return Target type string
*/
public String getType();
/**
* Gets the target title
* @return Target title (usually page title)
*/
public String getTitle();
/**
* Gets the target URL
* @return Target URL
*/
public String getUrl();
/**
* Checks if the target is attached
* @return true if target is attached
*/
public Boolean getAttached();
/**
* Gets the opener target ID
* @return ID of target that opened this one (for popups/new tabs)
*/
public Optional<TargetID> getOpenerId();
/**
* Gets the browser context ID
* @return Browser context identifier
*/
public Optional<BrowserContextID> getBrowserContextId();
}Unique identifier for a browser target.
/**
* Unique identifier for a browser target
*/
public class TargetID {
/**
* Creates a target ID from string
* @param id - Target ID string
*/
public TargetID(String id);
/**
* Gets the ID as string
* @return Target ID string
*/
public String toString();
}Session identifier for attached targets.
/**
* Session identifier for DevTools connection to a target
*/
public class SessionID {
/**
* Creates a session ID from string
* @param id - Session ID string
*/
public SessionID(String id);
/**
* Gets the ID as string
* @return Session ID string
*/
public String toString();
}Browser context identifier for isolated browsing contexts.
/**
* Browser context identifier for isolated browsing sessions
*/
public class BrowserContextID {
/**
* Creates a browser context ID from string
* @param id - Context ID string
*/
public BrowserContextID(String id);
/**
* Gets the ID as string
* @return Context ID string
*/
public String toString();
}// Filter targets by type
List<TargetInfo> targets = devTools.send(target.getTargets());
// Get only page targets
List<TargetInfo> pageTargets = targets.stream()
.filter(t -> t.getType().equals("page"))
.collect(Collectors.toList());
// Get service worker targets
List<TargetInfo> serviceWorkers = targets.stream()
.filter(t -> t.getType().equals("service_worker"))
.collect(Collectors.toList());
// Get background page targets (extensions)
List<TargetInfo> backgroundPages = targets.stream()
.filter(t -> t.getType().equals("background_page"))
.collect(Collectors.toList());public class MultiTargetManager {
private final Map<TargetID, SessionID> sessions = new ConcurrentHashMap<>();
private final DevTools devTools;
private final V85Target target;
public MultiTargetManager(DevTools devTools, V85Target target) {
this.devTools = devTools;
this.target = target;
// Monitor target detachment
devTools.addListener(target.detached(), this::handleTargetDetached);
}
public SessionID attachToTarget(TargetID targetId) {
try {
SessionID sessionId = devTools.send(target.attachToTarget(targetId));
sessions.put(targetId, sessionId);
return sessionId;
} catch (Exception e) {
throw new RuntimeException("Failed to attach to target: " + targetId, e);
}
}
public void detachFromTarget(TargetID targetId) {
SessionID sessionId = sessions.remove(targetId);
if (sessionId != null) {
devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.of(targetId)));
}
}
public void detachFromAllTargets() {
for (Map.Entry<TargetID, SessionID> entry : sessions.entrySet()) {
devTools.send(target.detachFromTarget(
Optional.of(entry.getValue()),
Optional.of(entry.getKey())
));
}
sessions.clear();
}
private void handleTargetDetached(TargetID targetId) {
sessions.remove(targetId);
System.out.println("Cleaned up session for detached target: " + targetId);
}
public Set<TargetID> getAttachedTargets() {
return new HashSet<>(sessions.keySet());
}
}// Continuous target monitoring
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
try {
List<TargetInfo> currentTargets = devTools.send(target.getTargets());
System.out.println("Current targets:");
for (TargetInfo targetInfo : currentTargets) {
System.out.printf(" %s: %s (%s) - %s%n",
targetInfo.getTargetId(),
targetInfo.getTitle(),
targetInfo.getType(),
targetInfo.getAttached() ? "attached" : "detached"
);
}
// Auto-attach to new page targets
for (TargetInfo targetInfo : currentTargets) {
if (targetInfo.getType().equals("page") && !targetInfo.getAttached()) {
try {
SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
System.out.println("Auto-attached to new page target: " + sessionId);
} catch (Exception e) {
System.err.println("Failed to auto-attach: " + e.getMessage());
}
}
}
} catch (Exception e) {
System.err.println("Error monitoring targets: " + e.getMessage());
}
}, 0, 5, TimeUnit.SECONDS);
// Remember to shutdown the executor when done
// executor.shutdown();Install with Tessl CLI
npx tessl i tessl/maven-org-seleniumhq-selenium--selenium-devtools-v85