Socket
Socket
Sign inDemoInstall

axe-core

Package Overview
Dependencies
0
Maintainers
4
Versions
1333
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.0.0-beta.1 to 3.0.0-beta.2

doc/examples/phantomjs/package.json

2

axe.d.ts

@@ -1,2 +0,2 @@

// Type definitions for axe-core 3.0.0-beta.1
// Type definitions for axe-core 3.0.0-beta.2
// Project: https://github.com/dequelabs/axe-core

@@ -3,0 +3,0 @@ // Definitions by: Marcy Sutton <https://github.com/marcysutton>

{
"name": "axe-core",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"contributors": [

@@ -46,2 +46,2 @@ {

"devDependencies": {}
}
}

@@ -0,1 +1,20 @@

<a name="3.0.0-beta.2"></a>
# [3.0.0-beta.2](https://github.com/dequelabs/axe-core/compare/v3.0.0-alpha.9...v3.0.0-beta.2) (2018-03-01)
### Bug Fixes
* **perf:** Improve getSelector performance ([737c81c](https://github.com/dequelabs/axe-core/commit/737c81c))
* Delete Selenium example, use grunt-axe-selenium instead ([063e701](https://github.com/dequelabs/axe-core/commit/063e701))
### Features
* Update Jasmin example ([72d49d5](https://github.com/dequelabs/axe-core/commit/72d49d5))
* Update Jest+React example ([5b35322](https://github.com/dequelabs/axe-core/commit/5b35322))
* Update Mocha example ([cf70f9f](https://github.com/dequelabs/axe-core/commit/cf70f9f))
* Update PhantomJS example ([641b5e6](https://github.com/dequelabs/axe-core/commit/641b5e6))
* Update QUnit example ([028ae51](https://github.com/dequelabs/axe-core/commit/028ae51))
# Change Log

@@ -88,2 +107,24 @@

<a name="3.0.0-alpha.7"></a>
# [3.0.0-alpha.7](https://github.com/dequelabs/axe-core/compare/v3.0.0-alpha.6...v3.0.0-alpha.7) (2017-10-20)
### Bug Fixes
* **aria-allowed-attr:** align rowcount, colcount, and colindex with 1.1 spec ([#555](https://github.com/dequelabs/axe-core/issues/555)) ([10efa88](https://github.com/dequelabs/axe-core/commit/10efa88))
* **required-children:** add combobox > listbox exception ([#559](https://github.com/dequelabs/axe-core/issues/559)) ([8d0991f](https://github.com/dequelabs/axe-core/commit/8d0991f))
* Added message about expected contrast ratio ([#381](https://github.com/dequelabs/axe-core/issues/381)) ([#562](https://github.com/dequelabs/axe-core/issues/562)) ([9e30d64](https://github.com/dequelabs/axe-core/commit/9e30d64))
### Performance Improvements
* **reporter:** add option to limit result types to be processed ([#568](https://github.com/dequelabs/axe-core/issues/568)) ([42b46d9](https://github.com/dequelabs/axe-core/commit/42b46d9)), closes [#512](https://github.com/dequelabs/axe-core/issues/512)
# Change Log
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
<a name="3.0.0-alpha.6"></a>

@@ -90,0 +131,0 @@ # [3.0.0-alpha.6](https://github.com/dequelabs/axe-core/compare/v3.0.0-alpha.3...v3.0.0-alpha.6) (2017-09-27)

@@ -426,3 +426,3 @@ # aXe Javascript Accessibility API

5. Run only some tags, bug exclude others
5. Run only some tags, but exclude others

@@ -429,0 +429,0 @@ Similar to scope, the runOnly option can accept an object with an 'include' and 'exclude' property. Only those checks that match an included tag will run, except those that share a tag from the exclude list.

@@ -13,9 +13,9 @@ {

"scripts": {
"build": "grunt"
"test": "grunt jasmine"
},
"devDependencies": {
"axe-core": "~1.0.1",
"grunt": "~0.4.4",
"grunt-contrib-jasmine": "~0.9.2"
"axe-core": "^2.6.1",
"grunt": "~1.0.2",
"grunt-contrib-jasmine": "~1.1.0"
}
}

@@ -11,4 +11,3 @@ {

},
"dependencies": {
},
"dependencies": {},
"scripts": {

@@ -18,13 +17,14 @@ "test": "jest"

"devDependencies": {
"axe-core": "^2.2.3",
"babel-jest": "^20.0.3",
"axe-core": "^2.6.1",
"babel-jest": "^22.4.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"enzyme": "^2.8.2",
"jest": "^20.0.4",
"jest-cli": "^20.0.4",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"react-test-renderer": "^15.5.4"
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"jest": "^22.4.0",
"jest-cli": "^22.4.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-test-renderer": "^16.2.0"
}
}

@@ -1,3 +0,6 @@

import { mount } from 'enzyme';
import { configure, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
let wrapper

@@ -4,0 +7,0 @@ export function mountToDoc (reactElm) {

@@ -13,10 +13,10 @@ {

"scripts": {
"build": "grunt"
"test": "grunt mocha"
},
"devDependencies": {
"axe-core": "~1.0.1",
"grunt": "~0.4.4",
"grunt-mocha": "~0.4.10",
"chai": "~1.9.1"
"axe-core": "^2.6.1",
"chai": "~4.1.2",
"grunt": "~1.0.2",
"grunt-mocha": "1.0.0"
}
}
/* global describe, it, expect, axe, document */
describe('axe', function () {
/* jshint expr: true */
'use strict';

@@ -9,3 +10,3 @@

axe.run(n, function (err, result) {
expect(err).to.be.null();
expect(err).to.be.null;
expect(result.violations.length).to.equal(0);

@@ -19,3 +20,3 @@ done();

axe.run(n, function (err, result) {
expect(err).to.be.null();
expect(err).to.be.null;
expect(result.violations.length).to.equal(1);

@@ -22,0 +23,0 @@ done();

@@ -13,2 +13,4 @@ /*global window, phantom */

console.log('Testing, please wait...');
page.open(args[1], function (status) {

@@ -41,7 +43,11 @@ // Check for page load success

} else {
console.log(JSON.stringify(msg, null, ' '));
if (msg.violations.length) {
console.log(JSON.stringify(msg.violations, null, ' '));
} else {
console.log('No violations found!');
}
}
phantom.exit();
phantom.exit(msg.violations.length);
};
});

@@ -13,10 +13,10 @@ {

"scripts": {
"build": "grunt"
"test": "grunt qunit"
},
"devDependencies": {
"axe-core": "~1.0.1",
"grunt": "~0.4.4",
"grunt-contrib-qunit": "~0.4.0",
"qunitjs": "~1.14.0"
"axe-core": "^2.6.1",
"grunt": "~1.0.2",
"grunt-contrib-qunit": "~2.0.0",
"qunitjs": "~2.4.1"
}
}

@@ -1,23 +0,27 @@

/* global module, asyncTest, expect, start, document, axe */
/* global QUnit, document, axe */
module('axe');
QUnit.module('axe');
asyncTest('should report that good HTML is good', function (assert) {
QUnit.test('should report that good HTML is good', function (assert) {
var n = document.getElementById('working');
expect(1);
assert.expect(2);
var done = assert.async();
axe.run(n, function (err, result) {
assert.equal(err, null);
assert.equal(result.violations.length, 0);
start();
done();
});
});
asyncTest('should report that bad HTML is bad', function (assert) {
QUnit.test('should report that bad HTML is bad', function (assert) {
var n = document.getElementById('broken');
expect(1);
assert.expect(2);
var done = assert.async();
axe.run(n, function (err, result) {
assert.equal(err, null);
assert.equal(result.violations.length, 1);
start();
done();
});
});

@@ -7,4 +7,4 @@ {

"messages": {
"pass": "Links can be distinguished from surrounding text in a way that does not rely on color",
"fail": "Links can not be distinguished from surrounding text in a way that does not rely on color",
"pass": "Links can be distinguished from surrounding text in some way other than by color",
"fail": "Links need to be distinguished from surrounding text in some way other than by color",
"incomplete": {

@@ -11,0 +11,0 @@ "bgContrast": "Element's contrast ratio could not be determined. Check for a distinct hover/focus style",

@@ -183,3 +183,2 @@ /*global Rule, Check, RuleResult, commons: true */

q.then(function (results) {
axe._tree = undefined; // empty the tree
axe._selectCache = undefined; // remove the cache

@@ -186,0 +185,0 @@ resolve(results.filter(function (result) { return !!result; }));

@@ -130,2 +130,4 @@ /* global Promise */

let results = reporter(rawResults, options, respond);
axe._selectorData = undefined;
axe._tree = undefined;
if (results !== undefined) {

@@ -132,0 +134,0 @@ respond(results);

function err(message, node) {
'use strict';
return new Error(message + ': ' + axe.utils.getSelector(node));
var selector;
if (axe._tree) {
selector = axe.utils.getSelector(node);
}
return new Error(message + ': ' + (selector || node));
}

@@ -6,0 +10,0 @@

const escapeSelector = axe.utils.escapeSelector;
let isXHTML;
const ignoredAttributes = [
'class', 'style', 'id',
'selected', 'checked',
'disabled', 'tabindex',
'aria-checked', 'aria-selected',
'aria-invalid', 'aria-activedescendant',
'aria-busy', 'aria-disabled', 'aria-expanded',
'aria-grabbed', 'aria-pressed', 'aria-valuenow'
];
const MAXATTRIBUTELENGTH = 31;
function isUncommonClassName (className) {
return ![
'focus', 'hover',
'hidden', 'visible',
'dirty', 'touched', 'valid', 'disable',
'enable', 'active', 'col-'
].find(str => className.includes(str));
/**
* get the attribute name and value as a string
* @param {Element} node The element that has the attribute
* @param {Attribute} at The attribute
* @return {String}
*/
function getAttributeNameValue(node, at) {
const name = at.name;
let atnv;
if (name.indexOf('href') !== -1 || name.indexOf('src') !== -1) {
let value = encodeURI(axe.utils.getFriendlyUriEnd(node.getAttribute(name)));
if (value) {
atnv = escapeSelector(at.name) + '$="' + value + '"';
} else {
return;
}
} else {
atnv = escapeSelector(name) + '="' + escapeSelector(at.value) + '"';
}
return atnv;
}
function getDistinctClassList (elm) {
if (!elm.classList || elm.classList.length === 0) {
return [];
function countSort(a, b) {
return (a.count < b.count) ? -1 : (a.count === b.count) ? 0 : 1;
}
/**
* Filter the attributes
* @param {Attribute} The potential attribute
* @return {Boolean} Whether to include or exclude
*/
function filterAttributes(at) {
return !ignoredAttributes.includes(at.name) && at.name.indexOf(':') === -1 &&
(!at.value || at.value.length < MAXATTRIBUTELENGTH);
}
/**
* Calculate the statistics for the classes, attributes and tags on the page, using
* the virtual DOM tree
* @param {Object} domTree The root node of the virtual DOM tree
* @returns {Object} The statistics consisting of three maps, one for classes,
* one for tags and one for attributes. The map values are
* the counts for how many elements with that feature exist
*/
axe.utils.getSelectorData = function (domTree) {
// jshint maxstatements:22
// jshint loopfunc:true
// Initialize the return structure with the three maps
let data = {
classes: {},
tags: {},
attributes: {}
};
domTree = Array.isArray(domTree) ? domTree : [domTree];
let currentLevel = domTree.slice();
let stack = [];
while (currentLevel.length) {
let current = currentLevel.pop();
let node = current.actualNode;
if (!!node.querySelectorAll) { // ignore #text nodes
// count the tag
let tag = node.nodeName;
if (data.tags[tag]) {
data.tags[tag]++;
} else {
data.tags[tag] = 1;
}
// count all the classes
if (node.classList) {
Array.from(node.classList).forEach((cl) => {
const ind = escapeSelector(cl);
if (data.classes[ind]) {
data.classes[ind]++;
} else {
data.classes[ind] = 1;
}
});
}
// count all the filtered attributes
if (node.attributes) {
Array.from(node.attributes).filter(filterAttributes).forEach((at) => {
let atnv = getAttributeNameValue(node, at);
if (atnv) {
if (data.attributes[atnv]) {
data.attributes[atnv]++;
} else {
data.attributes[atnv] = 1;
}
}
});
}
}
if (current.children.length) {
// "recurse"
stack.push(currentLevel);
currentLevel = current.children.slice();
}
while (!currentLevel.length && stack.length) {
currentLevel = stack.pop();
}
}
return data;
};
const siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];
return siblings.reduce((classList, childElm) => {
if (elm === childElm) {
return classList;
} else {
return classList.filter(classItem => {
return !childElm.classList.contains(classItem);
});
}
}, Array.from(elm.classList).filter(isUncommonClassName));
/**
* Given a node and the statistics on class frequency on the page,
* return all its uncommon class data sorted in order of decreasing uniqueness
* @param {Element} node The node
* @param {Object} classData The map of classes to counts
* @return {Array} The sorted array of uncommon class data
*/
function uncommonClasses(node, selectorData) {
// jshint loopfunc:true
let retVal = [];
let classData = selectorData.classes;
let tagData = selectorData.tags;
if (node.classList) {
Array.from(node.classList).forEach((cl) => {
let ind = escapeSelector(cl);
if (classData[ind] < tagData[node.nodeName]) {
retVal.push({
name: ind,
count: classData[ind],
species: 'class'
});
}
});
}
return retVal.sort(countSort);
}
const commonNodes = [
'div', 'span', 'p',
'b', 'i', 'u', 'strong', 'em',
'h2', 'h3'
];
/**
* Given an element and a selector that finds that element (but possibly other sibling elements)
* return the :nth-child(n) pseudo selector that uniquely finds the node within its siblings
* @param {Element} elm The Element
* @param {String} selector The selector
* @return {String} The nth-child selector
*/
function getNthChildString (elm, selector) {

@@ -50,170 +174,175 @@ const siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];

const createSelector = {
// Get ID properties
getElmId (elm) {
if (!elm.getAttribute('id')) {
return;
}
let doc = (elm.getRootNode && elm.getRootNode()) || document;
const id = '#' + escapeSelector(elm.getAttribute('id') || '');
if (
// Don't include youtube's uid values, they change on reload
!id.match(/player_uid_/) &&
// Don't include IDs that occur more then once on the page
doc.querySelectorAll(id).length === 1
) {
return id;
}
},
// Get custom element name
getCustomElm (elm, { isCustomElm, nodeName }) {
if (isCustomElm) {
return nodeName;
}
},
// Get ARIA role
getElmRoleProp (elm) {
if (elm.hasAttribute('role')) {
return '[role="' + escapeSelector(elm.getAttribute('role')) +'"]';
}
},
// Get uncommon node names
getUncommonElm (elm, { isCommonElm, isCustomElm, nodeName }) {
if (!isCommonElm && !isCustomElm) {
// Add [type] if nodeName is an input element
if (nodeName === 'input' && elm.hasAttribute('type')) {
nodeName += '[type="' + elm.type + '"]';
}
return nodeName;
}
},
// Has a name property, but no ID (Think input fields)
getElmNameProp (elm) {
if (!elm.hasAttribute('id') && elm.name) {
return '[name="' + escapeSelector(elm.name) + '"]';
}
},
// Get any distinct classes (as long as there aren't more then 3 of them)
getDistinctClass (elm, { distinctClassList }) {
if (distinctClassList.length > 0 && distinctClassList.length < 3) {
return '.' + distinctClassList.map(escapeSelector).join('.');
}
},
// Get a selector that uses src/href props
getFileRefProp (elm) {
let attr;
if (elm.hasAttribute('href')) {
attr = 'href';
} else if (elm.hasAttribute('src')) {
attr = 'src';
} else {
return;
}
const friendlyUriEnd = axe.utils.getFriendlyUriEnd(elm.getAttribute(attr));
if (friendlyUriEnd) {
return '[' + attr + '$="' + encodeURI(friendlyUriEnd) + '"]';
}
},
// Get common node names
getCommonName (elm, { nodeName, isCommonElm }) {
if (isCommonElm) {
return nodeName;
}
/**
* Get ID selector
*/
function getElmId (elm) {
if (!elm.getAttribute('id')) {
return;
}
};
let doc = (elm.getRootNode && elm.getRootNode()) || document;
const id = '#' + escapeSelector(elm.getAttribute('id') || '');
if (
// Don't include youtube's uid values, they change on reload
!id.match(/player_uid_/) &&
// Don't include IDs that occur more then once on the page
doc.querySelectorAll(id).length === 1
) {
return id;
}
}
/**
* Get an array of features (as CSS selectors) that describe an element
* Return the base CSS selector for a given element
*
* By going down the list of most to least prominent element features,
* we attempt to find those features that a dev is most likely to
* recognize the element by (IDs, aria roles, custom element names, etc.)
*/
function getElmFeatures (elm, featureCount) {
* @param {HTMLElement} elm The element to get the selector for
* @return {String | Array[String]} Base CSS selector for the node
*/
function getBaseSelector(elm) {
if (typeof isXHTML === 'undefined') {
isXHTML = axe.utils.isXHTML(document);
}
const nodeName = escapeSelector(isXHTML?
elm.localName
:elm.nodeName.toLowerCase());
const classList = Array.from(elm.classList) || [];
// Collect some props we need to build the selector
const props = {
nodeName,
classList,
isCustomElm: nodeName.includes('-'),
isCommonElm: commonNodes.includes(nodeName),
distinctClassList: getDistinctClassList(elm)
};
return escapeSelector(isXHTML ? elm.localName : elm.nodeName.toLowerCase());
}
return [
// go through feature selectors in order of priority
createSelector.getCustomElm,
createSelector.getElmRoleProp,
createSelector.getUncommonElm,
createSelector.getElmNameProp,
createSelector.getDistinctClass,
createSelector.getFileRefProp,
createSelector.getCommonName
].reduce((features, func) => {
// As long as we haven't met our count, keep looking for features
if (features.length === featureCount) {
return features;
/**
* Given a node and the statistics on attribute frequency on the page,
* return all its uncommon attribute data sorted in order of decreasing uniqueness
* @param {Element} node The node
* @param {Object} attData The map of attributes to counts
* @return {Array} The sorted array of uncommon attribute data
*/
function uncommonAttributes(node, selectorData) {
let retVal = [];
let attData = selectorData.attributes;
let tagData = selectorData.tags;
if (node.attributes) {
Array.from(node.attributes).filter(filterAttributes).forEach((at) => {
const atnv = getAttributeNameValue(node, at);
if (atnv && attData[atnv] < tagData[node.nodeName]) {
retVal.push({
name: atnv,
count: attData[atnv],
species: 'attribute'
});
}
});
}
return retVal.sort(countSort);
}
/**
* generates a selector fragment for an element based on the statistics of the page in
* which the element exists. This function takes into account the fact that selectors that
* use classes and tags are much faster than universal selectors. It also tries to use a
* unique class selector before a unique attribute selector (with the tag), followed by
* a selector made up of the three least common features statistically. A feature will
* also only be used if it is less common than the tag of the element itself.
*
* @param {Element} elm The element for which to generate a selector
* @param {Object} options Options for how to generate the selector
* @param {RootNode} doc The root node of the document or document fragment
* @returns {String} The selector
*/
function getThreeLeastCommonFeatures(elm, selectorData) {
let selector = '';
let features;
let clss = uncommonClasses(elm, selectorData);
let atts = uncommonAttributes(elm, selectorData);
if (clss.length && clss[0].count === 1) {
// only use the unique class
features = [clss[0]];
} else if (atts.length && atts[0].count === 1) {
// only use the unique attribute value
features = [atts[0]];
// if no class, add the tag
selector = getBaseSelector(elm);
} else {
features = clss.concat(atts);
// sort by least common
features.sort(countSort);
// select three least common features
features = features.slice(0, 3);
// if no class, add the tag
if (!features.some((feat) => { return feat.species === 'class'; })) {
// has no class
selector = getBaseSelector(elm);
} else {
// put the classes at the front of the selector
features.sort((a, b) => {
return (a.species !== b.species && a.species === 'class') ? -1 : (a.species === b.species) ? 0 : 1;
});
}
}
const feature = func(elm, props);
if (feature) {
if (!feature[0].match(/[a-z]/)) {
features.push(feature);
} else {
features.unshift(feature);
}
// construct the return value
return selector += features.reduce((val, feat) => {
switch(feat.species) {
case 'class':
return val + '.' + feat.name;
case 'attribute':
return val + '[' + feat.name + ']';
}
return features;
}, []);
return val; // should never happen
}, '');
}
/**
* generates a single selector for an element
* @param {Element} elm The element for which to generate a selector
* @param {Object} options Options for how to generate the selector
* @param {RootNode} doc The root node of the document or document fragment
* @returns {String} The selector
*/
function generateSelector (elm, options, doc) {
//jshint maxstatements: 19
let selector, addParent;
let { isUnique = false } = options;
const idSelector = createSelector.getElmId(elm);
//jshint maxstatements:21
//jshint loopfunc:true
if (!axe._selectorData) {
axe._selectorData = axe.utils.getSelectorData(axe._tree);
}
const {
featureCount = 2,
minDepth = 1,
toRoot = false,
childSelectors = []
toRoot = false
} = options;
let selector;
let similar;
if (idSelector) {
selector = idSelector;
isUnique = true;
/**
* Try to find a unique selector by filtering out all the clashing
* nodes by adding ancestor selectors iteratively.
* This loop is much faster than recursing and using querySelectorAll
*/
do {
let features = getElmId(elm);
if (!features) {
features = getThreeLeastCommonFeatures(elm, axe._selectorData);
features += getNthChildString(elm, features);
}
if (selector) {
selector = features + ' > ' + selector;
} else {
selector = features;
}
if (!similar) {
similar = Array.from(doc.querySelectorAll(selector));
} else {
similar = similar.filter((item) => {
return axe.utils.matchesSelector(item, selector);
});
}
elm = elm.parentElement;
} while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11);
} else {
selector = getElmFeatures(elm, featureCount).join('');
selector += getNthChildString(elm, selector);
isUnique = options.isUnique || doc.querySelectorAll(selector).length === 1;
if (similar.length === 1) {
return selector;
} else if (selector.indexOf(' > ') !== -1) {
// For the odd case that document doesn't have a unique selector
if (!isUnique && elm === document.documentElement) {
// todo: figure out what to do for shadow DOM
selector += ':root';
}
addParent = (minDepth !== 0 || !isUnique);
return ':root' + selector.substring(selector.indexOf(' > '));
}
const selectorParts = [selector, ...childSelectors];
if (elm.parentElement && elm.parentElement.nodeType !== 11 &&
(toRoot || addParent)) {
return generateSelector(elm.parentNode, {
toRoot, isUnique,
childSelectors: selectorParts,
featureCount: 1,
minDepth: minDepth -1
}, doc);
} else {
return selectorParts.join(' > ');
}
return ':root';
}

@@ -223,5 +352,5 @@

* Gets a unique CSS selector
* @param {HTMLElement} node The element to get the selector for
* @param {HTMLElement} node The element to get the selector for
* @param {Object} optional options
* @return {String | Array[String]} Unique CSS selector for the node
* @return {String | Array[String]} Unique CSS selector for the node
*/

@@ -228,0 +357,0 @@ axe.utils.getSelector = function createUniqueSelector (elm, options = {}) {

{
"name": "axe-core",
"description": "Accessibility engine for automated Web UI testing",
"version": "3.0.0-beta.1",
"version": "3.0.0-beta.2",
"license": "MPL-2.0",

@@ -95,2 +95,2 @@ "engines": {

"dependencies": {}
}
}

@@ -58,2 +58,18 @@ {

},
"2.4.2": {
"axe.js": "sha256-N21EZIlTis66XyG9F0DUSG+makyS31j4/yIBtvLKjHc=",
"axe.min.js": "sha256-uvfxOT2C0Y0fXlGDYDeDwYkBaZT3VgVMXEuSjG5TA14="
},
"2.5.0": {
"axe.js": "sha256-NYUXSdma9KjPfzmpt7jw/hlbmeAha8K3zEA2UOW+eWw=",
"axe.min.js": "sha256-7MV3BvKtgHeecwFjYOBYJbmOhvh2wdTGU7odxgpcrG0="
},
"2.6.0": {
"axe.js": "sha256-zK6kpREBDqi1wucJ1GoH9UafxT0E0+XUnrSzg03wdmw=",
"axe.min.js": "sha256-vqKSLjjqbp9J3seCuphn1h/3OC6o5jntS8LtlIftvdY="
},
"2.6.1": {
"axe.js": "sha256-HhkD8uj4rlOhjNmsuHHncei+5KplvYnAhJnosLXMztk=",
"axe.min.js": "sha256-y+l4Fcz9wkN5fulZ8z6Lpj2XY7l3GOoqSgw7/H5nbyM="
},
"3.0.0-alpha.7": {

@@ -74,3 +90,7 @@ "axe.js": "sha256-10kIurI2DW5bjegHOgc/MMSHiiXK2CAVWCQfoN6h0fs=",

"axe.min.js": "sha256-d18mAMFS/EfXi4Rd/BgC+LDs1WbBi+3qiv2m1bD0pm8="
},
"3.0.0-beta.2": {
"axe.js": "sha256-cMk6LIQ0mYRm54wqfZ6O2U/6BT6XpHPjqIPVyhMMHYU=",
"axe.min.js": "sha256-66fXkU5+wmx5X9sURMglHTsWKO8R+LoOIcBwB8N9dPI="
}
}

@@ -502,15 +502,2 @@ /*global Audit, Rule */

});
it('should clear axe._tree', function (done) {
var thing = 'honey badger';
axe.utils.getFlattenedTree = function () {
return thing;
};
a.run({ include: [document] }, {
rules: {}
}, function () {
assert.isTrue(typeof axe._tree === 'undefined');
axe.utils.getFlattenedTree = getFlattenedTree;
done();
}, isNotCalled);
});
it('should assign an empty array to axe._selectCache', function (done) {

@@ -517,0 +504,0 @@ var saved = axe.utils.ruleShouldRun;

@@ -75,2 +75,3 @@ /*global runRules */

setTimeout(function () {
axe._tree = axe.utils.getFlattenedTree(document);
runRules(document, {}, function (r) {

@@ -100,2 +101,3 @@ assert.lengthOf(r[0].passes, 3);

setTimeout(function () {
axe._tree = axe.utils.getFlattenedTree(document);
runRules(document, {}, function (r) {

@@ -159,2 +161,3 @@ var nodes = r[0].passes.map(function (detail) {

axe._tree = axe.utils.getFlattenedTree(document);
runRules('#fixture', {}, function (results) {

@@ -235,2 +238,3 @@ assert.deepEqual(JSON.parse(JSON.stringify(results)), [{

iframeReady('../mock/frames/context.html', fixture, 'context-test', function () {
axe._tree = axe.utils.getFlattenedTree(document);
runRules('#not-happening', {}, function () {

@@ -237,0 +241,0 @@ assert.fail('This selector should not exist.');

@@ -94,2 +94,17 @@ describe('axe.run', function () {

it('should clear axe._tree', function (done) {
var getFlattenedTree = axe.utils.getFlattenedTree;
var thing = 'honey badger';
axe.utils.getFlattenedTree = function () {
return thing;
};
axe._runRules = function () {
assert.isTrue(typeof axe._tree === 'undefined');
axe.utils.getFlattenedTree = getFlattenedTree;
done();
};
axe.run({ someOption: true }, noop);
});
describe('callback', function () {

@@ -96,0 +111,0 @@ it('gives errors to the first argument on the callback', function (done) {

/*global Context */
describe('axe.utils.collectResultsFromFrames', function () {
'use strict';
'use strict';
var fixture = document.getElementById('fixture');
var noop = function () {};
var fixture = document.getElementById('fixture');
var noop = function () {};
afterEach(function () {
fixture.innerHTML = '';
axe._tree = undefined;
axe._selectorData = undefined;
});
it('should timeout after 60s', function (done) {
var orig = window.setTimeout;
window.setTimeout = function (fn, to) {
if (to === 60000) {
assert.ok('timeout set');
fn();
} else { // ping timeout
return orig(fn, to);
}
return 'cats';
};
it('should timeout after 60s', function (done) {
var orig = window.setTimeout;
window.setTimeout = function (fn, to) {
if (to === 60000) {
assert.ok('timeout set');
fn();
} else { // ping timeout
return orig(fn, to);
}
return 'cats';
};
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
axe.utils.collectResultsFromFrames(context, {}, 'stuff', 'morestuff', noop,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.message.split(/: /)[0], 'Axe in frame timed out');
window.setTimeout = orig;
done();
});
});
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.collectResultsFromFrames(context, {}, 'stuff', 'morestuff', noop,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.message.split(/: /)[0], 'Axe in frame timed out');
window.setTimeout = orig;
done();
});
});
frame.id = 'level0';
frame.src = '../mock/frames/results-timeout.html';
fixture.appendChild(frame);
frame.id = 'level0';
frame.src = '../mock/frames/results-timeout.html';
fixture.appendChild(frame);
});
});
it('should override the timeout with `options.frameWaitTime`, if provided', function (done) {
var orig = window.setTimeout;
window.setTimeout = function (fn, to) {
if (to === 90000) {
assert.ok('timeout set');
fn();
} else { // ping timeout
return orig(fn, to);
}
return 'cats';
};
it('should override the timeout with `options.frameWaitTime`, if provided', function (done) {
var orig = window.setTimeout;
window.setTimeout = function (fn, to) {
if (to === 90000) {
assert.ok('timeout set');
fn();
} else { // ping timeout
return orig(fn, to);
}
return 'cats';
};
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
var params = { frameWaitTime: 90000 };
axe.utils.collectResultsFromFrames(context, params, 'stuff', 'morestuff', noop,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.message.split(/: /)[0], 'Axe in frame timed out');
window.setTimeout = orig;
done();
});
});
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
var params = { frameWaitTime: 90000 };
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.collectResultsFromFrames(context, params, 'stuff', 'morestuff', noop,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.message.split(/: /)[0], 'Axe in frame timed out');
window.setTimeout = orig;
done();
});
});
frame.id = 'level0';
frame.src = '../mock/frames/results-timeout.html';
fixture.appendChild(frame);
frame.id = 'level0';
frame.src = '../mock/frames/results-timeout.html';
fixture.appendChild(frame);
});
});

@@ -91,8 +95,9 @@ it('should not throw given a recursive iframe', function (done) {

var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.collectResultsFromFrames(context, {}, 'rules', 'morestuff', function () {
done();
}, function (e) {
assert.ok(false, e);
done();
});
assert.ok(false, e);
done();
});
});

@@ -106,21 +111,22 @@

it('returns errors send from the frame', function (done) {
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
axe.utils.collectResultsFromFrames(context, {}, 'command', 'params', noop,
function (err) {
it('returns errors send from the frame', function (done) {
var frame = document.createElement('iframe');
frame.addEventListener('load', function () {
var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.collectResultsFromFrames(context, {}, 'command', 'params', noop,
function (err) {
assert.instanceOf(err, Error);
assert.equal(err.message.split(/\n/)[0], 'error in axe.throw');
done();
});
assert.instanceOf(err, Error);
assert.equal(err.message.split(/\n/)[0], 'error in axe.throw');
done();
});
});
});
frame.id = 'level0';
frame.src = '../mock/frames/throwing.html';
fixture.appendChild(frame);
});
frame.id = 'level0';
frame.src = '../mock/frames/throwing.html';
fixture.appendChild(frame);
});
});

@@ -9,2 +9,4 @@ /*global DqElement */

fixture.innerHTML = '';
axe._tree = undefined;
axe._selectorData = undefined;
});

@@ -35,2 +37,3 @@

var div = document.createElement('div');
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var dqEl = new DqElement(div);

@@ -142,2 +145,3 @@

fixture.innerHTML = '<div id="foo" class="bar">Hello!</div>';
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var result = new DqElement(fixture.firstChild, {

@@ -144,0 +148,0 @@ absolutePaths: true

@@ -17,2 +17,28 @@ function createContentGetSelector() {

function makeNonunique(fixture) {
'use strict';
var nonUnique = '<div><div><div></div></div></div>';
fixture.innerHTML = '<main>' +
nonUnique + nonUnique + nonUnique +
'<div><div></div></div>';
var node = document.createElement('div');
var parent = fixture.querySelector('div:nth-child(4) > div');
parent.appendChild(node);
return node;
}
function makeNonuniqueLongAttributes(fixture) {
'use strict';
var nonUnique = '<div><div><div></div></div></div>';
fixture.innerHTML = '<main>' +
nonUnique + nonUnique + nonUnique +
'<div><div></div></div>';
var node = document.createElement('div');
node.setAttribute('data-att', 'ddfkjghlkdddfkjghlkdddfkjghlkdddfkjghlkd');
var parent = fixture.querySelector('div:nth-child(4) > div');
parent.appendChild(node);
return node;
}
describe('axe.utils.getSelector', function () {

@@ -26,2 +52,4 @@ 'use strict';

fixture.innerHTML = '';
axe._tree = undefined;
axe._selectorData = undefined;
});

@@ -36,7 +64,6 @@

fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '#fixture > div');
var result = document.querySelectorAll(sel);

@@ -51,7 +78,6 @@ assert.lengthOf(result, 1);

fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '#fixture > div');
var result = document.querySelectorAll(sel);

@@ -62,6 +88,7 @@ assert.lengthOf(result, 1);

it('should handle special characters', function () {
it('should handle special characters in IDs', function () {
var node = document.createElement('div');
node.id = 'monkeys#are.animals\\ok';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);

@@ -73,6 +100,7 @@ var result = document.querySelectorAll(axe.utils.getSelector(node));

it('should handle special characters in className', function () {
it('should handle special characters in classNames', function () {
var node = document.createElement('div');
node.className = '. bb-required';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);

@@ -93,2 +121,3 @@ var result = document.querySelectorAll(axe.utils.getSelector(node));

}
axe._tree = axe.utils.getFlattenedTree(document.documentElement);

@@ -100,6 +129,7 @@ var result = document.querySelectorAll(axe.utils.getSelector(expected));

it('should stop on unique ID', function () {
it('should use a unique ID', function () {
var node = document.createElement('div');
node.id = 'monkeys';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);

@@ -124,7 +154,7 @@ var sel = axe.utils.getSelector(node);

fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '#fixture > div:nth-child(2)');
assert.notInclude(sel, '#monkeys');
var result = document.querySelectorAll(sel);

@@ -143,6 +173,7 @@ assert.lengthOf(result, 1);

fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '#fixture > div.dogs.cats');
assert.equal(sel, '.dogs');

@@ -155,4 +186,244 @@ var result = document.querySelectorAll(sel);

it('should default to tagName and position if classes are not unique', function () {
it('should use classes if more unique than the tag', function () {
var node = document.createElement('p');
node.className = 'monkeys simian cats';
fixture.appendChild(node);
node = document.createElement('p');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '.dogs');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should NOT use classes if they are more common than the tag', function () {
var node = document.createElement('p');
node.className = 'dogs cats';
fixture.appendChild(node);
node = document.createElement('p');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.isTrue(sel.indexOf('.dogs') === -1);
assert.isTrue(sel.indexOf('p') === 0);
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use the most unique class', function () {
var node = document.createElement('div');
node.className = 'dogs';
fixture.appendChild(node);
node = document.createElement('div');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '.cats');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use the most unique class and not the unique attribute', function () {
var node = document.createElement('div');
node.className = 'dogs';
fixture.appendChild(node);
node = document.createElement('div');
node.className = 'dogs cats';
node.setAttribute('data-axe', 'hello');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '.cats');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use only a single unique attribute', function () {
var node = document.createElement('div');
node.setAttribute('data-thing', 'hello');
fixture.appendChild(node);
node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, 'div[data-axe="hello"]');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use three uncommon but not unique features', function () {
var node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
node.className = 'thing';
fixture.appendChild(node);
node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
node.className = 'thing';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
var clsIndex = sel.indexOf('.thing');
var attIndex = Math.min(sel.indexOf('[data-axe="hello"]'),
sel.indexOf('[data-thing="hello"]'));
assert.isTrue(clsIndex !== -1);
assert.isTrue(sel.indexOf('[data-axe="hello"]') !== -1);
assert.isTrue(sel.indexOf('[data-thing="hello"]') !== -1);
assert.isTrue(clsIndex < attIndex, 'classes first');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use only three uncommon but not unique features', function () {
var node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
node.setAttribute('data-thang', 'hello');
node.className = 'thing thang';
fixture.appendChild(node);
node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
node.setAttribute('data-thang', 'hello');
node.className = 'thing thang';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
var parts = sel.split('.');
parts = parts.reduce(function (val, item) {
var its = item.split('[');
return val.concat(its);
}, []).filter(function (item) {
return item !== '';
});
assert.equal(parts.length, 3);
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use only three uncommon but not unique classes', function () {
var node = document.createElement('div');
node.className = 'thing thang thug thick';
fixture.appendChild(node);
node = document.createElement('div');
node.className = 'thing thang thug thick';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
var parts = sel.split('.');
parts = parts.reduce(function (val, item) {
var its = item.split('[');
return val.concat(its);
}, []).filter(function (item) {
return item !== '';
});
assert.equal(parts.length, 3);
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should use only three uncommon but not unique attributes', function () {
var node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thug', 'hello');
node.setAttribute('data-thing', 'hello');
node.setAttribute('data-thang', 'hello');
fixture.appendChild(node);
node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
node.setAttribute('data-thang', 'hello');
node.setAttribute('data-thug', 'hello');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
var parts = sel.split('.');
parts = parts.reduce(function (val, item) {
var its = item.split('[');
return val.concat(its);
}, []).filter(function (item) {
return item !== '';
});
assert.equal(parts.length, 4);
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
});
it('should not use long attributes', function () {
var node = makeNonuniqueLongAttributes(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node, {});
assert.isTrue(sel.indexOf('data-att') === -1);
});
it('should use :root when not unique html element', function () {
// todo
var node = document.createElement('html');
node.setAttribute('lang', 'en');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(document.documentElement, {});
assert.equal(sel, ':root');
});
it('should use position if classes are not unique', function () {
var node = document.createElement('div');
node.className = 'monkeys simian';

@@ -164,6 +435,7 @@ fixture.appendChild(node);

fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '#fixture > div:nth-child(2)');
assert.equal(sel, '.monkeys.simian:nth-child(2)');

@@ -177,2 +449,4 @@ var result = document.querySelectorAll(sel);

it('should work on the documentElement', function () {
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(document.documentElement);

@@ -187,2 +461,4 @@ var result = document.querySelectorAll(sel);

document.documentElement.className = 'stuff and other things';
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(document.documentElement);

@@ -196,2 +472,4 @@ var result = document.querySelectorAll(sel);

it('should work on the body', function () {
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(document.body);

@@ -206,2 +484,4 @@ var result = document.querySelectorAll(sel);

var node = fixture.firstChild;
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);

@@ -220,2 +500,4 @@ var result = document.querySelectorAll(sel);

'</m:math>';
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var node = fixture.querySelector('m\\:ci');

@@ -228,31 +510,29 @@ var sel = axe.utils.getSelector(node);

it('shouldn\'t fail if the node\'s parentNode doesnt have children, somehow (Firefox bug)', function () {
var sel = axe.utils.getSelector({
nodeName: 'a',
classList: [],
getAttribute: function () { },
hasAttribute: function () { return false; },
parentNode: {
nodeName: 'b',
getAttribute: function () { },
hasAttribute: function () { return false; },
classList: []
}
it('should not use ignored attributes', function () {
var node = document.createElement('div');
var ignoredAttributes = [
'style',
'selected', 'checked',
'disabled', 'tabindex',
'aria-checked', 'aria-selected',
'aria-invalid', 'aria-activedescendant',
'aria-busy', 'aria-disabled', 'aria-expanded',
'aria-grabbed', 'aria-pressed', 'aria-valuenow'
];
ignoredAttributes.forEach(function (att) {
node.setAttribute(att, 'true');
});
assert.equal(sel, 'a');
});
it('should use role attributes', function () {
var node = document.createElement('div');
node.setAttribute('role', 'menuitem');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
assert.equal(
axe.utils.getSelector(node),
'#fixture > div[role="menuitem"]'
assert.isTrue(
axe.utils.getSelector(node).indexOf('[') === -1
);
});
it('should use href and src attributes', function () {
it('should use href and src attributes, shortened', function () {
var link = document.createElement('a');
link.setAttribute('href', '//deque.com/thang/');
fixture.appendChild(link);
link = document.createElement('a');
link.setAttribute('href', '//deque.com/about/');

@@ -262,80 +542,32 @@ fixture.appendChild(link);

var img = document.createElement('img');
img.setAttribute('src', '//deque.com/thang.png');
fixture.appendChild(img);
img = document.createElement('img');
img.setAttribute('src', '//deque.com/logo.png');
fixture.appendChild(img);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
assert.equal(
axe.utils.getSelector(link),
'#fixture > a[href$="about/"]'
'a[href$="about/"]'
);
assert.equal(
axe.utils.getSelector(img),
'#fixture > img[src$="logo.png"]'
'img[src$="logo.png"]'
);
});
it('should give use two features on the first element', function () {
it('should not generate universal selectors', function () {
var node = document.createElement('div');
node.setAttribute('role', 'menuitem');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
assert.equal(
axe.utils.getSelector(node),
'#fixture > div[role="menuitem"]'
'div[role="menuitem"]'
);
node.className = 'dqpl-btn-primary';
assert.equal(
axe.utils.getSelector(node),
'#fixture > [role="menuitem"].dqpl-btn-primary'
);
});
it('should give use one features on the subsequent elements', function () {
var span = document.createElement('span');
var node = document.createElement('div');
node.setAttribute('role', 'menuitem');
span.className = 'expand-icon';
node.appendChild(span);
fixture.appendChild(node);
assert.equal(
axe.utils.getSelector(span),
'[role="menuitem"] > span.expand-icon'
);
});
it('should prioritize uncommon tagNames', function () {
var node = document.createElement('button');
node.setAttribute('role', 'menuitem');
node.className = 'dqpl-btn-primary';
fixture.appendChild(node);
assert.equal(
axe.utils.getSelector(node),
'#fixture > button[role="menuitem"]'
);
});
it('should add [type] to input elements', function () {
var node = document.createElement('input');
node.type = 'password';
node.className = 'dqpl-textfield';
fixture.appendChild(node);
assert.equal(
axe.utils.getSelector(node),
'#fixture > input[type="password"].dqpl-textfield'
);
});
it('should use the name property', function () {
var node = document.createElement('input');
node.type = 'text';
node.name = 'username';
node.className = 'dqpl-textfield';
fixture.appendChild(node);
assert.equal(
axe.utils.getSelector(node),
'#fixture > input[type="text"][name="username"]'
);
});
it('no options: should work with shadow DOM', function () {

@@ -349,2 +581,4 @@ var shadEl;

makeShadowTreeGetSelector(fixture.firstChild);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');

@@ -365,2 +599,4 @@ assert.deepEqual(axe.utils.getSelector(shadEl), [

makeShadowTreeGetSelector(fixture.firstChild);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');

@@ -374,2 +610,22 @@ assert.deepEqual(axe.utils.getSelector(shadEl, { toRoot: true }), [

it('should correctly calculate unique selector when no discernable features', function () {
var node = makeNonunique(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node, {});
var mine = document.querySelector(sel);
assert.isTrue(mine === node);
});
it('should not traverse further up than required when no discernable features', function () {
var node = makeNonunique(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var top = fixture.querySelector('div:nth-child(4)');
var sel = axe.utils.getSelector(node, {});
sel = sel.substring(0, sel.indexOf(' >'));
var test = document.querySelector(sel);
assert.isTrue(test === top);
});
});

@@ -8,2 +8,4 @@ describe('axe.utils.sendCommandToFrame', function () {

fixture.innerHTML = '';
axe._tree = undefined;
axe._selectorData = undefined;
});

@@ -29,2 +31,3 @@

frame.addEventListener('load', function () {
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.sendCommandToFrame(frame, {}, function (result) {

@@ -86,3 +89,3 @@ assert.equal(result, null);

it('should respond once when no keepalive', function (done) {
var number = 2;
var number = 1;
var called = 0;

@@ -96,12 +99,9 @@ var frame = document.createElement('iframe');

if (called === number) {
clearTimeout(timer);
assert.isTrue(false);
assert.isTrue(true);
done();
} else {
throw new Error ('should not have been called');
}
}, assertNotCalled);
});
var timer = setTimeout(function () {
assert.isTrue(true);
done();
}, 150);

@@ -108,0 +108,0 @@ frame.id = 'level0';

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc