or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

console-logging.mddomain-management.mdindex.mdjavascript-execution.mdnetwork-operations.mdruntime-events.mdtarget-management.md

target-management.mddocs/

0

# Target Management

1

2

Manages browser targets (tabs, windows, workers), attachment/detachment operations, and target information retrieval. This domain enables control over multiple browser contexts and automation of complex multi-target scenarios.

3

4

## Capabilities

5

6

### V102Target Class

7

8

Main class for browser target management. Implements the idealized Target interface to provide v102-specific implementations for target operations and information retrieval.

9

10

```java { .api }

11

/**

12

* Manages browser targets (tabs, windows, workers)

13

*/

14

public class V102Target implements org.openqa.selenium.devtools.idealized.target.Target {

15

/**

16

* Detaches from a specific target using session ID or target ID

17

* @param sessionId Optional session identifier for the target connection

18

* @param targetId Optional target identifier to detach from

19

* @return Command to detach from target

20

*/

21

public Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);

22

23

/**

24

* Retrieves information about all available targets

25

* @return Command returning list of target information objects

26

*/

27

public Command<List<org.openqa.selenium.devtools.idealized.target.model.TargetInfo>> getTargets();

28

29

/**

30

* Attaches to a specific target for DevTools communication

31

* @param targetId Target identifier to attach to

32

* @return Command returning session ID for the new attachment

33

*/

34

public Command<SessionID> attachToTarget(TargetID targetId);

35

36

/**

37

* Sets automatic attachment for new targets as they are created

38

* Enables automatic DevTools connection to new tabs/windows

39

* @return Command to enable auto-attach for new targets

40

*/

41

public Command<Void> setAutoAttach();

42

43

/**

44

* Returns the target detached event for monitoring target disconnections

45

* @return Event for target detachment notifications

46

*/

47

public Event<TargetID> detached();

48

}

49

```

50

51

**Usage Examples:**

52

53

### Basic Target Discovery

54

55

```java

56

import org.openqa.selenium.chrome.ChromeDriver;

57

import org.openqa.selenium.devtools.DevTools;

58

import org.openqa.selenium.devtools.v102.V102Domains;

59

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

60

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

61

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

62

import java.util.List;

63

64

// Setup

65

ChromeDriver driver = new ChromeDriver();

66

DevTools devTools = driver.getDevTools();

67

devTools.createSession();

68

V102Domains domains = new V102Domains(devTools);

69

70

// Get all available targets

71

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

72

73

System.out.println("Available targets:");

74

for (TargetInfo target : targets) {

75

System.out.println(String.format(

76

"Target: %s - %s (%s) - %s",

77

target.getTargetId(),

78

target.getTitle(),

79

target.getType(),

80

target.getUrl()

81

));

82

}

83

84

// Find page targets

85

targets.stream()

86

.filter(target -> "page".equals(target.getType()))

87

.forEach(target -> {

88

System.out.println("Page target: " + target.getTitle() + " - " + target.getUrl());

89

});

90

```

91

92

### Target Attachment and Communication

93

94

```java

95

// Attach to specific targets for independent communication

96

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

97

98

for (TargetInfo target : targets) {

99

if ("page".equals(target.getType()) && !target.getAttached()) {

100

// Attach to unattached page targets

101

SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));

102

System.out.println("Attached to target " + target.getTargetId() + " with session " + sessionId);

103

104

// Now you can send commands to this specific target using the sessionId

105

// (This requires more advanced DevTools session management)

106

}

107

}

108

```

109

110

### Auto-Attach for New Targets

111

112

```java

113

// Enable automatic attachment to new targets

114

devTools.send(domains.target().setAutoAttach());

115

116

// Listen for target detachment events

117

devTools.addListener(domains.target().detached(), (targetId) -> {

118

System.out.println("Target detached: " + targetId);

119

});

120

121

// Open new tab - will be automatically attached

122

driver.executeScript("window.open('https://example.com', '_blank');");

123

124

// List targets again to see the new one

125

List<TargetInfo> updatedTargets = devTools.send(domains.target().getTargets());

126

System.out.println("Targets after opening new tab: " + updatedTargets.size());

127

```

128

129

### Multi-Target Management

130

131

