or run

npx @tessl/cli init
Log in

Version

Files

docs

api

cookie-management.mdjsdom-constructor.mdresource-loading.mdvirtual-console.mdwindow-dom-apis.md
index.md
tile.json

common-patterns.mddocs/guides/

Common Patterns

Practical examples for everyday jsdom tasks.

Basic DOM Manipulation

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><body></body>`);
const { document } = dom.window;

// Create and manipulate elements
const div = document.createElement("div");
div.id = "main";
div.className = "container";
div.textContent = "Hello World";
document.body.appendChild(div);

// Query elements
const main = document.getElementById("main");
const allDivs = document.querySelectorAll("div");

Working with Events

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><body><button id="btn">Click</button></body>`);
const { document, MouseEvent } = dom.window;

const button = document.getElementById("btn");
button.addEventListener("click", (event) => {
  console.log("Button clicked!");
});

// Dispatch event programmatically
const clickEvent = new MouseEvent("click", {
  bubbles: true,
  cancelable: true,
  view: dom.window
});
button.dispatchEvent(clickEvent);

Loading from URL

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

async function scrapePage() {
  const dom = await JSDOM.fromURL("https://example.com/", {
    resources: "usable",
    runScripts: "dangerously"
  });
  
  const title = dom.window.document.title;
  const paragraphs = Array.from(
    dom.window.document.querySelectorAll("p")
  ).map(p => p.textContent);
  
  return { title, paragraphs };
}

Custom Resource Loading

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

class CustomResourceLoader extends ResourceLoader {
  fetch(url, options) {
    // Override specific URLs
    if (url === "https://example.com/config.js") {
      return Promise.resolve(Buffer.from(`window.CONFIG = { apiUrl: "test" };`));
    }
    // Block certain resources
    if (url.includes("analytics")) {
      return Promise.resolve(null);
    }
    // Use default for others
    return super.fetch(url, options);
  }
}

const dom = new JSDOM(html, {
  resources: new CustomResourceLoader(),
  runScripts: "dangerously"
});

Working with Forms

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html>
  <body>
    <form id="myForm" action="/submit" method="post">
      <input type="text" name="username" value="john">
      <input type="password" name="password">
      <button type="submit">Submit</button>
    </form>
  </body>
`);

const { document } = dom.window;

// Access form
const form = document.getElementById("myForm");
console.log(form.action); // "/submit"
console.log(form.method); // "post"

// Access form controls
const username = form.elements.namedItem("username");
console.log(username.value); // "john"
username.value = "jane";

// Form manipulation
form.reset();
console.log(username.value); // "" (reset clears value)

Using Storage APIs

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><html></html>`, {
  url: "https://example.org/"
});

const { window } = dom;

// Use localStorage
window.localStorage.setItem("username", "john");
window.localStorage.setItem("theme", "dark");

console.log(window.localStorage.getItem("username")); // "john"
console.log(window.localStorage.length); // 2

// Use sessionStorage
window.sessionStorage.setItem("tempData", "value");

Handling Cookies

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

const cookieJar = new CookieJar();
cookieJar.setCookieSync("session=abc123", "https://example.org/");

const dom = new JSDOM(``, {
  url: "https://example.org/",
  cookieJar
});

// Access cookies from page
console.log(dom.window.document.cookie); // "session=abc123"

// Set cookies from the page
dom.window.document.cookie = "theme=dark";

Error Handling with Virtual Console

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

const virtualConsole = new VirtualConsole();
virtualConsole.on("error", (err) => console.error("Page error:", err));
virtualConsole.on("jsdomError", (error) => {
  console.error("jsdom error:", error.type, error.message);
});

const dom = new JSDOM(html, { virtualConsole });

Serializing Documents

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html>hello`);

// Serialize with doctype
const html = dom.serialize();
// Returns: "<!DOCTYPE html><html><head></head><body>hello</body></html>"

// Get outerHTML (no doctype)
const outerHTML = dom.window.document.documentElement.outerHTML;
// Returns: "<html><head></head><body>hello</body></html>"

Working with Custom Events

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><body></body>`);
const { document, CustomEvent } = dom.window;

// Create and dispatch custom event
const customEvent = new CustomEvent("myCustomEvent", {
  detail: { message: "Hello" }
});

document.addEventListener("myCustomEvent", (event) => {
  console.log(event.detail.message); // "Hello"
});

document.dispatchEvent(customEvent);

Using MutationObserver

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><body><div id="target"></div></body>`);
const { document, MutationObserver } = dom.window;

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

// Create observer
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    console.log("Mutation type:", mutation.type);
    console.log("Added nodes:", mutation.addedNodes.length);
  });
});

// Start observing
observer.observe(target, {
  childList: true,
  attributes: true,
  subtree: true
});

// Make changes
target.appendChild(document.createElement("p"));
target.setAttribute("class", "active");

// Stop observing
observer.disconnect();

Working with XPath

const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html>
  <body>
    <div class="item">Item 1</div>
    <div class="item">Item 2</div>
    <div class="item">Item 3</div>
  </body>
`);

const { document, XPathResult } = dom.window;

// Evaluate XPath
const result = document.evaluate(
  "//div[@class='item']",
  document,
  null,
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null
);

console.log(result.snapshotLength); // 3

for (let i = 0; i < result.snapshotLength; i++) {
  const node = result.snapshotItem(i);
  console.log(node.textContent); // "Item 1", "Item 2", "Item 3"
}