or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddom-apis.mdindex.mdjsdom-class.mdresources.mdtroubleshooting.mdvirtual-console.md
tile.json

dom-apis.mddocs/

0

# DOM APIs

1

2

The `window` object in jsdom provides a comprehensive browser-like environment with standard web APIs. This document covers the major DOM and browser APIs available through `dom.window`.

3

4

## Overview

5

6

Access the window object via the `window` property of a JSDOM instance:

7

8

```javascript

9

const { JSDOM } = require("jsdom");

10

11

const dom = new JSDOM(`<!DOCTYPE html><body><div id="app"></div></body>`);

12

const { window } = dom;

13

const { document } = window;

14

15

// Use standard DOM APIs

16

const app = document.getElementById("app");

17

app.innerHTML = "<h1>Hello, jsdom!</h1>";

18

```

19

20

## Major API Categories

21

22

### Core DOM APIs

23

24

Standard DOM manipulation interfaces matching browser behavior.

25

26

#### Document and Nodes

27

28

```javascript { .api }

29

/**

30

* Core DOM interfaces

31

*/

32

interface Window {

33

/** The Document interface */

34

document: Document;

35

36

/** DOM node types */

37

Node: typeof Node;

38

Element: typeof Element;

39

Document: typeof Document;

40

DocumentFragment: typeof DocumentFragment;

41

Text: typeof Text;

42

Comment: typeof Comment;

43

CDATASection: typeof CDATASection;

44

ProcessingInstruction: typeof ProcessingInstruction;

45

DocumentType: typeof DocumentType;

46

47

/** HTML element constructors */

48

HTMLElement: typeof HTMLElement;

49

HTMLDivElement: typeof HTMLDivElement;

50

HTMLSpanElement: typeof HTMLSpanElement;

51

HTMLParagraphElement: typeof HTMLParagraphElement;

52

HTMLAnchorElement: typeof HTMLAnchorElement;

53

HTMLImageElement: typeof HTMLImageElement;

54

HTMLFormElement: typeof HTMLFormElement;

55

HTMLInputElement: typeof HTMLInputElement;

56

HTMLButtonElement: typeof HTMLButtonElement;

57

HTMLSelectElement: typeof HTMLSelectElement;

58

HTMLTextAreaElement: typeof HTMLTextAreaElement;

59

HTMLScriptElement: typeof HTMLScriptElement;

60

HTMLLinkElement: typeof HTMLLinkElement;

61

HTMLStyleElement: typeof HTMLStyleElement;

62

HTMLIFrameElement: typeof HTMLIFrameElement;

63

HTMLCanvasElement: typeof HTMLCanvasElement;

64

// ... and many more HTML element types

65

}

66

```

67

68

**Usage:**

69

70

```javascript

71

const { document } = dom.window;

72

73

// Create elements

74

const div = document.createElement("div");

75

const text = document.createTextNode("Hello");

76

const comment = document.createComment("Comment");

77

const fragment = document.createDocumentFragment();

78

79

// Manipulate DOM

80

div.appendChild(text);

81

document.body.appendChild(div);

82

83

// Query DOM

84

const elements = document.querySelectorAll("div");

85

const element = document.getElementById("app");

86

const byClass = document.getElementsByClassName("container");

87

const byTag = document.getElementsByTagName("p");

88

```

89

90

#### Node Collections and Traversal

91

92

```javascript { .api }

93

/**

94

* Node collections and traversal interfaces

95

*/

96

interface Window {

97

/** Live collection of nodes */

98

NodeList: typeof NodeList;

99

100

/** Live collection of HTML elements */

101

HTMLCollection: typeof HTMLCollection;

102

103

/** Tree traversal interfaces */

104

NodeIterator: typeof NodeIterator;

105

TreeWalker: typeof TreeWalker;

106

107

/** Named node map for attributes */

108

NamedNodeMap: typeof NamedNodeMap;

109

}

110

```

111

112

**Usage:**

113

114

```javascript

115

const { document } = dom.window;

116

117

// Create tree walker

118

const walker = document.createTreeWalker(

119

document.body,

120

dom.window.NodeFilter.SHOW_ELEMENT

121

);

122

123

let node;

124

while (node = walker.nextNode()) {

125

console.log(node.nodeName);

126

}

127

128

// Create node iterator

129

const iterator = document.createNodeIterator(

130

document.body,

131

dom.window.NodeFilter.SHOW_TEXT

132

);

133

134

let textNode;

135

while (textNode = iterator.nextNode()) {

136

console.log(textNode.textContent);

137

}

138

```

139

140

#### Attributes and Ranges

141

142

