diff --git a/doc/examples/jsdom/test/a11y.js b/doc/examples/jsdom/test/a11y.js index bd946cef0c..0bc935c2e5 100644 --- a/doc/examples/jsdom/test/a11y.js +++ b/doc/examples/jsdom/test/a11y.js @@ -1,10 +1,11 @@ /* global describe, it */ +const axe = require('axe-core'); const jsdom = require('jsdom'); const { JSDOM } = jsdom; const assert = require('assert'); describe('axe', () => { - const { window } = new JSDOM(` + const { document } = new JSDOM(` JSDOM Example @@ -18,30 +19,30 @@ describe('axe', () => {

Not a label

- `); - - const axe = require('axe-core'); + `).window; 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('reports that good HTML is good', async () => { + const node = document.getElementById('working'); + const result = await axe.run(node, config); + assert.equal(result.violations.length, 0, 'Violations is not empty'); + }); + + it('reports that bad HTML is bad', async () => { + const node = document.getElementById('broken'); + const results = await axe.run(node, config); + assert.equal(results.violations.length, 1, 'Violations.length is not 1'); }); - 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(); - }); + it('allows commons after axe.setup() is called', () => { + axe.setup(document); + const input = document.querySelector('input'); + const role = axe.commons.aria.getRole(input); + assert.equal(role, 'textbox'); + axe.teardown(); }); }); diff --git a/lib/core/public/run.js b/lib/core/public/run.js index b5bdbd40e9..29443d3fa8 100644 --- a/lib/core/public/run.js +++ b/lib/core/public/run.js @@ -1,6 +1,6 @@ import { getReporter } from './reporter'; import normalizeRunParams from './run/normalize-run-params'; -import { setupGlobals, resetGlobals } from './run/globals-setup'; +import { setupGlobals } from './run/globals-setup'; import { assert } from '../utils'; const noop = () => {}; @@ -36,10 +36,10 @@ export default function run(...args) { axe.utils.performanceTimer.start(); } - function handleRunRules(rawResults, cleanup) { + function handleRunRules(rawResults, teardown) { const respond = results => { axe._running = false; - cleanup(); + teardown(); try { callback(null, results); } catch (e) { @@ -55,7 +55,7 @@ export default function run(...args) { createReport(rawResults, options, respond); } catch (err) { axe._running = false; - cleanup(); + teardown(); callback(err); reject(err); } @@ -66,7 +66,6 @@ export default function run(...args) { axe.utils.performanceTimer.end(); } axe._running = false; - resetGlobals(); callback(err); reject(err); } @@ -97,7 +96,6 @@ function createReport(rawResults, options, respond) { } function handleError(err, callback) { - resetGlobals(); if (typeof callback === 'function' && callback !== noop) { callback(err.message); return; diff --git a/lib/core/public/setup.js b/lib/core/public/setup.js index 3584a205e5..bcb1258f5d 100644 --- a/lib/core/public/setup.js +++ b/lib/core/public/setup.js @@ -1,4 +1,5 @@ import { getFlattenedTree, getSelectorData } from '../utils'; +import { setupGlobals } from './run/globals-setup'; /** * Setup axe-core so axe.common functions can work properly. @@ -10,7 +11,16 @@ function setup(node) { 'Axe is already setup. Call `axe.teardown()` before calling `axe.setup` again.' ); } + // Normalize document + if ( + node && + typeof node.documentElement === 'object' && + typeof node.defaultView === 'object' + ) { + node = node.documentElement; + } + setupGlobals(node); axe._tree = getFlattenedTree(node); axe._selectorData = getSelectorData(axe._tree); diff --git a/test/core/public/setup.js b/test/core/public/setup.js index 085848db4b..242f2b544e 100644 --- a/test/core/public/setup.js +++ b/test/core/public/setup.js @@ -32,6 +32,11 @@ describe('axe.setup', function () { assert.exists(axe._selectorData); }); + it('takes documentElement when passed the document', () => { + axe.setup(document); + assert.equal(axe._tree[0].actualNode, document.documentElement); + }); + it('should throw if called twice in a row', function () { function fn() { axe.setup(); diff --git a/test/node/jsdom.js b/test/node/jsdom.js index 267ea43e31..e7bddb4191 100644 --- a/test/node/jsdom.js +++ b/test/node/jsdom.js @@ -160,4 +160,37 @@ describe('jsdom axe-core', () => { }); }); }); + + describe('axe.setup()', () => { + afterEach(() => { + axe.teardown(); + }); + + it('sets up the tree', function () { + const { document } = new jsdom.JSDOM(domStr).window; + const tree = axe.setup(document.body); + assert.equal(tree, axe._tree[0]); + assert.equal(tree.actualNode, document.body); + }); + + it('can use commons after axe.setup()', () => { + const { document } = new jsdom.JSDOM(domStr).window; + axe.setup(document); + + const skipLink = document.querySelector('#skip'); + assert.equal(axe.commons.aria.getRole(skipLink), 'link'); + assert.equal(axe.commons.text.accessibleText(skipLink), 'Skip Link'); + }); + + it('is cleaned up with axe.teardown()', () => { + const { document } = new jsdom.JSDOM(domStr).window; + axe.setup(document); + axe.teardown(); + const skipLink = document.querySelector('#skip'); + + assert.throws(() => { + assert.equal(axe.commons.aria.getRole(skipLink), 'link'); + }); + }); + }); });