Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 3 commits into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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