```javascript { .api }

143

/**

144

* Attribute and range interfaces

145

*/

146

interface Window {

147

/** Attribute node */

148

Attr: typeof Attr;

149

150

/** Range interface for selections */

151

Range: typeof Range;

152

153

/** Selection interface */

154

Selection: typeof Selection;

155

}

156

```

157

158

**Usage:**

159

160

```javascript

161

const { document } = dom.window;

162

163

// Work with attributes

164

const div = document.createElement("div");

165

div.setAttribute("class", "container");

166

const attr = div.getAttributeNode("class");

167

console.log(attr.value); // "container"

168

169

// Work with ranges

170

const range = document.createRange();

171

range.selectNodeContents(document.body);

172

console.log(range.toString());

173

174

// Work with selection

175

const selection = dom.window.getSelection();

176

selection.addRange(range);

177

```

178

179

### Events

180

181

Complete event system with standard event types and propagation.

182

183

#### Event Constructors

184

185

```javascript { .api }

186

/**

187

* Event interfaces

188

*/

189

interface Window {

190

/** Base event classes */

191

EventTarget: typeof EventTarget;

192

Event: typeof Event;

193

CustomEvent: typeof CustomEvent;

194

195

/** UI events */

196

UIEvent: typeof UIEvent;

197

MouseEvent: typeof MouseEvent;

198

KeyboardEvent: typeof KeyboardEvent;

199

FocusEvent: typeof FocusEvent;

200

InputEvent: typeof InputEvent;

201

WheelEvent: typeof WheelEvent;

202

PointerEvent: typeof PointerEvent;

203

TouchEvent: typeof TouchEvent;

204

205

/** Form events */

206

SubmitEvent: typeof SubmitEvent;

207

208

/** Page events */

209

PopStateEvent: typeof PopStateEvent;

210

HashChangeEvent: typeof HashChangeEvent;

211

PageTransitionEvent: typeof PageTransitionEvent;

212

BeforeUnloadEvent: typeof BeforeUnloadEvent;

213

214

/** Other events */

215

ErrorEvent: typeof ErrorEvent;

216

MessageEvent: typeof MessageEvent;

217

ProgressEvent: typeof ProgressEvent;

218

StorageEvent: typeof StorageEvent;

219

PromiseRejectionEvent: typeof PromiseRejectionEvent;

220

}

221

```

222

223

**Usage:**

224

225

```javascript

226

const { document } = dom.window;

227

228

// Add event listeners

229

const button = document.createElement("button");

230

button.textContent = "Click me";

231

232

button.addEventListener("click", (event) => {

233

console.log("Button clicked!", event.type);

234

});

235

236

// Dispatch events

237

const event = new dom.window.MouseEvent("click", {

238

bubbles: true,

239

cancelable: true

240

});

241

button.dispatchEvent(event);

242

243

// Custom events

244

const customEvent = new dom.window.CustomEvent("myevent", {

245

detail: { data: "custom data" }

246

});

247

document.dispatchEvent(customEvent);

248

249

document.addEventListener("myevent", (e) => {

250

console.log(e.detail.data); // "custom data"

251

});

252

```

253

254

### Window and Navigation

255

256

Browser window properties and navigation interfaces.

257

258

#### Location and History

259

260

```javascript { .api }

261

/**

262

* Navigation interfaces

263

*/

264

interface Window {

265

/** Current location */

266

location: Location;

267

268

/** Session history */

269

history: History;

270

271

/** Navigator information */

272

navigator: Navigator;

273

274

/** Screen information */

275

screen: Screen;

276

277

/** Window properties */

278

top: Window;

279

parent: Window;

280

self: Window;

281

window: Window;

282

}

283

```

284

285

**Usage:**

286

287

```javascript

288

const { window } = dom;

289

290

// Location properties

291

console.log(window.location.href);

292

console.log(window.location.hostname);

293

console.log(window.location.pathname);

294

console.log(window.location.search);

295

console.log(window.location.hash);

296

297

// History methods

298

window.history.pushState({ page: 1 }, "Title", "/page1");

299

window.history.replaceState({ page: 2 }, "Title", "/page2");

300

window.history.back();

301

window.history.forward();

302

303

// Navigator

304

console.log(window.navigator.userAgent);

305

console.log(window.navigator.platform);

306

307

// Screen

308

console.log(window.screen.width);

309

console.log(window.screen.height);

310

```

311

312

**Note:** jsdom has limited navigation support - assigning to `window.location.href` does not navigate. Use `dom.reconfigure({ url })` or create new JSDOM instances for navigation.

313

314

### Timers and Animation

315

316

Asynchronous execution and animation frame APIs.

317

318

