diff --git a/doc/examples/jsdom/package.json b/doc/examples/jsdom/package.json
new file mode 100644
index 0000000000..38d8e325fe
--- /dev/null
+++ b/doc/examples/jsdom/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "axe-jsdom-example",
+ "description": "Axe JSDOM Example",
+ "version": "0.0.1",
+ "private": true,
+ "dependencies": {},
+ "scripts": {
+ "test": "mocha"
+ },
+ "devDependencies": {
+ "axe-core": "^3.2.2",
+ "jsdom": "^15.0.0",
+ "mocha": "^6.1.4"
+ }
+}
diff --git a/doc/examples/jsdom/test/a11y.js b/doc/examples/jsdom/test/a11y.js
new file mode 100644
index 0000000000..cfa4688a07
--- /dev/null
+++ b/doc/examples/jsdom/test/a11y.js
@@ -0,0 +1,61 @@
+/* global describe, it */
+const jsdom = require('jsdom');
+const { JSDOM } = jsdom;
+const assert = require('assert');
+
+describe('axe', () => {
+ const { window } = new JSDOM(`
+
+
+ JSDOM Example
+
+
+
+
+
+
+
+
+ `);
+
+ global.document = window.document;
+ global.window = window;
+
+ // needed by axios lib/helpers/isURLSameOrigin.js
+ global.navigator = window.navigator;
+
+ // needed by axe /lib/core/public/run.js
+ global.Node = window.Node;
+ global.NodeList = window.NodeList;
+
+ // needed by axe /lib/core/base/context.js
+ global.Element = window.Element;
+ global.Document = window.Document;
+
+ const axe = require('axe-core');
+ const config = {
+ rules: {
+ 'color-contrast': { enabled: false }
+ }
+ };
+
+ it('should report that good HTML is good', function(done) {
+ var n = window.document.getElementById('working');
+ axe.run(n, config, function(err, result) {
+ assert.equal(err, null, 'Error is not null');
+ assert.equal(result.violations.length, 0, 'Violations is not empty');
+ done();
+ });
+ });
+
+ it('should report that bad HTML is bad', function(done) {
+ var n = window.document.getElementById('broken');
+ axe.run(n, config, function(err, result) {
+ assert.equal(err, null, 'Error is not null');
+ assert.equal(result.violations.length, 1, 'Violations.length is not 1');
+ done();
+ });
+ });
+});