or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

events.mdindex.mdjavascript.mdlogging.mdnetwork.mdtargets.md

targets.mddocs/

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