```javascript { .api }

319

/**

320

* Timer and animation functions

321

*/

322

interface Window {

323

/** Schedule code execution */

324

setTimeout(callback: Function, delay?: number, ...args: any[]): number;

325

clearTimeout(id: number): void;

326

327

setInterval(callback: Function, delay?: number, ...args: any[]): number;

328

clearInterval(id: number): void;

329

330

setImmediate(callback: Function, ...args: any[]): number;

331

clearImmediate(id: number): void;

332

333

/** Animation frames (requires pretendToBeVisual: true) */

334

requestAnimationFrame?(callback: (timestamp: number) => void): number;

335

cancelAnimationFrame?(id: number): void;

336

}

337

```

338

339

**Usage:**

340

341

```javascript

342

const { window } = dom;

343

344

// Timers

345

const timeoutId = window.setTimeout(() => {

346

console.log("Timeout executed");

347

}, 100);

348

349

const intervalId = window.setInterval(() => {

350

console.log("Interval tick");

351

}, 500);

352

353

// Clear timers

354

window.clearTimeout(timeoutId);

355

window.clearInterval(intervalId);

356

357

// Immediate execution

358

window.setImmediate(() => {

359

console.log("Immediate executed");

360

});

361

362

// Animation frames (with pretendToBeVisual)

363

const dom2 = new JSDOM(``, { pretendToBeVisual: true });

364

dom2.window.requestAnimationFrame((timestamp) => {

365

console.log("Animation frame:", timestamp);

366

});

367

368

// Shut down jsdom

369

window.close(); // Terminates all timers

370

```

371

372

### Web Storage

373

374

localStorage and sessionStorage APIs.

375

376

```javascript { .api }

377

/**

378

* Web Storage interfaces

379

*/

380

interface Window {

381

/** Persistent local storage */

382

localStorage: Storage;

383

384

/** Session storage */

385

sessionStorage: Storage;

386

}

387

388

interface Storage {

389

readonly length: number;

390

getItem(key: string): string | null;

391

setItem(key: string, value: string): void;

392

removeItem(key: string): void;

393

clear(): void;

394

key(index: number): string | null;

395

}

396

```

397

398

**Usage:**

399

400

```javascript

401

const { window } = dom;

402

403

// localStorage

404

window.localStorage.setItem("username", "alice");

405

window.localStorage.setItem("theme", "dark");

406

407

console.log(window.localStorage.getItem("username")); // "alice"

408

console.log(window.localStorage.length); // 2

409

410

window.localStorage.removeItem("theme");

411

window.localStorage.clear();

412

413

// sessionStorage

414

window.sessionStorage.setItem("token", "abc123");

415

console.log(window.sessionStorage.getItem("token")); // "abc123"

416

417

// Storage events

418

window.addEventListener("storage", (event) => {

419

console.log("Storage changed:", event.key, event.newValue);

420

});

421

```

422

423

### Parsing and Serialization

424

425

HTML/XML parsing and serialization interfaces.

426

427

```javascript { .api }

428

/**

429

* Parsing and serialization interfaces

430

*/

431

interface Window {

432

/** Parse HTML/XML strings */

433

DOMParser: typeof DOMParser;

434

435

/** Serialize DOM to XML */

436

XMLSerializer: typeof XMLSerializer;

437

}

438

```

439

440

**Usage:**

441

442

```javascript

443

const { window } = dom;

444

445

// Parse HTML

446

const parser = new window.DOMParser();

447

const doc = parser.parseFromString("<p>Hello</p>", "text/html");

448

console.log(doc.querySelector("p").textContent); // "Hello"

449

450

// Parse XML

451

const xmlDoc = parser.parseFromString("<root><item/></root>", "application/xml");

452

console.log(xmlDoc.documentElement.nodeName); // "root"

453

454

// Serialize to XML

455

const serializer = new window.XMLSerializer();

456

const xmlString = serializer.serializeToString(doc.documentElement);

457

console.log(xmlString); // "<html>...</html>"

458

```

459

460

### File and Binary APIs

461

462

File, Blob, and FileReader interfaces.

463

464

```javascript { .api }

465

/**

466

* File and binary data interfaces

467

*/

468

interface Window {

469

/** Binary data container */

470

Blob: typeof Blob;

471

472

/** File representation */

473

File: typeof File;

474

475

/** List of files */

476

FileList: typeof FileList;

477

478

/** Read file contents */

479

FileReader: typeof FileReader;

480

}

481

```

482

483

**Usage:**

484

485

