SlideShare a Scribd company logo
1 of 27
THE JSDOM
WHAT IS JSDOM?
A JavaScript implementation of the DOM*,
for use with Node.js**
* Actually much more than just the DOM
** Actually it runs in more places than just Node.js
2 YEARS AGO…
jsdom in action
what jsdom implements
the future of jsdom
JSDOM IN ACTION
jsdom.env({
url: "http://www.dotjs.eu/",
scripts: ["https://code.jquery.com/jquery-2.1.1.js"],
loaded(errors, window) {
console.log("Number of speakers:");
console.log(window.$(".section-speakers .thumbnail").length);
}
});
var testPage = fs.readFileSync("index.html", "utf8");
var desiredOutput = fs.readFileSync("out.txt", "utf8");
browserifyFile("entry.js").then(bundledJS => {
var window = jsdom(testPage).parentWindow;
var scriptEl = window.document.createElement("script");
scriptEl.textContent = bundledJS;
window.document.head.appendChild(scriptEl);
assert.equal(window.document.body.innerHTML, desiredOutput);
});
http.createServer((req, res) => {
var pageUrl = url.parse(req.url, true)["proxy-me"];
jsdom.env(pageUrl, (err, window) => {
var images = window.document.querySelectorAll("img");
Promise.all(Array.prototype.map.call(images, imgEl => {
return getImageContents(url, imgEl.src)
.then(rotateImage)
.then(rotatedCanvas => imgEl.src = rotatedCanvas.toDataURL());
})
.then(() => res.end(jsdom.serializeDocument(window.document)));
});
}).listen(5002);
ZOMBIE.JS
var browser = Browser.create();
browser.visit("/signup")
.then(() => {
browser.fill("email", "zombie@underworld.dead");
browser.fill("password", "eat-the-living");
return browser.pressButton("Sign Me Up!");
})
.then(() => {
browser.assert.success();
browser.assert.text("title", "Welcome To Brains Depot");
});
FACEBOOK’S JEST
WHAT JSDOM IMPLEMENTS
JUST THE DOM?
NOPE.
• DOM
• HTML
• DOM Parsing & Serialization
• XHR
• URL
• CSS Selectors
• CSSOM
• (more crazy CSS specs…)
ACTUALLY, IT’S WORSE
(WE’RE FIXING THAT…)
WEB-PLATFORM-TESTS
https://github.com/w3c/web-platform-tests
FORTUNATELY, WE HAVE HELP
jsdom
parse5
cssom
csstyle
nwmatcher
xmlhttprequest
canvas
contextify
…
THE FUTURE OF JSDOM
TMPVAR/JSDOM#950
“In the browser, you can do:
window.document.querySelectorAll([
'link[type="text/xml"]',
'link[type="application/rss+xml"]',
'link[type="application/atom+xml"]'
]);
This doesn't work in jsdom.”
interface ParentNode {
...
[NewObject] NodeList querySelectorAll(DOMString selectors);
};
Document implements ParentNode;
https://dom.spec.whatwg.org/#parentnode
String(['a', 'b', 'c']) === 'a,b,c'
window.document.querySelectorAll([
'link[type="text/xml"]',
'link[type="application/rss+xml"]',
'link[type="application/atom+xml"]'
])
===
window.document.querySelectorAll(
'link[type="text/xml"],link[type="application/rss+xml"],
link[type="application/atom+xml"]'
)
WEBIDL
interface Attr {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;
readonly attribute DOMString localName;
readonly attribute DOMString name;
attribute DOMString value;
attribute DOMString textContent; // alias of .value
readonly attribute Element? ownerElement;
readonly attribute boolean specified; // useless; always returns true
};
HTMLHRELEMENT.IDL
interface HTMLHRElement : HTMLElement {
[Reflect] attribute DOMString align;
[Reflect] attribute DOMString color;
[Reflect] attribute boolean noShade;
[Reflect] attribute DOMString size;
[Reflect] attribute DOMString width;
};
⇒ HTMLHRELEMENT.JS
class HTMLHRElement extends HTMLElement {
get align() { return String(this.getAttribute("align")); }
set align(v) { this.setAttribute("align", String(v)); }
⋮
get noShade() { return Boolean(this.getAttribute("noshade")); }
set noShade(v) {
if (v) { this.setAttribute("noshade", ""); }
else { this.removeAttribute("noshade"); }
}
⋮
https://github.com/domenic/webidl-class-generator
https://github.com/domenic/webidl-html-reflector
https://github.com/domenic/webidl-conversions
https://github.com/tmpvar/jsdom

More Related Content

What's hot

Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax BasicsRichard Paul
 
JavaScript Everywhere! Creating a 100% JavaScript web stack
JavaScript Everywhere! Creating a 100% JavaScript web stackJavaScript Everywhere! Creating a 100% JavaScript web stack
JavaScript Everywhere! Creating a 100% JavaScript web stackTom Croucher
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017名辰 洪
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinNelson Glauber Leal
 
Devcast node.js e mongo db o casamento perfeito
Devcast   node.js e mongo db o casamento perfeitoDevcast   node.js e mongo db o casamento perfeito
Devcast node.js e mongo db o casamento perfeitoSuissa
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mateCodemotion
 
Bangun datar dan bangun ruang
Bangun datar dan bangun ruangBangun datar dan bangun ruang
Bangun datar dan bangun ruangSanSan Yagyoo
 
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015Jeongkyu Shin
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node jsfakedarren
 
Rapid dev env DevOps Warsaw July 2014
Rapid dev env DevOps Warsaw July 2014Rapid dev env DevOps Warsaw July 2014
Rapid dev env DevOps Warsaw July 2014blndrt
 
みんなの知らないChrome appsの世界
みんなの知らないChrome appsの世界みんなの知らないChrome appsの世界
みんなの知らないChrome appsの世界Yoichiro Tanaka
 
MongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームMongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームSuguru Namura
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004Seonki Paik
 
Shell Tips & Tricks
Shell Tips & TricksShell Tips & Tricks
Shell Tips & TricksMongoDB
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingSteve Rhoades
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Provectus
 

What's hot (20)

Javascript & Ajax Basics
Javascript & Ajax BasicsJavascript & Ajax Basics
Javascript & Ajax Basics
 
JavaScript Everywhere! Creating a 100% JavaScript web stack
JavaScript Everywhere! Creating a 100% JavaScript web stackJavaScript Everywhere! Creating a 100% JavaScript web stack
JavaScript Everywhere! Creating a 100% JavaScript web stack
 
What is nodejs
What is nodejsWhat is nodejs
What is nodejs
 
You will learn RxJS in 2017
You will learn RxJS in 2017You will learn RxJS in 2017
You will learn RxJS in 2017
 
Trimming The Cruft
Trimming The CruftTrimming The Cruft
Trimming The Cruft
 
Node.js - Best practices
Node.js  - Best practicesNode.js  - Best practices
Node.js - Best practices
 
Introdução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com KotlinIntrodução ao Desenvolvimento Android com Kotlin
Introdução ao Desenvolvimento Android com Kotlin
 
Devcast node.js e mongo db o casamento perfeito
Devcast   node.js e mongo db o casamento perfeitoDevcast   node.js e mongo db o casamento perfeito
Devcast node.js e mongo db o casamento perfeito
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Javascript is your (Auto)mate
Javascript is your (Auto)mateJavascript is your (Auto)mate
Javascript is your (Auto)mate
 
Bangun datar dan bangun ruang
Bangun datar dan bangun ruangBangun datar dan bangun ruang
Bangun datar dan bangun ruang
 
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
연구자 및 교육자를 위한 계산 및 분석 플랫폼 설계 - PyCon KR 2015
 
Building a real life application in node js
Building a real life application in node jsBuilding a real life application in node js
Building a real life application in node js
 
Rapid dev env DevOps Warsaw July 2014
Rapid dev env DevOps Warsaw July 2014Rapid dev env DevOps Warsaw July 2014
Rapid dev env DevOps Warsaw July 2014
 
みんなの知らないChrome appsの世界
みんなの知らないChrome appsの世界みんなの知らないChrome appsの世界
みんなの知らないChrome appsの世界
 
MongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲームMongoDB + node.js で作るソーシャルゲーム
MongoDB + node.js で作るソーシャルゲーム
 
Bs webgl소모임004
Bs webgl소모임004Bs webgl소모임004
Bs webgl소모임004
 
Shell Tips & Tricks
Shell Tips & TricksShell Tips & Tricks
Shell Tips & Tricks
 
Asynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time MessagingAsynchronous PHP and Real-time Messaging
Asynchronous PHP and Real-time Messaging
 
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
Василевский Илья (Fun-box): "автоматизация браузера при помощи PhantomJS"
 

Viewers also liked

The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)Domenic Denicola
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was BornDomenic Denicola
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptWojciech Dzikowski
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overviewhesher
 
Real World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptDomenic Denicola
 
Creating Truly RESTful APIs
Creating Truly RESTful APIsCreating Truly RESTful APIs
Creating Truly RESTful APIsDomenic Denicola
 
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
[Tokyo NodeFest 2015] Hardware Hacking for Javascript DevelopersTomomi Imura
 
Razor and the Art of Templating
Razor and the Art of TemplatingRazor and the Art of Templating
Razor and the Art of TemplatingJess Chadwick
 
Introducing Razor - A new view engine for ASP.NET
Introducing Razor - A new view engine for ASP.NET Introducing Razor - A new view engine for ASP.NET
Introducing Razor - A new view engine for ASP.NET Shiju Varghese
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6Solution4Future
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)Domenic Denicola
 
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016Mickaël Rémond
 

