CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Chrome DevTools Protocol version 115 bindings for Selenium Java WebDriver enabling programmatic browser debugging capabilities

Pending
Overview
Eval results
Files

target-management.mddocs/

Target & Session Management

Browser target (tab/window) management, debugging session control, and multi-target coordination with attachment and detachment capabilities through the v115Target class.

Capabilities

Target Domain

Comprehensive target management for controlling browser tabs, windows, and debugging sessions.

/**
 * Target domain for browser target and session management
 * Implements the idealized Target interface for version independence
 */
public class v115Target implements Target {
    /**
     * Detach from a specific target or session
     * @param sessionId Optional session ID to detach from
     * @param targetId Optional target ID to detach from
     * @return Command to detach from target
     */
    public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);
    
    /**
     * Get list of all available targets
     * @return Command returning list of TargetInfo objects
     */
    public Command<List<TargetInfo>> getTargets();
    
    /**
     * Attach to a target for debugging
     * @param targetId Target ID to attach to
     * @return Command returning SessionID for the debugging session
     */
    public Command<SessionID> attachToTarget(TargetID targetId);
    
    /**
     * Set automatic attachment behavior for new targets
     * @return Command to enable auto-attach for new targets
     */
    public Command<Void> setAutoAttach();
    
    /**
     * Get target detached event stream
     * @return Event stream for target detachment notifications
     */
    public Event<TargetID> detached();
}

Target Discovery

Discover and enumerate all browser targets including tabs, service workers, and other contexts.

Usage Examples:

import org.openqa.selenium.devtools.v115.v115Target;
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;
import org.openqa.selenium.devtools.idealized.target.model.TargetID;

// Create target domain
v115Target target = new v115Target();

// Get all available targets
List<TargetInfo> targets = devTools.send(target.getTargets());

System.out.println("Found " + targets.size() + " targets:");
for (TargetInfo targetInfo : targets) {
    System.out.println("Target ID: " + targetInfo.getTargetId());
    System.out.println("  Type: " + targetInfo.getType());
    System.out.println("  Title: " + targetInfo.getTitle());
    System.out.println("  URL: " + targetInfo.getUrl());
    System.out.println("  Attached: " + targetInfo.getAttached());
    
    if (targetInfo.getOpenerId().isPresent()) {
        System.out.println("  Opener: " + targetInfo.getOpenerId().get());
    }
    
    if (targetInfo.getBrowserContextId().isPresent()) {
        System.out.println("  Context: " + targetInfo.getBrowserContextId().get());
    }
    
    System.out.println();
}

Target Attachment

Attach to specific targets for debugging and control multiple browser contexts.

Usage Examples:

import org.openqa.selenium.devtools.idealized.target.model.SessionID;

// Find target to attach to (e.g., a specific tab)
List<TargetInfo> targets = devTools.send(target.getTargets());
Optional<TargetInfo> pageTarget = targets.stream()
    .filter(t -> "page".equals(t.getType()))
    .filter(t -> t.getUrl().contains("example.com"))
    .findFirst();

if (pageTarget.isPresent()) {
    TargetID targetId = pageTarget.get().getTargetId();
    
    // Attach to the target
    SessionID sessionId = devTools.send(target.attachToTarget(targetId));
    System.out.println("Attached to target with session: " + sessionId);
    
    // Use the session for target-specific operations
    // Note: Attached sessions can be used with DevTools.send() by specifying sessionId
    
    // Detach when done
    devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
    System.out.println("Detached from target");
}

Multi-Target Coordination

Coordinate operations across multiple browser targets simultaneously.

Usage Examples:

import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

// Set up multi-target management
Map<TargetID, SessionID> attachedTargets = new HashMap<>();
ExecutorService executor = Executors.newCachedThreadPool();

// Get all page targets
List<TargetInfo> pageTargets = devTools.send(target.getTargets()).stream()
    .filter(t -> "page".equals(t.getType()))
    .toList();

// Attach to all page targets
List<CompletableFuture<Void>> attachTasks = pageTargets.stream()
    .map(targetInfo -> CompletableFuture.runAsync(() -> {
        try {
            TargetID targetId = targetInfo.getTargetId();
            SessionID sessionId = devTools.send(target.attachToTarget(targetId));
            
            synchronized (attachedTargets) {
                attachedTargets.put(targetId, sessionId);
            }
            
            System.out.println("Attached to target: " + targetInfo.getTitle());
        } catch (Exception e) {
            System.err.println("Failed to attach to target: " + e.getMessage());
        }
    }, executor))
    .toList();

