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

jsdom-class.mddocs/

0

# JSDOM Class

1

2

The JSDOM class is the main interface for creating and managing jsdom instances. It provides methods for document serialization, node location tracking, VM context access, and runtime reconfiguration.

3

4

## Capabilities

5

6

### Constructor

7

8

Creates a new jsdom instance from HTML string or binary data.

9

10

```javascript { .api }

11

/**

12

* Create a new jsdom instance

13

* @param input - HTML content as string or binary data for encoding sniffing

14

* @param options - Configuration options

15

*/

16

constructor(input?: string | Buffer | ArrayBuffer | TypedArray, options?: JSDOMOptions)

17

```

18

19

**Parameters:**

20

21

- **`input`** (optional): HTML content to parse

22

- `string`: HTML string (most common)

23

- `Buffer`: Node.js Buffer for encoding sniffing

24

- `ArrayBuffer`: Standard JavaScript binary data

25

- `TypedArray`: Uint8Array, DataView, etc.

26

- Default: `""` (empty document)

27

28

- **`options`** (optional): Configuration object (see [Configuration](./configuration.md))

29

30

**Usage Examples:**

31

32

```javascript

33

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

34

35

// From HTML string

36

const dom = new JSDOM(`<!DOCTYPE html><p>Hello</p>`);

37

38

// Empty document

39

const emptyDom = new JSDOM();

40

41

// From binary data (encoding sniffing)

42

const buffer = Buffer.from(htmlBytes);

43

const domFromBuffer = new JSDOM(buffer);

44

45

// With options

46

const configuredDom = new JSDOM(`<!DOCTYPE html><p>Hello</p>`, {

47

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

48

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

49

contentType: "text/html",

50

runScripts: "dangerously"

51

});

52

```

53

54

### Instance Properties

55

56

Properties available on JSDOM instances.

57

58

#### window

59

60

```javascript { .api }

61

/**

62

* The Window object containing the DOM and browser APIs

63

*/

64

readonly window: Window

65

```

66

67

Returns the global window object (actually the global proxy for proper JavaScript behavior). This provides access to `document`, `navigator`, and all browser APIs.

68

69

**Usage Examples:**

70

71

```javascript

72

const dom = new JSDOM(`<p>Hello</p>`);

73

74

// Access window

75

const { window } = dom;

76

77

// Use window APIs

78

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

79

console.log(window.location.href); // "about:blank"

80

81

// Or destructure what you need

82

const { document } = dom.window;

83

```

84

85

#### virtualConsole

86

87

```javascript { .api }

88

/**

89

* The VirtualConsole instance for this jsdom

90

*/

91

readonly virtualConsole: VirtualConsole

92

```

93

94

Returns the VirtualConsole used by this jsdom. This is either the one you provided in options or the default one created automatically.

95

96

**Usage Examples:**

97

98

```javascript

99

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

100

101

const dom = new JSDOM(`<!DOCTYPE html>`);

102

103

// Access the virtual console

104

dom.virtualConsole.on("log", (message) => {

105

console.log("Page logged:", message);

106

});

107

```

108

109

#### cookieJar

110

111

```javascript { .api }

112

/**

113

* The CookieJar instance for this jsdom

114

*/

115

readonly cookieJar: CookieJar

116

```

117

118

Returns the CookieJar used by this jsdom for cookie storage. This is either the one you provided in options or the default one created automatically.

119

120

**Usage Examples:**

121

122

```javascript

123

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

124

125

const dom = new JSDOM(`<!DOCTYPE html>`, {

126

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

127

});

128

129

// Access the cookie jar

130

const cookies = dom.cookieJar.getCookiesSync("https://example.com/");

131

console.log(cookies);

132

```

133

134

### Instance Methods

135

136

Methods available on JSDOM instances.

137

138

#### serialize()

139

140

```javascript { .api }

141

/**

142

* Serialize the document to an HTML string including DOCTYPE

143

* @returns Complete HTML string with DOCTYPE

144

*/

145

serialize(): string

146

```

147

148

Returns the HTML serialization of the entire document, including the DOCTYPE declaration.

149

150

**Usage Examples:**

151

152

```javascript

153

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

154

155

const dom = new JSDOM(`<!DOCTYPE html>hello`);

156

console.log(dom.serialize());

157

// "<!DOCTYPE html><html><head></head><body>hello</body></html>"

158

159

// After modifying the DOM

160

const dom2 = new JSDOM(`<p>test</p>`);

161

dom2.window.document.querySelector("p").textContent = "modified";

162

console.log(dom2.serialize());

163

// "<html><head></head><body><p>modified</p></body></html>"

164

```