Viewers also liked (20)

Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
 
The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was Born
 
ES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern JavascriptES2015 / ES6: Basics of modern Javascript
ES2015 / ES6: Basics of modern Javascript
 
ES2015 (ES6) Overview
ES2015 (ES6) OverviewES2015 (ES6) Overview
ES2015 (ES6) Overview
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
Lecture 2: ES6 / ES2015 Slide
Lecture 2: ES6 / ES2015 SlideLecture 2: ES6 / ES2015 Slide
Lecture 2: ES6 / ES2015 Slide
 
Real World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScript
 
OpenZFS dotScale
OpenZFS dotScaleOpenZFS dotScale
OpenZFS dotScale
 
Creating Truly RESTful APIs
Creating Truly RESTful APIsCreating Truly RESTful APIs
Creating Truly RESTful APIs
 
The Final Frontier
The Final FrontierThe Final Frontier
The Final Frontier
 
Client-Side Packages
Client-Side PackagesClient-Side Packages
Client-Side Packages
 
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
[Tokyo NodeFest 2015] Hardware Hacking for Javascript Developers
 
Razor and the Art of Templating
Razor and the Art of TemplatingRazor and the Art of Templating
Razor and the Art of Templating
 
Introducing Razor - A new view engine for ASP.NET
Introducing Razor - A new view engine for ASP.NET Introducing Razor - A new view engine for ASP.NET
Introducing Razor - A new view engine for ASP.NET
 
