or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

events.mdindex.mdjavascript.mdlogging.mdnetwork.mdtarget.md

javascript.mddocs/

0

# JavaScript Operations

1

2

JavaScript evaluation, runtime bindings, and script injection capabilities for advanced browser interaction using Chrome DevTools Protocol v110.

3

4

## Capabilities

5

6

### JavaScript Domain Wrapper

7

8

High-level wrapper for CDP JavaScript/Runtime functionality providing type-safe access to script execution and runtime bindings.

9

10

```java { .api }

11

/**

12

* JavaScript domain wrapper for CDP v110 runtime operations

13

*/

14

public class v110Javascript extends Javascript<ScriptIdentifier, BindingCalled> {

15

/**

16

* Initialize JavaScript domain with DevTools session

17

* @param devtools Active DevTools session

18

*/

19

public v110Javascript(DevTools devtools);

20

}

21

```

22

23

### Runtime Domain Control

24

25

Enable and disable runtime domain for JavaScript operations.

26

27

```java { .api }

28

/**

29

* Enable runtime domain for JavaScript execution

30

* @return Command to enable runtime

31

*/

32

protected Command<Void> enableRuntime();

33

34

/**

35

* Disable runtime domain

36

* @return Command to disable runtime

37

*/

38

protected Command<Void> disableRuntime();

39

```

40

41

### JavaScript Bindings

42

43

Create bidirectional communication between Java and JavaScript through runtime bindings.

44

45

```java { .api }

46

/**

47

* Add JavaScript binding to runtime

48

* @param scriptName Name of binding in JavaScript global scope

49

* @return Command to add binding

50

*/

51

protected Command<Void> doAddJsBinding(String scriptName);

52

53

/**

54

* Remove JavaScript binding from runtime

55

* @param scriptName Name of binding to remove

56

* @return Command to remove binding

57

*/

58

protected Command<Void> doRemoveJsBinding(String scriptName);

59

60

/**

61

* Get binding called events

62

* @return Event stream for binding calls

63

*/

64

protected Event<BindingCalled> bindingCalledEvent();

65

66

/**

67

* Extract payload from binding event

68

* @param event Binding called event

69

* @return String payload from JavaScript

70

*/

71

protected String extractPayload(BindingCalled event);

72

```

73

74

**Usage Example:**

75

76

```java

77

import org.openqa.selenium.devtools.v110.v110Javascript;

78

import org.openqa.selenium.devtools.v110.runtime.model.BindingCalled;

79

80

v110Javascript javascript = new v110Javascript(devTools);

81

82

// Enable runtime and add binding

83

devTools.send(javascript.enableRuntime());

84

devTools.send(javascript.doAddJsBinding("javaCallback"));

85

86

// Listen for binding calls

87

devTools.addListener(javascript.bindingCalledEvent(), event -> {

88

String payload = javascript.extractPayload(event);

89

System.out.println("JavaScript called Java with: " + payload);

90

91

// Process the call and potentially respond

92

handleJavaScriptCallback(payload);

93

});

94

95

// Navigate to page and use binding

96

driver.get("https://example.com");

97

driver.executeScript("javaCallback('Hello from JavaScript!');");

98

```

99

100

### Page Domain Control

101

102

Enable page domain for script injection and page-level operations.

103

104

```java { .api }

105

/**

106

* Enable page domain

107

* @return Command to enable page domain

108

*/

109

protected Command<Void> enablePage();

110

111

/**

112

* Disable page domain

113

* @return Command to disable page domain

114

*/

115

protected Command<Void> disablePage();

116

```

117

118

### Script Injection

119

120

Inject JavaScript code to be evaluated on new document creation.

121

122

```java { .api }

123

/**

124

* Add script to evaluate on new document

125

* @param script JavaScript code to inject

126

* @return Command returning script identifier

127

*/

128

protected Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(String script);

129

130

/**

131

* Remove previously added script

132

* @param id Script identifier to remove

133

* @return Command to remove script

134

*/

135

protected Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier id);

136

```

137

138

**Usage Example:**

139

140

```java

141

import org.openqa.selenium.devtools.v110.page.model.ScriptIdentifier;

142

143

// Enable page domain

144

devTools.send(javascript.enablePage());

145

146

// Add script that runs on every page load

147

String initScript = """

148

window.myApp = {

149

initialized: true,

150

version: '1.0.0',

151

log: function(msg) {

152

console.log('[MyApp] ' + msg);

153

}

154

};

155

window.myApp.log('Application initialized');

156

""";

157

158

ScriptIdentifier scriptId = devTools.send(

159

javascript.addScriptToEvaluateOnNewDocument(initScript)

160

);

161

162

// Navigate - script will run automatically

163

driver.get("https://example.com");

164

165

// Later remove the script

166

devTools.send(javascript.removeScriptToEvaluateOnNewDocument(scriptId));

167

```

168

169

### High-Level JavaScript Operations

170

171

Convenient methods for common JavaScript operations (inherited from base Javascript class).

172

173