165

166

**Note:** This differs from `document.documentElement.outerHTML` which doesn't include the DOCTYPE.

167

168

#### nodeLocation()

169

170

```javascript { .api }

171

/**

172

* Get the source code location of a DOM node

173

* @param node - DOM node to get location for

174

* @returns Location info with line, column, and offset information, or undefined for dynamically created nodes

175

* @throws Error if includeNodeLocations option was not set to true

176

*/

177

nodeLocation(node: Node): LocationInfo | undefined

178

```

179

180

Returns the parse5 location info for where a node appears in the original HTML source. Only works if `includeNodeLocations: true` was set during construction.

181

182

**Returns:**

183

184

- `LocationInfo` object for nodes from original source

185

- `undefined` for nodes created via `innerHTML`, `outerHTML`, or `createContextualFragment()`

186

187

**Throws:**

188

189

- `Error` if `includeNodeLocations` was not set to `true`

190

191

**Usage Examples:**

192

193

```javascript

194

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

195

196

const dom = new JSDOM(`<p>Hello

197

<img src="foo.jpg">

198

</p>`, { includeNodeLocations: true });

199

200

const document = dom.window.document;

201

const pEl = document.querySelector("p");

202

const imgEl = document.querySelector("img");

203

204

console.log(dom.nodeLocation(pEl));

205

// { startOffset: 0, endOffset: 39, startLine: 1, endLine: 2,

206

// startCol: 1, endCol: 7, startTag: {...}, endTag: {...} }

207

208

console.log(dom.nodeLocation(imgEl));

209

// { startOffset: 13, endOffset: 32, ... }

210

211

// Dynamically created nodes return undefined

212

pEl.innerHTML = `<div>new</div>`;

213

const divEl = document.querySelector("div");

214

console.log(dom.nodeLocation(divEl)); // undefined

215

```

216

217

**LocationInfo Structure:**

218

219

```javascript

220

{

221

startOffset: number, // Character offset in source

222

endOffset: number,

223

startLine: number, // 1-indexed line number

224

endLine: number,

225

startCol: number, // 1-indexed column number

226

endCol: number,

227

startTag: { // For elements only

228

startOffset: number,

229

endOffset: number,

230

startLine: number,

231

endLine: number,

232

startCol: number,

233

endCol: number,

234

attrs: { // Attribute locations

235

attrName: { startOffset, endOffset, startLine, endLine, startCol, endCol }

236

}

237

},

238

endTag: { ... }, // For elements with closing tags

239

attrs: { ... } // Same as startTag.attrs

240

}

241

```

242

243

#### getInternalVMContext()

244

245

```javascript { .api }

246

/**

247

* Get the Node.js VM context for advanced script execution

248

* @returns Contextified global object for use with Node.js vm module

249

* @throws TypeError if runScripts option was not set

250

*/

251

getInternalVMContext(): object

252

```

253

254

Returns the internal VM context for use with Node.js's `vm` module. Enables advanced use cases like pre-compiling scripts and running them multiple times.

255

256

**Throws:**

257

258

- `TypeError` if `runScripts` option was not set to `"dangerously"` or `"outside-only"`

259

260

**Usage Examples:**

261

262

```javascript

263

const { Script } = require("vm");

264

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

265

266

const dom = new JSDOM(``, { runScripts: "outside-only" });

267

268

// Pre-compile a script

269

const script = new Script(`

270

if (!this.ran) {

271

this.ran = 0;

272

}

273

++this.ran;

274

`);

275

276

// Run it multiple times

277

const vmContext = dom.getInternalVMContext();

278

script.runInContext(vmContext);

279

script.runInContext(vmContext);

280

script.runInContext(vmContext);

281

282

console.log(dom.window.ran); // 3

283

284

// With timeout

285

const infiniteScript = new Script(`while(true) {}`);

286

try {

287

infiniteScript.runInContext(vmContext, { timeout: 50 });

288

} catch (e) {

289

console.error("Script timed out");

290

}

291

```

292

293

#### reconfigure()

294

295

```javascript { .api }

296

/**

297

* Reconfigure the jsdom after creation

298

* @param settings - Settings to change

299

* @param settings.windowTop - Override window.top (normally unforgeable)

300

* @param settings.url - Change the document URL

301

* @throws TypeError if url is invalid

302

*/

303

reconfigure(settings: { windowTop?: any, url?: string }): void

304

```