Views
ViewsViews
Views
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016Building Scalable Systems: What you can learn from Erlang - DotScale 2016
Building Scalable Systems: What you can learn from Erlang - DotScale 2016
 

Similar to The jsdom

Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJSSylvain Zimmer
 
Intro to go web assembly
Intro to go web assemblyIntro to go web assembly
Intro to go web assemblyChe-Chia Chang
 
All aboard the NodeJS Express
All aboard the NodeJS ExpressAll aboard the NodeJS Express
All aboard the NodeJS ExpressDavid Boyer
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.jsYoann Gotthilf
 
React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsMatteo Manchi
 
The Dojo Build System
The Dojo Build SystemThe Dojo Build System
The Dojo Build Systemklipstein
 
Declarative and standards-based web application development with the Ample SDK
Declarative and standards-based web application development with the Ample SDKDeclarative and standards-based web application development with the Ample SDK
Declarative and standards-based web application development with the Ample SDKBéla Varga
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slideshelenmga
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.Mike Brevoort
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...GITS Indonesia
 
Modern Web Technologies
Modern Web TechnologiesModern Web Technologies
Modern Web TechnologiesPerttu Myry
 
WebSocket JSON Hackday
WebSocket JSON HackdayWebSocket JSON Hackday
WebSocket JSON HackdaySomay Nakhal
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejsJames Carr
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Murat Yener
 