```java

132

import java.util.Map;

133

import java.util.HashMap;

134

135

// Track attached targets and their sessions

136

Map<TargetID, SessionID> attachedTargets = new HashMap<>();

137

138

// Get initial targets

139

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

140

141

// Attach to all page targets

142

for (TargetInfo target : targets) {

143

if ("page".equals(target.getType()) && !target.getAttached()) {

144

try {

145

SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));

146

attachedTargets.put(target.getTargetId(), sessionId);

147

System.out.println("Attached to: " + target.getTitle());

148

} catch (Exception e) {

149

System.err.println("Failed to attach to target " + target.getTargetId() + ": " + e.getMessage());

150

}

151

}

152

}

153

154

// Monitor for target detachment

155

devTools.addListener(domains.target().detached(), (targetId) -> {

156

if (attachedTargets.containsKey(targetId)) {

157

SessionID sessionId = attachedTargets.remove(targetId);

158

System.out.println("Target " + targetId + " detached (was session " + sessionId + ")");

159

}

160

});

161

162

// Detach from specific targets when done

163

for (Map.Entry<TargetID, SessionID> entry : attachedTargets.entrySet()) {

164

devTools.send(domains.target().detachFromTarget(

165

Optional.of(entry.getValue()),

166

Optional.of(entry.getKey())

167

));

168

}

169

```

170

171

### Target Filtering and Selection

172

173

```java

174

import java.util.Optional;

175

176

// Find specific types of targets

177

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

178

179

// Find the main page target

180

Optional<TargetInfo> mainPage = targets.stream()

181

.filter(target -> "page".equals(target.getType()))

182

.filter(target -> target.getUrl().startsWith("https://"))

183

.findFirst();

184

185

if (mainPage.isPresent()) {

186

System.out.println("Main page: " + mainPage.get().getTitle());

187

}

188

189

// Find service worker targets

190

List<TargetInfo> serviceWorkers = targets.stream()

191

.filter(target -> "service_worker".equals(target.getType()))

192

.collect(Collectors.toList());

193

194

System.out.println("Service workers: " + serviceWorkers.size());

195

196

// Find background pages (extensions)

197

List<TargetInfo> backgroundPages = targets.stream()

198

.filter(target -> "background_page".equals(target.getType()))

199

.collect(Collectors.toList());

200

201

System.out.println("Background pages: " + backgroundPages.size());

202

```

203

204

## CDP Protocol Classes

205

206

The V102Target class interacts with generated CDP protocol classes:

207

208

### Target Domain

209

210

```java { .api }

211

// Generated CDP target classes (available at runtime)

212

class Target {

213

static Command<GetTargetsResponse> getTargets();

214

static Command<AttachToTargetResponse> attachToTarget(TargetID targetId, boolean flatten);

215

static Command<Void> detachFromTarget(Optional<SessionID> sessionId, Optional<TargetID> targetId);

216

static Command<Void> setAutoAttach(boolean autoAttach, boolean waitForDebuggerOnStart, Optional<Boolean> flatten);

217

static Event<DetachedFromTargetEvent> detachedFromTarget();

218

}

219

220

// Target information from CDP

221

class TargetInfo {

222

TargetID getTargetId();

223

String getType();

224

String getTitle();

225

String getUrl();

226

boolean getAttached();

227

Optional<TargetID> getOpenerId();

228

Optional<BrowserContextID> getBrowserContextId();

229

}

230

231

// Target and session identifiers

232

class TargetID {

233

TargetID(String id);

234

String toString();

235

}

236

237

class SessionID {

238

SessionID(String id);

239

String toString();

240

}

241

242

class BrowserContextID {

243

BrowserContextID(String id);

244

String toString();

245

}

246

```

247

248

### Target Event Data

249

250

```java { .api }

251

// Detachment event data

252

class DetachedFromTargetEvent {

253

Optional<SessionID> getSessionId();

254

Optional<TargetID> getTargetId();

255

}

256

```

257

258

### High-Level Target Types

259

260

Different types of targets you may encounter:

261

262

- **page**: Regular web pages and tabs

263

- **service_worker**: Service worker instances

264

- **shared_worker**: Shared worker instances

265

- **background_page**: Extension background pages

266

- **webview**: Embedded webview instances

267

- **iframe**: Frame targets (when site isolation is enabled)

268

- **other**: Other miscellaneous targets

269

270

## Target Management Patterns

271

272

### Target Lifecycle Monitoring

273

274