```java { .api }

174

/**

175

* Add JavaScript binding with automatic event handling

176

* @param bindingName Name for JavaScript binding

177

* @param handler Function to handle binding calls

178

*/

179

public void addJsBinding(String bindingName, Consumer<String> handler);

180

181

/**

182

* Remove JavaScript binding

183

* @param bindingName Name of binding to remove

184

*/

185

public void removeJsBinding(String bindingName);

186

187

/**

188

* Pin script for evaluation on new documents

189

* @param scriptName Name/identifier for script

190

* @param script JavaScript code to pin

191

*/

192

public void pin(String scriptName, String script);

193

194

/**

195

* Unpin previously pinned script

196

* @param scriptName Name of script to unpin

197

*/

198

public void unpin(String scriptName);

199

```

200

201

## CDP Domain Classes

202

203

### Runtime Domain

204

205

Direct access to CDP Runtime domain for low-level JavaScript operations.

206

207

```java { .api }

208

import org.openqa.selenium.devtools.v110.runtime.Runtime;

209

210

/**

211

* Enable runtime domain

212

*/

213

public static Command<Void> enable();

214

215

/**

216

* Disable runtime domain

217

*/

218

public static Command<Void> disable();

219

220

/**

221

* Add runtime binding

222

*/

223

public static Command<Void> addBinding(

224

String name,

225

Optional<ExecutionContextId> executionContextId,

226

Optional<String> executionContextName

227

);

228

229

/**

230

* Remove runtime binding

231

*/

232

public static Command<Void> removeBinding(String name);

233

234

/**

235

* Binding called event

236

*/

237

public static Event<BindingCalled> bindingCalled();

238

239

/**

240

* Evaluate JavaScript expression

241

*/

242

public static Command<EvaluateResponse> evaluate(

243

String expression,

244

Optional<String> objectGroup,

245

Optional<Boolean> includeCommandLineAPI,

246

Optional<Boolean> silent,

247

Optional<ExecutionContextId> contextId,

248

Optional<Boolean> returnByValue,

249

Optional<Boolean> generatePreview,

250

Optional<Boolean> userGesture,

251

Optional<Boolean> awaitPromise,

252

Optional<Boolean> throwOnSideEffect,

253

Optional<TimeDelta> timeout,

254

Optional<Boolean> disableBreaks,

255

Optional<Boolean> replMode,

256

Optional<Boolean> allowUnsafeEvalBlockedByCSP

257

);

258

```

259

260

### Page Domain

261

262

Direct access to CDP Page domain for page-level script operations.

263

264

```java { .api }

265

import org.openqa.selenium.devtools.v110.page.Page;

266

267

/**

268

* Enable page domain

269

*/

270

public static Command<Void> enable();

271

272

/**

273

* Disable page domain

274

*/

275

public static Command<Void> disable();

276

277

/**

278

* Add script to evaluate on new document

279

*/

280

public static Command<ScriptIdentifier> addScriptToEvaluateOnNewDocument(

281

String source,

282

Optional<String> worldName,

283

Optional<Boolean> includeCommandLineAPI

284

);

285

286

/**

287

* Remove script to evaluate on new document

288

*/

289

public static Command<Void> removeScriptToEvaluateOnNewDocument(ScriptIdentifier identifier);

290

```

291

292

## Model Classes

293

294

### Script and Binding Models

295

296

```java { .api }

297

import org.openqa.selenium.devtools.v110.page.model.*;

298

import org.openqa.selenium.devtools.v110.runtime.model.*;

299

300

/**

301

* Script identifier for page-level scripts

302

*/

303

public class ScriptIdentifier {

304

String toString();

305

}

306

307

/**

308

* Runtime binding called event

309

*/

310

public class BindingCalled {

311

/**

312

* Binding name that was called

313

*/

314

String getName();

315

316

/**

317

* Payload sent from JavaScript

318

*/

319

String getPayload();

320

321

/**

322

* Execution context where binding was called

323

*/

324

ExecutionContextId getExecutionContextId();

325

}

326

327

/**

328

* JavaScript evaluation response

329

*/

330

public class EvaluateResponse {

331

/**

332

* Evaluation result as remote object

333

*/

334

RemoteObject getResult();

335

336

/**

337

* Exception details if evaluation threw

338

*/

339

Optional<ExceptionDetails> getExceptionDetails();

340

}

341

342

/**

343

* JavaScript execution context identifier

344

*/

345

public class ExecutionContextId {

346

Integer getValue();

347

String toString();

348

}

349

```

350

351

### Runtime Object Models

352

353

```java { .api }

354

/**

355

* Remote object representing JavaScript values

356

*/

357

public class RemoteObject {

358

/**

359

* Object type (object, function, undefined, string, number, boolean, symbol, bigint)

360

*/

361

RemoteObjectType getType();

362

363

/**

364

* Object subtype for more specific type information

365

*/

366

Optional<RemoteObjectSubtype> getSubtype();

367

368

/**

369

* Primitive value (for strings, numbers, booleans)

370

*/

371

Optional<Object> getValue();

372

373

/**

374

* String description of the object

375

*/

376

Optional<String> getDescription();

377

378

/**

379

* Unique object identifier for further operations

380

*/

381

Optional<RemoteObjectId> getObjectId();

382

}

383

384

/**

385

* Exception details from JavaScript evaluation

386

*/

387

public class ExceptionDetails {

388

String getText();

389

Optional<String> getUrl();

390

Integer getLineNumber();

391

Integer getColumnNumber();

392

Optional<RemoteObject> getException();

393

}

394

```