Similar to The jsdom (20)

Web Crawling with NodeJS
Web Crawling with NodeJSWeb Crawling with NodeJS
Web Crawling with NodeJS
 
Intro to go web assembly
Intro to go web assemblyIntro to go web assembly
Intro to go web assembly
 
All aboard the NodeJS Express
All aboard the NodeJS ExpressAll aboard the NodeJS Express
All aboard the NodeJS Express
 
Scripting GeoServer
Scripting GeoServerScripting GeoServer
Scripting GeoServer
 
Introduction to REST API with Node.js
Introduction to REST API with Node.jsIntroduction to REST API with Node.js
Introduction to REST API with Node.js
 
React Native for multi-platform mobile applications
React Native for multi-platform mobile applicationsReact Native for multi-platform mobile applications
React Native for multi-platform mobile applications
 
Modern frontend in react.js
Modern frontend in react.jsModern frontend in react.js
Modern frontend in react.js
 
5.node js
5.node js5.node js
5.node js
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
The Dojo Build System
The Dojo Build SystemThe Dojo Build System
The Dojo Build System
 
Declarative and standards-based web application development with the Ample SDK
Declarative and standards-based web application development with the Ample SDKDeclarative and standards-based web application development with the Ample SDK
Declarative and standards-based web application development with the Ample SDK
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
 
Jquery dojo slides
Jquery dojo slidesJquery dojo slides
Jquery dojo slides
 
Node.js - async for the rest of us.
Node.js - async for the rest of us.Node.js - async for the rest of us.
Node.js - async for the rest of us.
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
 
Modern Web Technologies
Modern Web TechnologiesModern Web Technologies
Modern Web Technologies
 
WebSocket JSON Hackday
WebSocket JSON HackdayWebSocket JSON Hackday
WebSocket JSON Hackday
 
Introduction to nodejs
Introduction to nodejsIntroduction to nodejs
Introduction to nodejs
 
Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15Android and the Seven Dwarfs from Devox'15
Android and the Seven Dwarfs from Devox'15
 
Nodejs Intro Part One
Nodejs Intro Part OneNodejs Intro Part One
Nodejs Intro Part One
 

More from Domenic Denicola

How to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesHow to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesDomenic Denicola
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great JusticeDomenic Denicola
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 

More from Domenic Denicola (9)

ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Streams for the Web
Streams for the WebStreams for the Web
Streams for the Web
 
After Return of the Jedi
After Return of the JediAfter Return of the Jedi
After Return of the Jedi
 
How to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesHow to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards Bodies
 
The Extensible Web
The Extensible WebThe Extensible Web
The Extensible Web
 
Domains!
Domains!Domains!
Domains!
 
Promises, Promises
Promises, PromisesPromises, Promises
Promises, Promises
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 

Recently uploaded

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 

Recently uploaded (20)

Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 

The jsdom

