0
# Target Management
1
2
Browser target (tab/window/iframe) management including attachment, detachment, and target enumeration for multi-context automation. Enables advanced browser automation scenarios involving multiple tabs, windows, and execution contexts.
3
4
## Capabilities
5
6
### Target Handler
7
8
Creates a target management handler for Chrome DevTools Protocol v99.
9
10
```java { .api }
11
/**
12
* Target management implementation for CDP v99
13
* Implements the idealized Target interface
14
*/
15
public class V99Target implements org.openqa.selenium.devtools.idealized.target.Target;
16
```
17
18
### Target Attachment and Detachment
19
20
Attach to and detach from browser targets for multi-context automation.
21
22
```java { .api }
23
/**
24
* Attach to a specific target for DevTools communication
25
* @param targetId - ID of target to attach to
26
* @return Command returning session ID for the attached target
27
*/
28
public Command<SessionID> attachToTarget(TargetID targetId);
29
30
/**
31
* Detach from a target, ending DevTools communication
32
* @param sessionId - Optional session ID to detach
33
* @param targetId - Optional target ID to detach
34
* @return Command to detach from target
35
*/
36
public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);
37
38
/**
39
* Enable automatic attachment to new targets
40
* @return Command to enable auto-attach
41
*/
42
public Command<Void> setAutoAttach();
43
```
44
45
### Target Discovery
46
47
List and discover available browser targets.
48
49
```java { .api }
50
/**
51
* Get list of all available targets
52
* @return Command returning list of target information
53
*/
54
public Command<List<TargetInfo>> getTargets();
55
```
56
57
### Target Events
58
59
Monitor target lifecycle events.
60
61
```java { .api }
62
/**
63
* Get event for when targets are detached
64
* @return Event for target detachment
65
*/
66
public Event<TargetID> detached();
67
```
68
69
## Protocol Types
70
71
### Target Identification
72
73
```java { .api }
74
/**
75
* Unique identifier for browser targets
76
*/
77
public class TargetID {
78
/**
79
* Create target ID from string
80
* @param id - Target ID string
81
*/
82
public TargetID(String id);
83
84
/**
85
* Get target ID as string
86
* @return Target ID string
87
*/
88
public String toString();
89
}
90
91
/**
92
* Session identifier for DevTools connections
93
*/
94
public class SessionID {
95
/**
96
* Create session ID from string
97
* @param id - Session ID string
98
*/
99
public SessionID(String id);
100
101
/**
102
* Get session ID as string
103
* @return Session ID string
104
*/
105
public String toString();
106
}
107
108
/**
109
* Browser context identifier
110
*/
111
public class BrowserContextID {
112
/**
113
* Create browser context ID from string
114
* @param id - Context ID string
115
*/
116
public BrowserContextID(String id);
117
118
/**
119
* Get context ID as string
120
* @return Context ID string
121
*/
122
public String toString();
123
}
124
```
125
126
### Target Information
127
128
```java { .api }
129
/**
130
* Information about a browser target
131
*/
132
public class TargetInfo {
133
/**
134
* Create target information
135
* @param targetId - Target identifier
136
* @param type - Target type (page, background_page, etc.)
137
* @param title - Target title
138
* @param url - Target URL
139
* @param attached - Whether target is attached
140
* @param openerId - Optional opener target ID
141
* @param browserContextId - Optional browser context ID
142
*/
143
public TargetInfo(
144
TargetID targetId,
145
String type,
146
String title,
147
String url,
148
Boolean attached,
149
Optional<TargetID> openerId,
150
Optional<BrowserContextID> browserContextId
151
);
152
153
/**
154
* Get target ID
155
* @return Target identifier
156
*/
157
public TargetID getTargetId();
158
159
/**
160
* Get target type
161
* @return Type string (page, background_page, service_worker, etc.)
162
*/
163
public String getType();
164
165
/**
166
* Get target title (usually page title)
167
* @return Title string
168
*/
169
public String getTitle();
170
171
/**
172
* Get target URL
173
* @return URL string
174
*/
175
public String getUrl();
176
177
/**
178
* Check if target is attached
179
* @return True if attached to DevTools
180
*/
181
public Boolean getAttached();
182
183
/**
184
* Get opener target ID if target was opened by another target
185
* @return Optional opener target ID
186
*/
187
public Optional<TargetID> getOpenerId();
188
189
/**
190
* Get browser context ID
191
* @return Optional browser context ID
192
*/
193
public Optional<BrowserContextID> getBrowserContextId();
194
}
195
```
196
197
### Target Types
198
199
Common target types you may encounter:
200
- `"page"` - Regular web page/tab
201
- `"background_page"` - Extension background page
202
- `"service_worker"` - Service worker
203
- `"shared_worker"` - Shared worker
204
- `"browser"` - Browser-level target
205
- `"other"` - Other target types
206
207
## Usage Examples
208
209
### Basic Target Discovery
210
211
```java
212
import org.openqa.selenium.devtools.DevTools;
213
import org.openqa.selenium.devtools.v99.V99Domains;
214
import org.openqa.selenium.devtools.idealized.target.model.TargetInfo;
215
216
DevTools devTools = ...; // from ChromeDriver
217
V99Domains domains = new V99Domains(devTools);
218
219
// Get all available targets
220
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
221
222
System.out.println("Available targets:");
223
for (TargetInfo target : targets) {
224
System.out.printf(" %s: %s (%s) - %s%n",
225
target.getTargetId().toString(),
226
target.getTitle(),
227
target.getType(),
228
target.getUrl()
229
);
230
231
if (target.getAttached()) {
232
System.out.println(" [ATTACHED]");
233
}
234
}
235
```
236
237
### Multi-Tab Automation
238
239
```java
240
// Open a new tab
241
((JavascriptExecutor) driver).executeScript("window.open('about:blank', '_blank');");
242
243
// Get updated target list
244
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
245
246
// Find the new tab (page type, not attached)
247
TargetInfo newTab = targets.stream()
248
.filter(target -> "page".equals(target.getType()))
249
.filter(target -> !target.getAttached())
250
.findFirst()
251
.orElseThrow(() -> new RuntimeException("No new tab found"));
252
253
System.out.println("Found new tab: " + newTab.getTargetId());
254
255
// Attach to the new tab
256
SessionID sessionId = devTools.send(domains.target().attachToTarget(newTab.getTargetId()));
257
System.out.println("Attached with session ID: " + sessionId);
258
259
// Later, detach from the tab
260
devTools.send(domains.target().detachFromTarget(Optional.of(sessionId), Optional.of(newTab.getTargetId())));
261
```
262
263
### Target Event Monitoring
264
265
```java
266
// Enable auto-attach for new targets
267
devTools.send(domains.target().setAutoAttach());
268
269
// Monitor target detachment events
270
devTools.addListener(domains.target().detached(), targetId -> {
271
System.out.println("Target detached: " + targetId.toString());
272
273
// Clean up any resources associated with this target
274
cleanupTargetResources(targetId);
275
});
276
277
// Monitor for new targets (would require additional Target domain events)
278
// Note: V99Target doesn't expose target creation events directly
279
// You would need to poll getTargets() or use lower-level CDP events
280
```
281
282
### Selective Target Attachment
283
284
```java
285
// Get all targets
286
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
287
288
// Attach only to page targets that aren't already attached
289
List<SessionID> attachedSessions = new ArrayList<>();
290
291
for (TargetInfo target : targets) {
292
if ("page".equals(target.getType()) && !target.getAttached()) {
293
try {
294
SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));
295
attachedSessions.add(sessionId);
296
297
System.out.printf("Attached to page '%s' with session %s%n",
298
target.getTitle(), sessionId.toString());
299
} catch (Exception e) {
300
System.err.println("Failed to attach to target " + target.getTargetId() + ": " + e.getMessage());
301
}
302
}
303
}
304
305
// Later, clean up all attachments
306
for (SessionID sessionId : attachedSessions) {
307
try {
308
devTools.send(domains.target().detachFromTarget(Optional.of(sessionId), Optional.empty()));
309
} catch (Exception e) {
310
System.err.println("Failed to detach session " + sessionId + ": " + e.getMessage());
311
}
312
}
313
```
314
315
### Target Filtering and Classification
316
317
```java
318
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
319
320
// Classify targets by type
321
Map<String, List<TargetInfo>> targetsByType = targets.stream()
322
.collect(Collectors.groupingBy(TargetInfo::getType));
323
324
targetsByType.forEach((type, targetList) -> {
325
System.out.println(type + " targets (" + targetList.size() + "):");
326
targetList.forEach(target -> {
327
System.out.printf(" %s: %s%n", target.getTitle(), target.getUrl());
328
});
329
});
330
331
// Find main page targets (excluding extension pages, workers, etc.)
332
List<TargetInfo> pageTargets = targets.stream()
333
.filter(target -> "page".equals(target.getType()))
334
.filter(target -> !target.getUrl().startsWith("chrome-extension://"))
335
.collect(Collectors.toList());
336
337
System.out.println("Found " + pageTargets.size() + " page targets");
338
```
339
340
### Browser Context Management
341
342
```java
343
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
344
345
// Group targets by browser context
346
Map<Optional<BrowserContextID>, List<TargetInfo>> targetsByContext = targets.stream()
347
.collect(Collectors.groupingBy(TargetInfo::getBrowserContextId));
348
349
targetsByContext.forEach((contextId, targetList) -> {
350
String contextName = contextId.map(id -> id.toString()).orElse("default");
351
System.out.println("Browser context " + contextName + ":");
352
353
targetList.forEach(target -> {
354
System.out.printf(" %s (%s): %s%n",
355
target.getTitle(), target.getType(), target.getUrl());
356
});
357
});
358
```
359
360
### Target Hierarchy Tracking
361
362
```java
363
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
364
365
// Build parent-child relationships
366
Map<TargetID, List<TargetInfo>> childTargets = targets.stream()
367
.filter(target -> target.getOpenerId().isPresent())
368
.collect(Collectors.groupingBy(target -> target.getOpenerId().get()));
369
370
// Find root targets (no opener)
371
List<TargetInfo> rootTargets = targets.stream()
372
.filter(target -> target.getOpenerId().isEmpty())
373
.collect(Collectors.toList());
374
375
// Display hierarchy
376
for (TargetInfo rootTarget : rootTargets) {
377
displayTargetHierarchy(rootTarget, childTargets, 0);
378
}
379
380
private void displayTargetHierarchy(TargetInfo target, Map<TargetID, List<TargetInfo>> childMap, int depth) {
381
String indent = " ".repeat(depth);
382
System.out.printf("%s%s (%s): %s%n", indent, target.getTitle(), target.getType(), target.getUrl());
383
384
List<TargetInfo> children = childMap.getOrDefault(target.getTargetId(), Collections.emptyList());
385
for (TargetInfo child : children) {
386
displayTargetHierarchy(child, childMap, depth + 1);
387
}
388
}
389
```
390
391
## Error Handling
392
393
Target management operations can encounter various issues:
394
395
- **Invalid target IDs**: Target may have been closed before attachment
396
- **Session conflicts**: Multiple DevTools sessions on same target
397
- **Permission issues**: Some targets may not allow attachment
398
- **Context mismatches**: Targets in different browser contexts have different capabilities
399
400
Handle errors through proper exception handling:
401
402
```java
403
try {
404
List<TargetInfo> targets = devTools.send(domains.target().getTargets());
405
406
for (TargetInfo target : targets) {
407
if (shouldAttachToTarget(target)) {
408
try {
409
SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));
410
handleAttachedTarget(target.getTargetId(), sessionId);
411
} catch (DevToolsException e) {
412
System.err.println("Failed to attach to target " + target.getTargetId() + ": " + e.getMessage());
413
// Continue with other targets
414
}
415
}
416
}
417
} catch (DevToolsException e) {
418
System.err.println("Failed to get targets: " + e.getMessage());
419
}
420
```
421
422
## Performance Considerations
423
424
- **Target polling**: Frequent `getTargets()` calls can impact performance
425
- **Session management**: Too many attached sessions consume browser resources
426
- **Event processing**: Target events should be processed efficiently
427
- **Memory usage**: Maintaining references to many targets can consume memory
428
- **Network overhead**: Remote debugging increases target-related network traffic
429
430
## Security Considerations
431
432
- **Cross-origin restrictions**: Some targets may be in different security contexts
433
- **Extension isolation**: Extension targets have different permissions
434
- **Private browsing**: Targets in private contexts may have restricted access
435
- **Iframe limitations**: Some iframe targets may not allow external attachment