395

396

## Advanced Usage Examples

397

398

### Bidirectional Communication

399

400

```java

401

v110Javascript javascript = new v110Javascript(devTools);

402

devTools.send(javascript.enableRuntime());

403

404

// Set up bidirectional communication

405

javascript.addJsBinding("sendToJava", payload -> {

406

System.out.println("Received from JavaScript: " + payload);

407

408

// Send response back to JavaScript

409

String response = processPayload(payload);

410

driver.executeScript("window.javaResponse = arguments[0];", response);

411

});

412

413

// Navigate and establish communication

414

driver.get("https://example.com");

415

416

// JavaScript can now call: sendToJava("some data")

417

// And receive responses via: window.javaResponse

418

```

419

420

### Script Injection for Testing

421

422

```java

423

// Enable page domain

424

devTools.send(javascript.enablePage());

425

426

// Inject testing utilities

427

String testingScript = """

428

window.testUtils = {

429

waitForElement: function(selector, timeout = 5000) {

430

return new Promise((resolve, reject) => {

431

const startTime = Date.now();

432

const check = () => {

433

const element = document.querySelector(selector);

434

if (element) {

435

resolve(element);

436

} else if (Date.now() - startTime > timeout) {

437

reject(new Error('Element not found: ' + selector));

438

} else {

439

setTimeout(check, 100);

440

}

441

};

442

check();

443

});

444

},

445

446

simulateEvent: function(element, eventType) {

447

const event = new Event(eventType, { bubbles: true });

448

element.dispatchEvent(event);

449

}

450

};

451

""";

452

453

ScriptIdentifier testUtilsScript = devTools.send(

454

javascript.addScriptToEvaluateOnNewDocument(testingScript)

455

);

456

457

// Now all pages will have testUtils available

458

```

459

460

### Runtime Evaluation

461

462

```java

463

import org.openqa.selenium.devtools.v110.runtime.Runtime;

464

import org.openqa.selenium.devtools.v110.runtime.model.EvaluateResponse;

465

466

// Enable runtime

467

devTools.send(Runtime.enable());

468

469

// Evaluate JavaScript expression

470

EvaluateResponse response = devTools.send(Runtime.evaluate(

471

"document.title + ' - ' + location.href",

472

Optional.empty(), // objectGroup

473

Optional.empty(), // includeCommandLineAPI

474

Optional.of(false), // silent

475

Optional.empty(), // contextId

476

Optional.of(true), // returnByValue

477

Optional.empty(), // generatePreview

478

Optional.empty(), // userGesture

479

Optional.empty(), // awaitPromise

480

Optional.empty(), // throwOnSideEffect

481

Optional.empty(), // timeout

482

Optional.empty(), // disableBreaks

483

Optional.empty(), // replMode

484

Optional.empty() // allowUnsafeEvalBlockedByCSP

485

));

486

487

if (response.getExceptionDetails().isPresent()) {

488

System.err.println("JavaScript error: " +

489

response.getExceptionDetails().get().getText());

490

} else {

491

Object result = response.getResult().getValue().orElse(null);

492

System.out.println("JavaScript result: " + result);

493

}

494

```

495

496

## Error Handling

497

498

JavaScript operations may encounter various error conditions:

499

500

```java

501

import org.openqa.selenium.devtools.DevToolsException;

502

import org.openqa.selenium.JavascriptException;

503

504

// Handle runtime enablement failures

505

try {

506

devTools.send(javascript.enableRuntime());

507

} catch (DevToolsException e) {

508

System.err.println("Failed to enable runtime: " + e.getMessage());

509

}

510

511

// Handle binding setup failures

512

try {

513

javascript.addJsBinding("myBinding", payload -> {

514

// Handle binding call

515

});

516

} catch (DevToolsException e) {

517

System.err.println("Failed to add binding: " + e.getMessage());

518

}

519

520

// Handle JavaScript evaluation errors

521

devTools.addListener(Runtime.evaluate("invalid.javascript.code",

522

Optional.empty(), Optional.empty(), Optional.of(false),

523

Optional.empty(), Optional.of(true), Optional.empty(),

524

Optional.empty(), Optional.empty(), Optional.empty(),

525

Optional.empty(), Optional.empty(), Optional.empty(),

526

Optional.empty()), response -> {

527

528

if (response.getExceptionDetails().isPresent()) {

529

ExceptionDetails details = response.getExceptionDetails().get();

530

System.err.printf("JavaScript Error at %s:%d - %s%n",

531

details.getUrl().orElse("unknown"),

532

details.getLineNumber(),

533

details.getText());

534

}

535

});

536

```