Editor's Notes

  1. It’s my believe that to truly, deeply understand something … you have to re-implement it in JavaScript. That’s why I want to tell you about the most rewarding open-source project I’ve been involved in since joining the JavaScript community: a project called jsdom.
  2. The tagline of jsdom is that it’s a JavaScript implementation of the DOM, for use in Node.js. (Click to show asterisks.) This isn’t entirely accurate, and we’ll talk more about the details soon, but the basic idea is there. We’re starting in an environment divorced from the web, with just the basics of JavaScript to guide us: objects, functions, arrays, etc. And we want to produce a simulacrum of the many APIs that make a web page work: things like window, and document, and querySelector, and XMLHttpRequest. We want to produce such an accurate emulation, that we can then run code meant for a real browser, against our implementation. In essense, we are reimplementing much of the browser, in JavaScript. The original reason for creating jsdom was for server-side rendering. You could run the JavaScript that composes a page out of data and templates and all that, against this pure-JavaScript environment, and get a bunch of HTML out at the end. You’d then send this down the wire to render in the browser, and then run that same JavaScript in the browser against the already-rendered DOM. But jsdom has grown far beyond that.
  3. I got involved with jsdom a couple years ago, mainly using it for testing. I was writing a Windows 8 app in HTML and JS, and it turns out that there’s no way to run automated unit tests in Windows 8. Crazy, right? So I found this project called jsdom, that provided a virtual environment in which I could run my unit tests. I submitted a few pull requests, then a few more, and pretty soon I was hooked. I’ve been helping to maintain the project ever since, with involvement from some 124 other contributors as well.
  4. Here’s an example of perhaps the simplest use of jsdom: using it as a web scraper. You can see how we load a URL into the jsdom environment, then also load our own script---jQuery. One everything has loaded into the environment, we can manipulate the window object to do things like select elements using jQuery and count or manipulate them. Note that all of this is taking place purely in Node.js---in JavaScript. There’s no instance of Chrome being booted up; no Selenium server in the background. The process of building up a virtual tree of nodes into a document, and into a fully-functional window object, is taking place entirely in terms of JavaScript objects provided by the jsdom library. Pretty cool, right?
  5. Here’s an example that’s a bit more complicated. It shows how you can use jsdom for testing. In this case, we’re testing some code that’s meant to run in the browser via browserify. First we create the JavaScript for the browserify bundle, just as a string of JS. Then we use jsdom to create an in-memory window from a basic index.html page. Then we manipulate this window: we create a <script> element, and insert the output from browserify into that script element. Finally we test to see if the script modified the contents of our window’s <body> in the expected manner. I use jsdom for these kind of tests in many of the libraries I write. In this way it can replace costly out-of-process tools like PhantomJS or Selenium.
  6. Finally, here’s an example of using jsdom in real-time as part of a server pipeline. This is a quick-and-dirty HTTP server that will take any URL you give it, and use jsdom to flip all the images, in real time. It does this by using jsdom’s canvas functionality to rotate the image, then get the result as a data URL, which it then modifies the DOM to point to. And indeed…
  7. It works! … These examples give you some idea of some of the more common uses of having an in-JavaScript DOM: scraping, testing, and real-time manipulation. People have built more complicated tools on top of jsdom, for example:
  8. Zombie.js, which takes the idea of an in-memory window one step further to give you an in-memory browser, where you can submit forms, click links, and more.
  9. Or Facebook’s Jest testing framework, which uses jsdom to run your tests lightning-fast against a mocked browser environment.
  10. The actual “DOM” standard is just a single document, a living standard hosted at dom.spec.whatwg.org. It defines only the basics, really: events, node trees, attributes, mutation observers, and documents. You might think creating jsdom was just a matter of translating this spec into code.
  11. It turns out that to create a useful document and window object, you need a lot more than just the DOM Standard and its node trees. You also need HTML, for the definition of all the elements that will appear in that DOM. You need the spec for parsing the DOM, in order to construct the node tree from a string. You need the spec for serializing, in order to make innerHTML work. And of course you need things like XHR and URL parsing. What’s more, even though jsdom doesn’t do any actual layout calculations (yet?), you do need some CSS implemented. CSS selectors, of course, so that querySelector works, but also the CSS object model, so that when things animate or hide or show, you can reflect that in the .style property.
  12. jsdom was coded before the modern DOM and HTML standards existed. Instead, we have this code structure that tries to build itself up in steps: first DOM level 1, then… well… (Slides) It turns out browsers never actually implemented a lot of this stuff. Much of it was crazy XML things; others were just very obscure; etc. The modern DOM and HTML standards codify what browsers actually implement, in a single spec, and they have a note about how a bunch of stuff is obsolete and should be removed from implementations that still have it. So jsdom is actually built in this same layered way, reflecting the historical way specs grew up, and needs a good clean-up effort. That’s just a small taste of the unfortunate truth about the standards underlying the web platform, but we’ll stop there for today.
  13. Anyway, the good news is we’re fixing that; in jsdom 2.0, we’re starting the process of squashing everything down into a single implementation, instead of the layer cake.
  14. As part of this effort, we’re starting to run the web-platform-tests suite against jsdom. Web-platform-tests is a cross-vendor test suite meant to cover, essentially, all of the web platform: DOM, HTML, CSS, Shadow DOM, Service Worker … it’s all there. It’s not perfect by any means. Coverage is pretty spotty … there’s only two tests for all of <select>, for example. It’s generally understaffed, and it’s sometimes hard to get vendors to contribute their tests to the suite. But it’s still a really cool project, and I’m excited for jsdom to start participating in it---hopefully we can become one of the vendors contributing our tests back, so that they’re run in all the “real” web browsers out there. Right now we’re just running a tiny subset, but our policy is that new features should be implemented by pulling in the appropriate web-platform-test.
  15. Finally, I want to give a shout out to the other projects that make jsdom possible. We depend on these guys for some of the trickiest and most important parts of jsdom. They’re all maintained by separate people, outside of the jsdom team, who have taken the time to produce a faithful implementation of the relevant part of the web platform. I’ve been consistently impressed by how professional the maintainers of these projects are, and the extent to which they’re willing to work with jsdom. For example, we recently had a great collaboration with the author of parse5, our HTML parser, to get support for the <template> tag into jsdom. And when we wanted to make jsdom browserifyable, so that you could run it in a web worker, we discussed some of the tricks we needed with the author of cssstyle, and were able to get that up and running pretty quickly. It’s been really great.
  16. I want to finish up by talking about the future of jsdom, but I’m going to do it in a bit of a roundabout way. I promise it’ll all connect up.
  17. First I want to share with you this interesting issue that was opened on jsdom pretty recently. (read the slide) I was pretty puzzled by this, as I’d never heard of querySelectorAll taking an array before. So I went to look at the spec:
  18. The thing to notice is that querySelectorAll is specced as taking a “DOMString,” which to us mere mortals just means a JavaScript string. But what’s important to realize about the spec is that when it says something takes a DOMString, it means that any argument you pass it gets converted to a string. So from this perspective, the behavior makes sense:
  19. When you convert an array to a string, it does a join with commas. So that’s why you can pass an array to querySelectorAll, and it’ll still work.
  20. It turns out that this is a pretty general problem, and it occurs because we’ve been mostly ignoring the way specs are written. Specs are written in this horrible language called “WebIDL,” with weird concepts like “interfaces” and “readonly attributes.” What browsers actually do, given this, is they write code generation tools to take WebIDL and turn it into C++ implementations of the DOM APIs, with all the type conversions and such baked in. This is the kind of step we’re missing from jsdom: something that takes the machine-readable WebIDL language written in the specs, and auto-generates the correct type conversions and so on.
  21. In fact, you can go further than this in some cases. You can generate the entire HTMLHRElement class from its IDL definition. This definition, translated into JavaScript speak, is just saying that it has a number of getters and setters which “reflect” the values of the corresponding HTML attribute. It really just means this:
  22. What I’ve done here, is “generated” a JavaScript implementation of HTMLHRElement from its WebIDL definition. Just like how browser vendors generate C++ implementations from WebIDL! This way we’re guaranteed to get all the correct semantics, as specified in the appropriate standard, and not create any oversights. Well of course, as I said at the beginning, to truly understand something, like how browsers generate their implementations of the DOM from IDL, you have to reimplement it in JavaScript.
  23. So that’s what I’ve been doing. These tools are actually built in the service of a separate project of mine, HTML as Custom Elements, which I’d love to talk with you about. The basic idea is that they’re able to take as input WebIDL, with all its weird features, and convert them into straight JavaScript classes. In other words, they are an automated version of the translation that I did by hand in the last two slides. The first generates the class; the second is responsible for the details of reflecting WebIDL properties to HTML attributes; and the last is responsible for doing all the type conversions, some of which are actually pretty complicated. But the main takeaway here, is to realize that me and the jsdom team are moving ever forward, becoming more and more a real browser, and learning more and more along the way.
  24. So that’s it! I’d encourage you to come contribute to jsdom with me, and learn how the web platform works … by reimplementing it in JavaScript.