// Wait for all attachments to complete
CompletableFuture.allOf(attachTasks.toArray(new CompletableFuture[0]))
    .join();

System.out.println("Attached to " + attachedTargets.size() + " targets");

// Perform operations on all attached targets
attachedTargets.forEach((targetId, sessionId) -> {
    try {
        // Example: Enable runtime on each target
        devTools.send(
            org.openqa.selenium.devtools.v115.runtime.Runtime.enable(),
            sessionId
        );
    } catch (Exception e) {
        System.err.println("Error enabling runtime on target " + targetId + ": " + e.getMessage());
    }
});

// Clean up - detach from all targets
attachedTargets.forEach((targetId, sessionId) -> {
    try {
        devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
    } catch (Exception e) {
        System.err.println("Error detaching from target " + targetId + ": " + e.getMessage());
    }
});

executor.shutdown();

Auto-Attach Configuration

Configure automatic attachment to new targets as they are created.

Usage Examples:

// Enable auto-attach for new targets
devTools.send(target.setAutoAttach());

// Listen for target detachment events
devTools.addListener(target.detached(), detachedTargetId -> {
    System.out.println("Target detached: " + detachedTargetId);
    
    // Clean up any tracking for this target
    synchronized (attachedTargets) {
        SessionID sessionId = attachedTargets.remove(detachedTargetId);
        if (sessionId != null) {
            System.out.println("Cleaned up session: " + sessionId);
        }
    }
});

// Open new tabs - they will be automatically attached
driver.executeScript("window.open('https://example.com/page1', '_blank');");
driver.executeScript("window.open('https://example.com/page2', '_blank');");

// Give some time for auto-attachment
Thread.sleep(1000);

// Check attached targets
List<TargetInfo> currentTargets = devTools.send(target.getTargets());
long attachedCount = currentTargets.stream()
    .filter(TargetInfo::getAttached)
    .count();

System.out.println("Currently attached to " + attachedCount + " targets");

Target Event Monitoring

Monitor target lifecycle events for dynamic target management.

Usage Examples:

import org.openqa.selenium.devtools.v115.target.Target;
import org.openqa.selenium.devtools.v115.target.model.TargetInfo;

// Listen for target creation events
devTools.addListener(Target.targetCreated(), targetInfo -> {
    System.out.println("New target created:");
    System.out.println("  ID: " + targetInfo.getTargetId());
    System.out.println("  Type: " + targetInfo.getType());
    System.out.println("  URL: " + targetInfo.getUrl());
    
    // Auto-attach to new page targets
    if ("page".equals(targetInfo.getType())) {
        try {
            SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
            System.out.println("  Auto-attached with session: " + sessionId);
        } catch (Exception e) {
            System.err.println("  Failed to auto-attach: " + e.getMessage());
        }
    }
});

// Listen for target info changes
devTools.addListener(Target.targetInfoChanged(), targetInfo -> {
    System.out.println("Target info updated:");
    System.out.println("  ID: " + targetInfo.getTargetId());
    System.out.println("  New Title: " + targetInfo.getTitle());
    System.out.println("  New URL: " + targetInfo.getUrl());
});

// Listen for target destruction
devTools.addListener(Target.targetDestroyed(), targetId -> {
    System.out.println("Target destroyed: " + targetId);
});

// Enable target domain for events
devTools.send(Target.setDiscoverTargets(true));

Advanced Target Management Patterns

Target-Specific DevTools Operations

Execute DevTools commands on specific targets using session IDs:

// Attach to a specific target
TargetID specificTarget = findTargetByUrl("https://api.example.com");
SessionID apiSession = devTools.send(target.attachToTarget(specificTarget));

// Execute commands on the specific target
devTools.send(
    org.openqa.selenium.devtools.v115.runtime.Runtime.enable(),
    apiSession
);

devTools.send(
    org.openqa.selenium.devtools.v115.runtime.Runtime.evaluate(
        "console.log('Hello from API target');",
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty(),
        Optional.empty()
    ),
    apiSession
);

Cross-Target Communication

Set up communication between different browser targets:

// Set up cross-target messaging system
Map<TargetID, SessionID> messagingTargets = new HashMap<>();