```java

275

// Monitor complete target lifecycle

276

devTools.send(domains.target().setAutoAttach());

277

278

// Track target creation through getTargets polling

279

Set<TargetID> knownTargets = new HashSet<>();

280

List<TargetInfo> initialTargets = devTools.send(domains.target().getTargets());

281

initialTargets.forEach(target -> knownTargets.add(target.getTargetId()));

282

283

// Listen for detachment

284

devTools.addListener(domains.target().detached(), (targetId) -> {

285

knownTargets.remove(targetId);

286

System.out.println("Target lifecycle ended: " + targetId);

287

});

288

289

// Periodically check for new targets

290

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

291

scheduler.scheduleAtFixedRate(() -> {

292

try {

293

List<TargetInfo> currentTargets = devTools.send(domains.target().getTargets());

294

for (TargetInfo target : currentTargets) {

295

if (!knownTargets.contains(target.getTargetId())) {

296

knownTargets.add(target.getTargetId());

297

System.out.println("New target detected: " + target.getTitle());

298

}

299

}

300

} catch (Exception e) {

301

System.err.println("Error checking targets: " + e.getMessage());

302

}

303

}, 1, 1, TimeUnit.SECONDS);

304

```

305

306

### Selective Target Attachment

307

308

```java

309

// Attach only to specific target types or URLs

310

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

311

312

for (TargetInfo target : targets) {

313

boolean shouldAttach = false;

314

315

// Attach to main application pages

316

if ("page".equals(target.getType()) &&

317

target.getUrl().contains("myapp.com")) {

318

shouldAttach = true;

319

}

320

321

// Attach to service workers for the application

322

if ("service_worker".equals(target.getType()) &&

323

target.getUrl().contains("myapp.com")) {

324

shouldAttach = true;

325

}

326

327

if (shouldAttach && !target.getAttached()) {

328

try {

329

SessionID sessionId = devTools.send(domains.target().attachToTarget(target.getTargetId()));

330

System.out.println("Attached to " + target.getType() + ": " + target.getTitle());

331

} catch (Exception e) {

332

System.err.println("Failed to attach to target: " + e.getMessage());

333

}

334

}

335

}

336

```

337

338

### Target Information Analysis

339

340

```java

341

// Analyze target relationships and hierarchy

342

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

343

344

// Group targets by opener (parent-child relationships)

345

Map<Optional<TargetID>, List<TargetInfo>> targetsByOpener = targets.stream()

346

.collect(Collectors.groupingBy(TargetInfo::getOpenerId));

347

348

// Print target hierarchy

349

targetsByOpener.forEach((openerId, targetList) -> {

350

if (openerId.isPresent()) {

351

System.out.println("Targets opened by " + openerId.get() + ":");

352

} else {

353

System.out.println("Root targets:");

354

}

355

356

targetList.forEach(target -> {

357

System.out.println(" " + target.getType() + ": " + target.getTitle());

358

});

359

});

360

361

// Find browser context information

362

targets.forEach(target -> {

363

target.getBrowserContextId().ifPresent(contextId -> {

364

System.out.println("Target " + target.getTargetId() + " in context " + contextId);

365

});

366

});

367

```

368

369

### Error Handling in Target Operations

370

371

```java

372

// Robust target attachment with error handling

373

public SessionID safeAttachToTarget(TargetID targetId) {

374

try {

375

// Verify target still exists

376

List<TargetInfo> targets = devTools.send(domains.target().getTargets());

377

boolean targetExists = targets.stream()

378

.anyMatch(target -> target.getTargetId().equals(targetId));

379

380

if (!targetExists) {

381

throw new IllegalArgumentException("Target " + targetId + " no longer exists");

382

}

383

384

// Attempt attachment

385

SessionID sessionId = devTools.send(domains.target().attachToTarget(targetId));

386

System.out.println("Successfully attached to target " + targetId);

387

return sessionId;

388

389

} catch (Exception e) {

390

System.err.println("Failed to attach to target " + targetId + ": " + e.getMessage());

391

throw new RuntimeException("Target attachment failed", e);

392

}

393

}

394

395

// Safe detachment

396

public void safeDetachFromTarget(SessionID sessionId, TargetID targetId) {

397

try {

398

devTools.send(domains.target().detachFromTarget(

399

Optional.of(sessionId),

400

Optional.of(targetId)

401

));

402

System.out.println("Successfully detached from target " + targetId);

403

} catch (Exception e) {

404

System.err.println("Failed to detach from target " + targetId + ": " + e.getMessage());

405

// Continue execution - detachment failures are often not critical

406

}

407

}

408

```