Skip to content

Commit

Permalink
feat(globals): deduce required window and document globals from conte…
Browse files Browse the repository at this point in the history
…xt (#2308)

* feat(globals): deduce required window and document globals from context

* fix
  • Loading branch information
straker authored Jun 22, 2020
1 parent a56190c commit 61bac69
Show file tree
Hide file tree
Showing 8 changed files with 42 additions and 30 deletions.
14 changes: 0 additions & 14 deletions doc/examples/jsdom/test/a11y.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,6 @@ describe('axe', () => {
</body>
</html>`);

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: {
Expand Down
2 changes: 1 addition & 1 deletion lib/commons/dom/is-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
function isNode(element) {
'use strict';
return element instanceof Node;
return element instanceof window.Node;
}

export default isNode;
4 changes: 2 additions & 2 deletions lib/commons/dom/visually-contains.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ function contains(node, parent) {
style.overflow === 'scroll' ||
style.overflow === 'auto' ||
style.overflow === 'hidden' ||
parent instanceof HTMLBodyElement ||
parent instanceof HTMLHtmlElement
parent instanceof window.HTMLBodyElement ||
parent instanceof window.HTMLHtmlElement
);
}

Expand Down
4 changes: 2 additions & 2 deletions lib/commons/dom/visually-overlaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ function visuallyOverlaps(rect, parent) {
return (
style.overflow === 'scroll' ||
style.overflow === 'auto' ||
parent instanceof HTMLBodyElement ||
parent instanceof HTMLHtmlElement
parent instanceof window.HTMLBodyElement ||
parent instanceof window.HTMLHtmlElement
);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/commons/table/get-scope.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function getScope(cell) {
var role = cell.getAttribute('role');

if (
cell instanceof Element === false ||
cell instanceof window.Element === false ||
['TD', 'TH'].indexOf(cell.nodeName.toUpperCase()) === -1
) {
throw new TypeError('Expected TD or TH element');
Expand Down
17 changes: 10 additions & 7 deletions lib/core/base/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ function pushUniqueFrameSelector(context, type, selectorArray) {
*/
function normalizeContext(context) {
// typeof NodeList.length in PhantomJS === function
if ((context && typeof context === 'object') || context instanceof NodeList) {
if (context instanceof Node) {
if (
(context && typeof context === 'object') ||
context instanceof window.NodeList
) {
if (context instanceof window.Node) {
return {
include: [context],
exclude: []
Expand Down Expand Up @@ -140,7 +143,7 @@ function parseSelectorArray(context, type) {
})
);
break;
} else if (item && item.length && !(item instanceof Node)) {
} else if (item && item.length && !(item instanceof window.Node)) {
if (item.length > 1) {
pushUniqueFrameSelector(context, type, item);
} else {
Expand All @@ -152,8 +155,8 @@ function parseSelectorArray(context, type) {
})
);
}
} else if (item instanceof Node) {
if (item.documentElement instanceof Node) {
} else if (item instanceof window.Node) {
if (item.documentElement instanceof window.Node) {
result.push(context.flatTree[0]);
} else {
result.push(getNodeFromTree(item));
Expand Down Expand Up @@ -198,11 +201,11 @@ function getRootNode({ include, exclude }) {
for (var i = 0; i < selectors.length; ++i) {
var item = selectors[i];

if (item instanceof Element) {
if (item instanceof window.Element) {
return item.ownerDocument.documentElement;
}

if (item instanceof Document) {
if (item instanceof window.Document) {
return item.documentElement;
}
}
Expand Down
27 changes: 25 additions & 2 deletions lib/core/public/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ function isContext(potential) {
switch (true) {
case typeof potential === 'string':
case Array.isArray(potential):
case Node && potential instanceof Node:
case NodeList && potential instanceof NodeList:
case window.Node && potential instanceof window.Node:
case window.NodeList && potential instanceof window.NodeList:
return true;

case typeof potential !== 'object':
Expand Down Expand Up @@ -87,6 +87,29 @@ function run(context, options, callback) {
throw new Error('No audit configured');
}

// if window or document are not defined and context was passed in
// we can use it to configure them
// NOTE: because our polyfills run first, the global window object
// always exists but may not have things we expect
const hasWindow = window && 'Node' in window && 'NodeList' in window;
const hasDoc = !!document;
if (!hasWindow || !hasDoc) {
if (!context || !context.ownerDocument) {
throw new Error(
'Required "window" or "document" globals not defined and cannot be deduced from the context. ' +
'Either set the globals before running or pass in a valid Element.'
);
}

if (!hasDoc) {
document = context.ownerDocument;
}

if (!hasWindow) {
window = document.defaultView;
}
}

let args = normalizeRunParams(context, options, callback);
context = args.context;
options = args.options;
Expand Down
2 changes: 1 addition & 1 deletion lib/core/utils/check-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function checkHelper(checkResult, options, resolve, reject) {
checkResult.data = data;
},
relatedNodes: function(nodes) {
nodes = nodes instanceof Node ? [nodes] : toArray(nodes);
nodes = nodes instanceof window.Node ? [nodes] : toArray(nodes);
checkResult.relatedNodes = nodes.map(function(element) {
return new DqElement(element, options);
});
Expand Down

0 comments on commit 61bac69

Please sign in to comment.