305

306

Modifies jsdom configuration after creation. Allows changing the normally-unforgeable `window.top` property and updating the document URL.

307

308

**Parameters:**

309

310

- **`settings.windowTop`** (optional): Override `window.top`. Useful for testing scenarios with iframes.

311

- **`settings.url`** (optional): Change the document URL. Must be a valid absolute URL. Updates `window.location`, `document.URL`, `document.documentURI`, base URL resolution, and same-origin checks. Does **not** navigate or fetch new content.

312

313

**Throws:**

314

315

- `TypeError` if `url` is not a valid absolute URL

316

317

**Usage Examples:**

318

319

```javascript

320

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

321

322

const dom = new JSDOM(`<img src="foo.jpg">`, {

323

url: "http://example.com/"

324

});

325

326

console.log(dom.window.location.href); // "http://example.com/"

327

console.log(dom.window.document.querySelector("img").src);

328

// "http://example.com/foo.jpg"

329

330

// Change URL

331

dom.reconfigure({ url: "http://localhost/bar/index.html" });

332

333

console.log(dom.window.location.href); // "http://localhost/bar/index.html"

334

console.log(dom.window.document.querySelector("img").src);

335

// "http://localhost/bar/foo.jpg" (relative URL re-resolved)

336

337

// Override window.top

338

const fakeTop = { is: "top" };

339

dom.reconfigure({ windowTop: fakeTop });

340

console.log(dom.window.top); // { is: "top" }

341

342

// Can set to undefined

343

dom.reconfigure({ windowTop: undefined });

344

console.log(dom.window.top); // undefined

345

```

346

347

### Static Methods

348

349

Static methods on the JSDOM class for convenient instance creation.

350

351

#### JSDOM.fromURL()

352

353

```javascript { .api }

354

/**

355

* Create jsdom by fetching from a URL

356

* @param url - URL to fetch (HTTP/HTTPS)

357

* @param options - Configuration options (url and contentType not allowed)

358

* @returns Promise resolving to JSDOM instance

359

*/

360

static fromURL(url: string, options?: JSDOMOptions): Promise<JSDOM>

361

```

362

363

Factory method that fetches HTML from a URL and creates a jsdom instance. The URL is fetched via HTTP/HTTPS with automatic redirect following.

364

365

**Parameters:**

366

367

- **`url`**: HTTP or HTTPS URL to fetch

368

- **`options`** (optional): Same as constructor options with restrictions:

369

- Cannot include `url` (determined from response URL)

370

- Cannot include `contentType` (determined from Content-Type header)

371

- `referrer` used as HTTP Referer header

372

- `resources` affects initial request (e.g., proxy configuration)

373

- `cookieJar` used for HTTP cookies (sent and received)

374

375

**Returns:** Promise resolving to JSDOM instance

376

377

**Behavior:**

378

379

- Follows HTTP redirects automatically

380

