0
# Target & Session Management
1
2
Browser target (tab/window) management, debugging session control, and multi-target coordination with attachment and detachment capabilities through the v115Target class.
3
4
## Capabilities
5
6
### Target Domain
7
8
Comprehensive target management for controlling browser tabs, windows, and debugging sessions.
9
10
```java { .api }
11
/**
12
* Target domain for browser target and session management
13
* Implements the idealized Target interface for version independence
14
*/
15
public class v115Target implements Target {
16
/**
17
* Detach from a specific target or session
18
* @param sessionId Optional session ID to detach from
19
* @param targetId Optional target ID to detach from
20
* @return Command to detach from target
21
*/
22
public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);
23
24
/**
25
* Get list of all available targets
26
* @return Command returning list of TargetInfo objects
27
*/
28
public Command<List<TargetInfo>> getTargets();
29
30
/**
31
* Attach to a target for debugging
32
* @param targetId Target ID to attach to
33
* @return Command returning SessionID for the debugging session
34
*/
35
public Command<SessionID> attachToTarget(TargetID targetId);
36
37
/**
38
* Set automatic attachment behavior for new targets
39
* @return Command to enable auto-attach for new targets
40
*/
41
public Command<Void> setAutoAttach();
42
43
/**
44
* Get target detached event stream
45
* @return Event stream for target detachment notifications
46
*/
47
public Event<TargetID> detached();
48
}
49
```
50
51
### Target Discovery
52
53
Discover and enumerate all browser targets including tabs, service workers, and other contexts.
54
55
**Usage Examples:**
56
57
```java
58
import org.openqa.selenium.devtools.v115.v115Target;
59
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;
60
import org.openqa.selenium.devtools.idealized.target.model.TargetID;
61
62
// Create target domain
63
v115Target target = new v115Target();
64
65
// Get all available targets
66
List<TargetInfo> targets = devTools.send(target.getTargets());
67
68
System.out.println("Found " + targets.size() + " targets:");
69
for (TargetInfo targetInfo : targets) {
70
System.out.println("Target ID: " + targetInfo.getTargetId());
71
System.out.println(" Type: " + targetInfo.getType());
72
System.out.println(" Title: " + targetInfo.getTitle());
73
System.out.println(" URL: " + targetInfo.getUrl());
74
System.out.println(" Attached: " + targetInfo.getAttached());
75
76
if (targetInfo.getOpenerId().isPresent()) {
77
System.out.println(" Opener: " + targetInfo.getOpenerId().get());
78
}
79
80
if (targetInfo.getBrowserContextId().isPresent()) {
81
System.out.println(" Context: " + targetInfo.getBrowserContextId().get());
82
}
83
84
System.out.println();
85
}
86
```
87
88
### Target Attachment
89
90
Attach to specific targets for debugging and control multiple browser contexts.
91
92
**Usage Examples:**
93
94
```java
95
import org.openqa.selenium.devtools.idealized.target.model.SessionID;
96
97
// Find target to attach to (e.g., a specific tab)
98
List<TargetInfo> targets = devTools.send(target.getTargets());
99
Optional<TargetInfo> pageTarget = targets.stream()
100
.filter(t -> "page".equals(t.getType()))
101
.filter(t -> t.getUrl().contains("example.com"))
102
.findFirst();
103
104
if (pageTarget.isPresent()) {
105
TargetID targetId = pageTarget.get().getTargetId();
106
107
// Attach to the target
108
SessionID sessionId = devTools.send(target.attachToTarget(targetId));
109
System.out.println("Attached to target with session: " + sessionId);
110
111
// Use the session for target-specific operations
112
// Note: Attached sessions can be used with DevTools.send() by specifying sessionId
113
114
// Detach when done
115
devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
116
System.out.println("Detached from target");
117
}
118
```
119
120
### Multi-Target Coordination
121
122
Coordinate operations across multiple browser targets simultaneously.
123
124
**Usage Examples:**
125
126
```java
127
import java.util.Map;
128
import java.util.HashMap;
129
import java.util.concurrent.CompletableFuture;
130
import java.util.concurrent.ExecutorService;
131
import java.util.concurrent.Executors;
132
133
// Set up multi-target management
134
Map<TargetID, SessionID> attachedTargets = new HashMap<>();
135
ExecutorService executor = Executors.newCachedThreadPool();
136
137
// Get all page targets
138
List<TargetInfo> pageTargets = devTools.send(target.getTargets()).stream()
139
.filter(t -> "page".equals(t.getType()))
140
.toList();
141
142
// Attach to all page targets
143
List<CompletableFuture<Void>> attachTasks = pageTargets.stream()
144
.map(targetInfo -> CompletableFuture.runAsync(() -> {
145
try {
146
TargetID targetId = targetInfo.getTargetId();
147
SessionID sessionId = devTools.send(target.attachToTarget(targetId));
148
149
synchronized (attachedTargets) {
150
attachedTargets.put(targetId, sessionId);
151
}
152
153
System.out.println("Attached to target: " + targetInfo.getTitle());
154
} catch (Exception e) {
155
System.err.println("Failed to attach to target: " + e.getMessage());
156
}
157
}, executor))
158
.toList();
159
160
// Wait for all attachments to complete
161
CompletableFuture.allOf(attachTasks.toArray(new CompletableFuture[0]))
162
.join();
163
164
System.out.println("Attached to " + attachedTargets.size() + " targets");
165
166
// Perform operations on all attached targets
167
attachedTargets.forEach((targetId, sessionId) -> {
168
try {
169
// Example: Enable runtime on each target
170
devTools.send(
171
org.openqa.selenium.devtools.v115.runtime.Runtime.enable(),
172
sessionId
173
);
174
} catch (Exception e) {
175
System.err.println("Error enabling runtime on target " + targetId + ": " + e.getMessage());
176
}
177
});
178
179
// Clean up - detach from all targets
180
attachedTargets.forEach((targetId, sessionId) -> {
181
try {
182
devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
183
} catch (Exception e) {
184
System.err.println("Error detaching from target " + targetId + ": " + e.getMessage());
185
}
186
});
187
188
executor.shutdown();
189
```
190
191
### Auto-Attach Configuration
192
193
Configure automatic attachment to new targets as they are created.
194
195
**Usage Examples:**
196
197
```java
198
// Enable auto-attach for new targets
199
devTools.send(target.setAutoAttach());
200
201
// Listen for target detachment events
202
devTools.addListener(target.detached(), detachedTargetId -> {
203
System.out.println("Target detached: " + detachedTargetId);
204
205
// Clean up any tracking for this target
206
synchronized (attachedTargets) {
207
SessionID sessionId = attachedTargets.remove(detachedTargetId);
208
if (sessionId != null) {
209
System.out.println("Cleaned up session: " + sessionId);
210
}
211
}
212
});
213
214
// Open new tabs - they will be automatically attached
215
driver.executeScript("window.open('https://example.com/page1', '_blank');");
216
driver.executeScript("window.open('https://example.com/page2', '_blank');");
217
218
// Give some time for auto-attachment
219
Thread.sleep(1000);
220
221
// Check attached targets
222
List<TargetInfo> currentTargets = devTools.send(target.getTargets());
223
long attachedCount = currentTargets.stream()
224
.filter(TargetInfo::getAttached)
225
.count();
226
227
System.out.println("Currently attached to " + attachedCount + " targets");
228
```
229
230
### Target Event Monitoring
231
232
Monitor target lifecycle events for dynamic target management.
233
234
**Usage Examples:**
235
236
```java
237
import org.openqa.selenium.devtools.v115.target.Target;
238
import org.openqa.selenium.devtools.v115.target.model.TargetInfo;
239
240
// Listen for target creation events
241
devTools.addListener(Target.targetCreated(), targetInfo -> {
242
System.out.println("New target created:");
243
System.out.println(" ID: " + targetInfo.getTargetId());
244
System.out.println(" Type: " + targetInfo.getType());
245
System.out.println(" URL: " + targetInfo.getUrl());
246
247
// Auto-attach to new page targets
248
if ("page".equals(targetInfo.getType())) {
249
try {
250
SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
251
System.out.println(" Auto-attached with session: " + sessionId);
252
} catch (Exception e) {
253
System.err.println(" Failed to auto-attach: " + e.getMessage());
254
}
255
}
256
});
257
258
// Listen for target info changes
259
devTools.addListener(Target.targetInfoChanged(), targetInfo -> {
260
System.out.println("Target info updated:");
261
System.out.println(" ID: " + targetInfo.getTargetId());
262
System.out.println(" New Title: " + targetInfo.getTitle());
263
System.out.println(" New URL: " + targetInfo.getUrl());
264
});
265
266
// Listen for target destruction
267
devTools.addListener(Target.targetDestroyed(), targetId -> {
268
System.out.println("Target destroyed: " + targetId);
269
});
270
271
// Enable target domain for events
272
devTools.send(Target.setDiscoverTargets(true));
273
```
274
275
## Advanced Target Management Patterns
276
277
### Target-Specific DevTools Operations
278
279
Execute DevTools commands on specific targets using session IDs:
280
281
```java
282
// Attach to a specific target
283
TargetID specificTarget = findTargetByUrl("https://api.example.com");
284
SessionID apiSession = devTools.send(target.attachToTarget(specificTarget));
285
286
// Execute commands on the specific target
287
devTools.send(
288
org.openqa.selenium.devtools.v115.runtime.Runtime.enable(),
289
apiSession
290
);
291
292
devTools.send(
293
org.openqa.selenium.devtools.v115.runtime.Runtime.evaluate(
294
"console.log('Hello from API target');",
295
Optional.empty(),
296
Optional.empty(),
297
Optional.empty(),
298
Optional.empty(),
299
Optional.empty(),
300
Optional.empty(),
301
Optional.empty(),
302
Optional.empty(),
303
Optional.empty(),
304
Optional.empty(),
305
Optional.empty(),
306
Optional.empty(),
307
Optional.empty(),
308
Optional.empty(),
309
Optional.empty(),
310
Optional.empty(),
311
Optional.empty(),
312
Optional.empty(),
313
Optional.empty()
314
),
315
apiSession
316
);
317
```
318
319
### Cross-Target Communication
320
321
Set up communication between different browser targets:
322
323
```java
324
// Set up cross-target messaging system
325
Map<TargetID, SessionID> messagingTargets = new HashMap<>();
326
327
// Attach to all page targets
328
devTools.send(target.getTargets()).stream()
329
.filter(t -> "page".equals(t.getType()))
330
.forEach(targetInfo -> {
331
try {
332
SessionID sessionId = devTools.send(target.attachToTarget(targetInfo.getTargetId()));
333
messagingTargets.put(targetInfo.getTargetId(), sessionId);
334
335
// Set up message listener on each target
336
devTools.send(
337
org.openqa.selenium.devtools.v115.runtime.Runtime.addBinding(
338
"crossTargetMessage",
339
Optional.empty(),
340
Optional.empty()
341
),
342
sessionId
343
);
344
345
} catch (Exception e) {
346
System.err.println("Failed to set up messaging for target: " + e.getMessage());
347
}
348
});
349
350
// Handle cross-target messages
351
devTools.addListener(
352
org.openqa.selenium.devtools.v115.runtime.Runtime.bindingCalled(),
353
bindingEvent -> {
354
if ("crossTargetMessage".equals(bindingEvent.getName())) {
355
String message = bindingEvent.getPayload();
356
System.out.println("Cross-target message: " + message);
357
358
// Broadcast to all other targets
359
messagingTargets.values().forEach(sessionId -> {
360
try {
361
devTools.send(
362
org.openqa.selenium.devtools.v115.runtime.Runtime.evaluate(
363
"console.log('Received cross-target message: " + message + "');",
364
Optional.empty(),
365
Optional.empty(),
366
Optional.empty(),
367
Optional.empty(),
368
Optional.empty(),
369
Optional.empty(),
370
Optional.empty(),
371
Optional.empty(),
372
Optional.empty(),
373
Optional.empty(),
374
Optional.empty(),
375
Optional.empty(),
376
Optional.empty(),
377
Optional.empty(),
378
Optional.empty(),
379
Optional.empty(),
380
Optional.empty(),
381
Optional.empty(),
382
Optional.empty()
383
),
384
sessionId
385
);
386
} catch (Exception e) {
387
System.err.println("Failed to broadcast message: " + e.getMessage());
388
}
389
});
390
}
391
}
392
);
393
```
394
395
### Target Resource Management
396
397
Track and manage resources across multiple targets:
398
399
```java
400
// Track target resources
401
Map<TargetID, TargetResources> targetResources = new ConcurrentHashMap<>();
402
403
class TargetResources {
404
private final SessionID sessionId;
405
private final Set<String> enabledDomains = ConcurrentHashMap.newKeySet();
406
private final List<String> injectedScripts = new ArrayList<>();
407
408
public TargetResources(SessionID sessionId) {
409
this.sessionId = sessionId;
410
}
411
412
public void enableDomain(String domain) {
413
enabledDomains.add(domain);
414
}
415
416
public void addScript(String script) {
417
injectedScripts.add(script);
418
}
419
420
public void cleanup() {
421
// Clean up resources for this target
422
System.out.println("Cleaning up " + enabledDomains.size() + " domains and " +
423
injectedScripts.size() + " scripts");
424
}
425
}
426
427
// Set up resource tracking
428
devTools.addListener(target.detached(), detachedTargetId -> {
429
TargetResources resources = targetResources.remove(detachedTargetId);
430
if (resources != null) {
431
resources.cleanup();
432
}
433
});
434
```
435
436
## Error Handling
437
438
### Target Attachment Failures
439
440
Handle cases where target attachment fails:
441
442
```java
443
try {
444
SessionID sessionId = devTools.send(target.attachToTarget(targetId));
445
System.out.println("Successfully attached to target");
446
} catch (Exception e) {
447
System.err.println("Failed to attach to target: " + e.getMessage());
448
449
// Check if target still exists
450
List<TargetInfo> currentTargets = devTools.send(target.getTargets());
451
boolean targetExists = currentTargets.stream()
452
.anyMatch(t -> t.getTargetId().equals(targetId));
453
454
if (!targetExists) {
455
System.err.println("Target no longer exists");
456
} else {
457
System.err.println("Target exists but attachment failed - may already be attached");
458
}
459
}
460
```
461
462
### Session Management Errors
463
464
Handle session lifecycle errors gracefully:
465
466
```java
467
// Track active sessions for cleanup
468
Set<SessionID> activeSessions = ConcurrentHashMap.newKeySet();
469
470
// Safe session cleanup
471
public void cleanupSession(SessionID sessionId) {
472
if (activeSessions.contains(sessionId)) {
473
try {
474
devTools.send(target.detachFromTarget(Optional.of(sessionId), Optional.empty()));
475
activeSessions.remove(sessionId);
476
System.out.println("Successfully cleaned up session: " + sessionId);
477
} catch (Exception e) {
478
System.err.println("Error cleaning up session " + sessionId + ": " + e.getMessage());
479
// Remove from tracking even if cleanup failed
480
activeSessions.remove(sessionId);
481
}
482
}
483
}
484
485
// Cleanup all sessions on shutdown
486
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
487
System.out.println("Cleaning up " + activeSessions.size() + " active sessions");
488
activeSessions.forEach(this::cleanupSession);
489
}));
490
```
491
492
### Target Discovery Errors
493
494
Handle target enumeration failures:
495
496
```java
497
try {
498
List<TargetInfo> targets = devTools.send(target.getTargets());
499
System.out.println("Found " + targets.size() + " targets");
500
} catch (Exception e) {
501
System.err.println("Failed to get target list: " + e.getMessage());
502
503
// Fallback to basic target operations
504
System.out.println("Falling back to current target only");
505
}
506
```