```javascript

486

const { window } = dom;

487

488

// Create Blob

489

const blob = new window.Blob(["Hello, world!"], { type: "text/plain" });

490

console.log(blob.size); // 13

491

console.log(blob.type); // "text/plain"

492

493

// Create File

494

const file = new window.File(["content"], "test.txt", {

495

type: "text/plain",

496

lastModified: Date.now()

497

});

498

console.log(file.name); // "test.txt"

499

500

// Read file

501

const reader = new window.FileReader();

502

reader.onload = (event) => {

503

console.log("File contents:", event.target.result);

504

};

505

reader.readAsText(blob);

506

```

507

508

### Network APIs

509

510

WebSocket and basic network interfaces.

511

512

```javascript { .api }

513

/**

514

* Network interfaces

515

*/

516

interface Window {

517

/** WebSocket connection */

518

WebSocket: typeof WebSocket;

519

520

/** Fetch API headers */

521

Headers: typeof Headers;

522

523

/** Abort controller for requests */

524

AbortController: typeof AbortController;

525

AbortSignal: typeof AbortSignal;

526

}

527

```

528

529

**Usage:**

530

531

```javascript

532

const { window } = dom;

533

534

// WebSocket

535

const ws = new window.WebSocket("wss://example.com/socket");

536

537

ws.onopen = () => {

538

console.log("WebSocket connected");

539

ws.send("Hello server");

540

};

541

542

ws.onmessage = (event) => {

543

console.log("Received:", event.data);

544

};

545

546

ws.onerror = (error) => {

547

console.error("WebSocket error:", error);

548

};

549

550

ws.close();

551

552

// Headers

553

const headers = new window.Headers();

554

headers.append("Content-Type", "application/json");

555

headers.append("Authorization", "Bearer token");

556

557

console.log(headers.get("Content-Type")); // "application/json"

558

559

// AbortController

560

const controller = new window.AbortController();

561

const signal = controller.signal;

562

563

// Use signal with APIs that support it

564

// controller.abort(); // Cancel operation

565

```

566

567

### Custom Elements

568

569

Custom elements and shadow DOM APIs.

570

571

```javascript { .api }

572

/**

573

* Custom elements interfaces

574

*/

575

interface Window {

576

/** Custom elements registry */

577

customElements: CustomElementRegistry;

578

579

/** Element internals */

580

ElementInternals: typeof ElementInternals;

581

}

582

```

583

584

**Usage:**

585

586

```javascript

587

const { window } = dom;

588

589

// Define custom element

590

class MyElement extends window.HTMLElement {

591

constructor() {

592

super();

593

this.attachShadow({ mode: "open" });

594

}

595

596

connectedCallback() {

597

this.shadowRoot.innerHTML = "<p>Custom element content</p>";

598

}

599

}

600

601

// Register custom element

602

window.customElements.define("my-element", MyElement);

603

604

// Use custom element

605

const custom = dom.window.document.createElement("my-element");

606

dom.window.document.body.appendChild(custom);

607

```

608

609

### Console

610

611

Console API connected to VirtualConsole.

612

613

```javascript { .api }

614

/**

615

* Console interface

616

*/

617

interface Window {

618

console: Console;

619

}

620

621

interface Console {

622

log(...args: any[]): void;

623

error(...args: any[]): void;

624

warn(...args: any[]): void;

625

info(...args: any[]): void;

626

debug(...args: any[]): void;

627

trace(...args: any[]): void;

628

assert(condition: boolean, ...args: any[]): void;

629

clear(): void;

630

count(label?: string): void;

631

countReset(label?: string): void;

632

dir(obj: any, options?: object): void;

633

dirxml(...args: any[]): void;

634

group(...args: any[]): void;

635

groupCollapsed(...args: any[]): void;

636

groupEnd(): void;

637

table(data: any): void;

638

time(label?: string): void;

639

timeLog(label?: string, ...args: any[]): void;

640

timeEnd(label?: string): void;

641

}

642

```

643

644

**Usage:**

645

646

```javascript

647

const { window } = dom;

648

649

// Console methods

650

window.console.log("Log message");

651

window.console.error("Error message");

652

window.console.warn("Warning message");

653

window.console.info("Info message");

654

655

window.console.time("operation");

656

// ... do something ...

657

window.console.timeEnd("operation");

658

659

window.console.group("Group");

660

window.console.log("Inside group");

661

window.console.groupEnd();

662

663

window.console.table([

664

{ name: "Alice", age: 30 },

665

{ name: "Bob", age: 25 }

666

]);

667

```

668

669

### Other Web APIs

670

671

Additional web platform APIs.

672

673