- URL fragment (#hash) preserved from original URL

381

- Content-Type header determines `contentType`

382

- Final URL (after redirects) used as document URL

383

- HTTP cookies handled via `cookieJar` option

384

385

**Usage Examples:**

386

387

```javascript

388

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

389

390

// Simple fetch

391

JSDOM.fromURL("https://example.com/").then(dom => {

392

console.log(dom.serialize());

393

});

394

395

// With options

396

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

397

const cookieJar = new CookieJar();

398

399

JSDOM.fromURL("https://example.com/page.html", {

400

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

401

cookieJar: cookieJar,

402

resources: "usable",

403

runScripts: "dangerously"

404

}).then(dom => {

405

console.log(dom.window.document.title);

406

console.log("Cookies:", cookieJar.getCookiesSync("https://example.com/"));

407

});

408

409

// Error handling

410

JSDOM.fromURL("https://example.com/").catch(error => {

411

console.error("Failed to load:", error.message);

412

});

413

```

414

415

#### JSDOM.fromFile()

416

417

```javascript { .api }

418

/**

419

* Create jsdom by reading from a file

420

* @param filename - File path relative to current working directory

421

* @param options - Configuration options

422

* @returns Promise resolving to JSDOM instance

423

*/

424

static fromFile(filename: string, options?: JSDOMOptions): Promise<JSDOM>

425

```

426

427

Factory method that reads HTML from a file and creates a jsdom instance.

428

429

**Parameters:**

430

431

- **`filename`**: File path (relative to current working directory or absolute)

432

- **`options`** (optional): Same as constructor options with defaults:

433

- `url` defaults to `file://` URL for the file

434

- `contentType` defaults to `"application/xhtml+xml"` for `.xhtml`, `.xht`, `.xml` extensions

435

436

**Returns:** Promise resolving to JSDOM instance

437

438

**Usage Examples:**

439

440

```javascript

441

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

442

443

// Read from file

444

JSDOM.fromFile("./test.html").then(dom => {

445

console.log(dom.serialize());

446

});

447

448

// With options

449

JSDOM.fromFile("./page.html", {

450

url: "https://example.com/", // Override default file:// URL

451

contentType: "text/html",

452

runScripts: "dangerously"

453

}).then(dom => {

454

console.log(dom.window.document.title);

455

});

456

457

// Using async/await

458

async function loadPage() {

459

const dom = await JSDOM.fromFile("./index.html");

460

return dom.window.document.querySelector("h1").textContent;

461

}

462

```

463

464

#### JSDOM.fragment()

465

466

```javascript { .api }

467

/**

468

* Create a DocumentFragment from HTML string (lightweight, no full document)

469

* @param string - HTML string to parse

470

* @returns DocumentFragment with parsed content

471

*/

472

static fragment(string?: string): DocumentFragment

473

```

474

475

Factory method for parsing HTML into a DocumentFragment without creating a full jsdom instance. This is lightweight and efficient for simple parsing needs.

476

477

**Parameters:**

478

479

- **`string`** (optional): HTML string to parse. Default: `""`

480

481

**Returns:** DocumentFragment instance

482

483

**Characteristics:**

484

485

- No full document or window object created

486

- Parses as if inside `<template>` element (allows any element type including `<td>`, `<tr>`, etc.)

487

- Resulting fragment has no browsing context (`ownerDocument.defaultView === null`)

488

- All invocations share the same template owner document (very efficient)

489

- No customization options available

490

491

**Usage Examples:**

492

493

```javascript

494

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

495

496

// Parse HTML fragment

497

const frag = JSDOM.fragment(`<p>Hello</p><p><strong>Hi!</strong></p>`);

498

499

console.log(frag.childNodes.length); // 2

500

console.log(frag.querySelector("strong").textContent); // "Hi!"

501

502

// Parse table elements (requires template context)

503

const tableFrag = JSDOM.fragment(`<tr><td>Cell</td></tr>`);

504

console.log(tableFrag.firstChild.nodeName); // "TR"

505

506

// Serialize single element fragment

507

const singleFrag = JSDOM.fragment(`<p>Hello</p>`);

508

console.log(singleFrag.firstChild.outerHTML); // "<p>Hello</p>"

509

510

// Use with actual DOM

511

const frag2 = JSDOM.fragment(`<li>Item 1</li><li>Item 2</li>`);

512

const dom = new JSDOM(`<ul id="list"></ul>`);

513

dom.window.document.getElementById("list").appendChild(frag2);

514

console.log(dom.serialize());

515

// Contains: <ul id="list"><li>Item 1</li><li>Item 2</li></ul>

516

```

517

518

## Types

519

520

```javascript { .api }

521

interface JSDOMOptions {

522

url?: string;

523

referrer?: string;

524

contentType?: string;

525

includeNodeLocations?: boolean;

526

storageQuota?: number;

527

runScripts?: "dangerously" | "outside-only";

528

resources?: "usable" | ResourceLoader;

529

pretendToBeVisual?: boolean;

530

virtualConsole?: VirtualConsole;

531

cookieJar?: CookieJar;

532

beforeParse?: (window: Window) => void;

533

}

534

535

interface LocationInfo {

536

startOffset: number;

537

endOffset: number;

538

startLine: number;

539

endLine: number;

540

startCol: number;

541

endCol: number;

542

startTag?: TagLocationInfo;

543

endTag?: TagLocationInfo;

544

attrs?: Record<string, AttrLocationInfo>;

545

}

546

547

interface TagLocationInfo {

548

startOffset: number;

549

endOffset: number;

550

startLine: number;

551

endLine: number;

552

startCol: number;

553

endCol: number;

554

attrs?: Record<string, AttrLocationInfo>;

555

}

556

557

interface AttrLocationInfo {

558

startOffset: number;

559

endOffset: number;

560

startLine: number;

561

endLine: number;

562

startCol: number;

563

endCol: number;

564

}

565

```

566