What is jsdom?
The jsdom npm package is a pure-JavaScript implementation of many web standards, notably the WHATWG DOM and HTML Standards, for use with Node.js. It is designed to create a web browsing environment similar to what you would find in a web browser, allowing for the parsing and manipulation of HTML and XML documents. It can be used for testing web pages and JavaScript libraries in a Node.js environment.
What are jsdom's main functionalities?
DOM Manipulation
This feature allows you to manipulate the DOM of a document. The code sample demonstrates how to append a new list item to an unordered list.
const { JSDOM } = require('jsdom');
const dom = new JSDOM(`<ul><li>Item 1</li></ul>`);
const ul = dom.window.document.querySelector('ul');
ul.appendChild(dom.window.document.createElement('li')).textContent = 'Item 2';
console.log(dom.window.document.body.innerHTML);
Event Handling
This feature enables you to simulate and handle events. The code sample shows how to simulate a click event on a button and handle it by logging a message.
const { JSDOM } = require('jsdom');
const dom = new JSDOM(`<button id='myButton'>Click me</button>`);
const button = dom.window.document.querySelector('#myButton');
button.addEventListener('click', () => console.log('Button clicked!'));
button.click();
Fetching Remote Content
This feature allows you to fetch remote content and create a JSDOM instance from it. The code sample demonstrates fetching and logging the HTML content of a webpage.
const { JSDOM } = require('jsdom');
JSDOM.fromURL('https://example.com/').then(dom => {
console.log(dom.serialize());
});
Running Scripts
This feature allows you to run scripts within the context of the JSDOM instance. The code sample shows how to execute a script that changes the text content of the document body.
const { JSDOM } = require('jsdom');
const dom = new JSDOM(`<script>document.body.textContent = 'Hello, world!';</script>`);
console.log(dom.window.document.body.textContent);
Other packages similar to jsdom
cheerio
Cheerio is a fast, flexible, and lean implementation of core jQuery designed specifically for the server. It does not implement a full web browser API as jsdom does, but it is often used for simpler DOM manipulation tasks and is faster due to its focus on a subset of use cases.
puppeteer
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. It is more powerful for tasks like web scraping, automated testing, and rendering since it operates over a real browser, but it is heavier and more resource-intensive compared to jsdom.
phantomjs
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has similar capabilities to Puppeteer but uses WebKit as the rendering engine instead of Chromium. It is no longer actively maintained, but it was once a popular choice for headless website testing.
jsdom
CommonJS implementation of the DOM intended to be platform independent and as minimal/light as possible while completely adhering to the w3c DOM specifications.
Currently Implemented and w3c Compliant:
- DOM Level 1 (html/svg/xml)
- Browser (BOM) Augmentation (getElementsByClassName, getElementById, etc..)
Note: Running the tests now requires mjsunit.runner
see: testlog for w3 test compliance
see: plan for roadmap and thoughts about this project
see: project site for additional information
Examples
Creating a document-less window
var jsdom = require("jsdom"),
window = jsdom.createWindow();
console.log(window.document);
// output: undefined
Creating a document
var jsdom = require("jsdom"),
doc = new (jsdom.dom.level1.core.Document)();
console.log(doc.nodeName);
// outputs: #document
Creating a browser-like BOM/DOM/Window
var jsdom = require("jsdom").jsdom,
window = jsdom().createWindow(
"<html><head></head><body>hello world</body></html>"
);
console.log(window.document.innerHTML);
// output: '<html><head></head><body>hello world</body></html>'
console.log(window.innerWidth)
// output: 1024
console.log(typeof window.document.getElementsByClassName);
// outputs: function
Load arbitrary scripts
var jsdom = require("jsdom").jsdom,
window = jsdom().createWindow(),
script = window.document.createElement("script");
script.src = 'http://code.jquery.com/jquery-1.4.2.js';
script.onload = function() {
if (this.readyState === 'complete') {
console.log(window.jQuery.fn.jquery);
// outputs: 1.4.2
}
};
jQueryify
var jsdom = require("jsdom"),
window = jsdom.jsdom().createWindow();
jsdom.jQueryify(window, "http://code.jquery.com/jquery-1.4.2.min.js" , function() {
window.jQuery('body').append(<div class='testing'>Hello World, It works</div>");
console.log(window.jQuery(".testing").text());
});