```javascript { .api }

674

/**

675

* Additional web APIs

676

*/

677

interface Window {

678

/** URL manipulation */

679

URL: typeof URL;

680

URLSearchParams: typeof URLSearchParams;

681

682

/** Text encoding */

683

TextEncoder: typeof TextEncoder;

684

TextDecoder: typeof TextDecoder;

685

686

/** Crypto API */

687

crypto: Crypto;

688

689

/** DOMException */

690

DOMException: typeof DOMException;

691

692

/** Form data */

693

FormData: typeof FormData;

694

}

695

```

696

697

**Usage:**

698

699

```javascript

700

const { window } = dom;

701

702

// URL

703

const url = new window.URL("https://example.com/path?query=value#hash");

704

console.log(url.hostname); // "example.com"

705

console.log(url.searchParams.get("query")); // "value"

706

707

// URLSearchParams

708

const params = new window.URLSearchParams("foo=bar&baz=qux");

709

console.log(params.get("foo")); // "bar"

710

params.append("new", "value");

711

712

// TextEncoder/Decoder

713

const encoder = new window.TextEncoder();

714

const bytes = encoder.encode("Hello");

715

console.log(bytes); // Uint8Array

716

717

const decoder = new window.TextDecoder();

718

const text = decoder.decode(bytes);

719

console.log(text); // "Hello"

720

721

// Crypto

722

const randomValues = new Uint8Array(16);

723

window.crypto.getRandomValues(randomValues);

724

console.log(randomValues);

725

726

// FormData

727

const form = window.document.createElement("form");

728

const formData = new window.FormData(form);

729

formData.append("username", "alice");

730

formData.append("email", "alice@example.com");

731

```

732

733

## Canvas Support

734

735

jsdom supports the Canvas API via the optional `canvas` peer dependency.

736

737

To enable canvas support:

738

739

```bash

740

npm install canvas

741

```

742

743

Once installed, `<canvas>` elements have the full Canvas API:

744

745

```javascript

746

const { JSDOM } = require("jsdom");

747

748

const dom = new JSDOM(`<!DOCTYPE html><canvas id="canvas"></canvas>`);

749

const canvas = dom.window.document.getElementById("canvas");

750

751

// If canvas package is installed

752

if (canvas.getContext) {

753

const ctx = canvas.getContext("2d");

754

ctx.fillStyle = "red";

755

ctx.fillRect(10, 10, 100, 100);

756

757

// Export to buffer

758

canvas.toBuffer((err, buffer) => {

759

// PNG buffer

760

});

761

}

762

```

763

764

## Limitations

765

766

### No Layout Calculation

767

768

jsdom does not implement layout or rendering. Layout-related properties return placeholder values:

769

770

- `getBoundingClientRect()` returns zeros

771

- `offsetWidth`, `offsetHeight`, `offsetTop`, etc. return 0

772

- `clientWidth`, `clientHeight` return 0

773

- `getComputedStyle()` returns default values

774

775

**Workaround:** Mock layout values with `Object.defineProperty()`:

776

777

```javascript

778

Object.defineProperty(element, "offsetWidth", {

779

get: () => 100

780

});

781

```

782

783

### No Navigation

784

785

Assigning to `window.location.href` does not navigate or create new documents.

786

787

**Workaround:** Create new JSDOM instances for each page:

788

789

```javascript

790

async function navigate(url) {

791

const dom = await JSDOM.fromURL(url);

792

return dom;

793

}

794

```

795

796

## Complete Example

797

798

```javascript

799

const { JSDOM } = require("jsdom");

800

801

const dom = new JSDOM(`

802

<!DOCTYPE html>

803

<html>

804

<head><title>Test Page</title></head>

805

<body>

806

<div id="app">

807

<h1>Welcome</h1>

808

<button id="btn">Click Me</button>

809

<ul id="list"></ul>

810

</div>

811

</body>

812

</html>

813

`, {

814

url: "https://example.com/",

815

referrer: "https://google.com/",

816

runScripts: "outside-only",

817

pretendToBeVisual: true

818

});

819

820

const { window } = dom;

821

const { document } = window;

822

823

// DOM manipulation

824

const button = document.getElementById("btn");

825

const list = document.getElementById("list");

826

827

// Event handling

828

button.addEventListener("click", () => {

829

console.log("Button clicked!");

830

831

const item = document.createElement("li");

832

item.textContent = `Item ${list.children.length + 1}`;

833

list.appendChild(item);

834

});

835

836

// Trigger event

837

button.click();

838

839

// Storage

840

window.localStorage.setItem("visited", "true");

841

842

// Timers

843

window.setTimeout(() => {

844

console.log("Timer executed");

845

}, 100);

846

847

// Serialize result

848

console.log(dom.serialize());

849

850

// Clean up

851

window.close();

852

```

853