// Attach to all page targets
devTools.send(target.getTargets()).stream()
    .filter(t -> "page".equals(t.getType()))
    .forEach(targetInfo -> {
        try {
            SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
            messagingTargets.put(targetInfo.getTargetId(), sessionId);
            
            // Set up message listener on each target
            devTools.send(
                org.openqa.selenium.devtools.v115.runtime.Runtime.addBinding(
                    "crossTargetMessage", 
                    Optional.empty(), 
                    Optional.empty()
                ),
                sessionId
            );
            
        } catch (Exception e) {
            System.err.println("Failed to set up messaging for target: " + e.getMessage());
        }
    });

// Handle cross-target messages
devTools.addListener(
    org.openqa.selenium.devtools.v115.runtime.Runtime.bindingCalled(),
    bindingEvent -> {
        if ("crossTargetMessage".equals(bindingEvent.getName())) {
            String message = bindingEvent.getPayload();
            System.out.println("Cross-target message: " + message);
            
            // Broadcast to all other targets
            messagingTargets.values().forEach(sessionId -> {
                try {
                    devTools.send(
                        org.openqa.selenium.devtools.v115.runtime.Runtime.evaluate(
                            "console.log('Received cross-target message: " + message + "');",
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty()
                        ),
                        sessionId
                    );
                } catch (Exception e) {
                    System.err.println("Failed to broadcast message: " + e.getMessage());
                }
            });
        }
    }
);

Target Resource Management

Track and manage resources across multiple targets:

// Track target resources
Map<TargetID, TargetResources> targetResources = new ConcurrentHashMap<>();

class TargetResources {
    private final SessionID sessionId;
    private final Set<String> enabledDomains = ConcurrentHashMap.newKeySet();
    private final List<String> injectedScripts = new ArrayList<>();
    
    public TargetResources(SessionID sessionId) {
        this.sessionId = sessionId;
    }
    
    public void enableDomain(String domain) {
        enabledDomains.add(domain);
    }
    
    public void addScript(String script) {
        injectedScripts.add(script);
    }
    
    public void cleanup() {
        // Clean up resources for this target
        System.out.println("Cleaning up " + enabledDomains.size() + " domains and " + 
                          injectedScripts.size() + " scripts");
    }
}

// Set up resource tracking
devTools.addListener(target.detached(), detachedTargetId -> {
    TargetResources resources = targetResources.remove(detachedTargetId);
    if (resources != null) {
        resources.cleanup();
    }
});

Error Handling

Target Attachment Failures

Handle cases where target attachment fails:

try {
    SessionID sessionId = devTools.send(target.attachToTarget(targetId));
    System.out.println("Successfully attached to target");
} catch (Exception e) {
    System.err.println("Failed to attach to target: " + e.getMessage());
    
    // Check if target still exists
    List<TargetInfo> currentTargets = devTools.send(target.getTargets());
    boolean targetExists = currentTargets.stream()
        .anyMatch(t -> t.getTargetId().equals(targetId));
        
    if (!targetExists) {
        System.err.println("Target no longer exists");
    } else {
        System.err.println("Target exists but attachment failed - may already be attached");
    }
}

Session Management Errors

Handle session lifecycle errors gracefully:

// Track active sessions for cleanup
Set<SessionID> activeSessions = ConcurrentHashMap.newKeySet();

// Safe session cleanup
public void cleanupSession(SessionID sessionId) {
    if (activeSessions.contains(sessionId)) {
        try {
            devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
            activeSessions.remove(sessionId);
            System.out.println("Successfully cleaned up session: " + sessionId);
        } catch (Exception e) {
            System.err.println("Error cleaning up session " + sessionId + ": " + e.getMessage());
            // Remove from tracking even if cleanup failed
            activeSessions.remove(sessionId);
        }
    }
}

// Cleanup all sessions on shutdown
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    System.out.println("Cleaning up " + activeSessions.size() + " active sessions");
    activeSessions.forEach(this::cleanupSession);
}));

Target Discovery Errors

Handle target enumeration failures:

try {
    List<TargetInfo> targets = devTools.send(target.getTargets());
    System.out.println("Found " + targets.size() + " targets");
} catch (Exception e) {
    System.err.println("Failed to get target list: " + e.getMessage());
    
    // Fallback to basic target operations
    System.out.println("Falling back to current target only");
}

Install with Tessl CLI

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

docs

domain-management.md

index.md

javascript-integration.md

logging-operations.md

network-operations.md

runtime-events.md

target-management.md

tile.json