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.3 to 3.0.0

doc/rule-descriptions.nl.md

2

axe.d.ts

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

// Type definitions for axe-core 3.0.0-beta.3
// Type definitions for axe-core 3.0.0
// 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.3",
"version": "3.0.0",
"contributors": [

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

"devDependencies": {}
}
}

@@ -0,1 +1,47 @@

# 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"></a>
# [3.0.0](https://github.com/dequelabs/axe-core/compare/v3.0.0-beta.2...v3.0.0) (2018-03-19)
### Bug Fixes
* Allow exclusion of Shadow DOM content ([cc66eb2](https://github.com/dequelabs/axe-core/commit/cc66eb2))
* Avoid flatTree memory leak ([a902e80](https://github.com/dequelabs/axe-core/commit/a902e80))
* **main-is-top-level:** Rename check to landmark-is-top-level for greater reuse ([b405af1](https://github.com/dequelabs/axe-core/commit/b405af1))
* Avoid timing issue with axe cleanup method ([24ea6a7](https://github.com/dequelabs/axe-core/commit/24ea6a7))
* correct misnamed check ([1e709e0](https://github.com/dequelabs/axe-core/commit/1e709e0))
* Correct runOnly object for TypeScript definition ([571e984](https://github.com/dequelabs/axe-core/commit/571e984))
* **has-at-least-one-main:** Rename check to page-has-main, for reusability ([9a9c283](https://github.com/dequelabs/axe-core/commit/9a9c283))
* **has-no-more-than-one-main:** Rename check to page-no-duplicate for better reuse ([e75324b](https://github.com/dequelabs/axe-core/commit/e75324b))
* **region:** Ignore forms without accessible name as landmarks ([8ad2718](https://github.com/dequelabs/axe-core/commit/8ad2718))
* **rule:** skip-link rule doesn't decode URI encoded href's ([818b5cd](https://github.com/dequelabs/axe-core/commit/818b5cd))
* Ensure all rules have a category tag ([d61e67d](https://github.com/dequelabs/axe-core/commit/d61e67d))
* make getSelector work with URIs that cannot be shortened ([a113555](https://github.com/dequelabs/axe-core/commit/a113555))
### Features
* Make aria-level required with role=heading [#740](https://github.com/dequelabs/axe-core/issues/740) ([64b743f](https://github.com/dequelabs/axe-core/commit/64b743f))
* **aria:** allow DPUB ARIA roles ([70b48f6](https://github.com/dequelabs/axe-core/commit/70b48f6))
* **frame-tested:** Use this new rule to test if all frames are available, instead of axe.log ([83cd17d](https://github.com/dequelabs/axe-core/commit/83cd17d))
* **landmark-contentinfo-is-top-level:** add rule ensuring top level contentinfo ([5692e7d](https://github.com/dequelabs/axe-core/commit/5692e7d))
* **landmark-no-more-than-one-banner:** add rule ensuring no more than one banner ([6617800](https://github.com/dequelabs/axe-core/commit/6617800))
* **landmark-no-more-than-one-contentinfo:** add rule ensuring no more than one contentinfo ([82217ef](https://github.com/dequelabs/axe-core/commit/82217ef))
* **page-has-heading-one:** Added new best-practice rule ([cb8f261](https://github.com/dequelabs/axe-core/commit/cb8f261))
* **rules:** add new rule aria-dpub-role-fallback ([9470c02](https://github.com/dequelabs/axe-core/commit/9470c02))
* Make options.runOnly more forgiving about plurality ([fa81f9d](https://github.com/dequelabs/axe-core/commit/fa81f9d))
* Translated all 3.0 rules to Japanese ([3862e7e](https://github.com/dequelabs/axe-core/commit/3862e7e))
### BREAKING CHANGES
* Incorrect use of runOnly now throws errors
* **main-is-top-level:** The check main-is-top-level is no longer available
* **has-at-least-one-main:** Original has-at-least-one-main check is no longer available
<a name="3.0.0-beta.3"></a>

@@ -139,24 +185,2 @@ # [3.0.0-beta.3](https://github.com/dequelabs/axe-core/compare/v3.0.0-beta.2...v3.0.0-beta.3) (2018-03-08)

<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>

@@ -163,0 +187,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)

@@ -122,6 +122,6 @@ # aXe Javascript Accessibility API

[
{ ruleId: "area-alt", description: "Checks the <area> elements of image…" },
{ ruleId: "aria-allowed-attr", description: "Checks all attributes that start…" },
{ ruleId: "aria-required-attr", description: "Checks all elements that contain…" },
{ ruleId: "area-alt", description: "Checks the <area> elements of image…" },
{ ruleId: "aria-allowed-attr", description: "Checks all attributes that start…" },
{ ruleId: "aria-required-attr", description: "Checks all elements that contain…" },
]

@@ -156,30 +156,30 @@ ```

* `configurationOptions` - Options object; where the valid name, value pairs are:
* `branding` - mixed(optional) Used to set the branding of the helpUrls
* `brand` - string(optional) sets the brand string - default "axe"
* `application` - string(optional) sets the application string - default "axeAPI"
* `reporter` - Used to set the output format that the axe.run function will pass to the callback function
* `v1` to use the previous version's format: `axe.configure({ reporter: "v1" });`
* `v2` to use the current version's format: `axe.configure({ reporter: "v2" });`
* `checks` - Used to add checks to the list of checks used by rules, or to override the properties of existing checks
* The checks attribute is an array of check objects
* Each check object can contain the following attributes
* `id` - string(required). This uniquely identifies the check. If the check already exists, this will result in any supplied check properties being overridden. The properties below that are marked required if new are optional when the check is being overridden.
* `evaluate` - function(required for new). This is the function that implements the check's functionality.
* `after` - function(optional). This is the function that gets called for checks that operate on a page-level basis, to process the results from the iframes.
* `options` - mixed(optional). This is the options structure that is passed to the evaluate function and is intended to be used to configure checks. It is the most common property that is intended to be overridden for existing checks.
* `enabled` - boolean(optional, default `true`). This is used to indicate whether the check is on or off by default. Checks that are off are not evaluated, even when included in a rule. Overriding this is a common way to disable a particular check across multiple rules.
* `rules` - Used to add rules to the existing set of rules, or to override the properties of existing rules
* The rules attribute is an Array of rule objects
* each rule object can contain the following attributes
* `id` - string(required). This uniquely identifies the rule. If the rule already exists, it will be overridden with any of the attributes supplied. The attributes below that are marked required, are only required for new rules.
* `selector` - string(optional, default `*`). A CSS selector used to identify the elements that are passed into the rule for evaluation.
* `excludeHidden` - boolean(optional, default `true`). This indicates whether elements that are hidden from all users are to be passed into the rule for evaluation.
* `enabled` - boolean(optional, default `true`). Whether the rule is turned on. This is a common attribute for overriding.
* `pageLevel` - boolean(optional, default `false`). When set to true, this rule is only applied when the entire page is tested. Results from nodes on different frames are combined into a single result. See [page level rules](#page-level-rules).
* `any` - array(optional, default `[]`). This is the list of checks that must all "pass" or else there is a violation.
* `all` - array(optional, default `[]`). This is the list of checks that, if any "fails", will generate a violation.
* `none` - array(optional, default `[]`). This is a list of the checks that, if none "pass", will generate a violation.
* `tags` - array(optional, default `[]`). A list if the tags that "classify" the rule. In practice, you must supply some valid tags or the default evaluation will not invoke the rule. The convention is to include the standard (WCAG 2 and/or section 508), the WCAG 2 level, Section 508 paragraph, and the WCAG 2 success criteria. Tags are constructed by converting all letters to lower case, removing spaces and periods and concatinating the result. E.g. WCAG 2 A success criteria 1.1.1 would become ["wcag2a", "wcag111"]
* `matches` - string(optional, default `*`). A filtering CSS selector that will exclude elements that do not match the CSS selector.
* `disableOtherRules` - Disables all rules not included in the `rules` property.
* `branding` - mixed(optional) Used to set the branding of the helpUrls
* `brand` - string(optional) sets the brand string - default "axe"
* `application` - string(optional) sets the application string - default "axeAPI"
* `reporter` - Used to set the output format that the axe.run function will pass to the callback function
* `v1` to use the previous version's format: `axe.configure({ reporter: "v1" });`
* `v2` to use the current version's format: `axe.configure({ reporter: "v2" });`
* `checks` - Used to add checks to the list of checks used by rules, or to override the properties of existing checks
* The checks attribute is an array of check objects
* Each check object can contain the following attributes
* `id` - string(required). This uniquely identifies the check. If the check already exists, this will result in any supplied check properties being overridden. The properties below that are marked required if new are optional when the check is being overridden.
* `evaluate` - function(required for new). This is the function that implements the check's functionality.
* `after` - function(optional). This is the function that gets called for checks that operate on a page-level basis, to process the results from the iframes.
* `options` - mixed(optional). This is the options structure that is passed to the evaluate function and is intended to be used to configure checks. It is the most common property that is intended to be overridden for existing checks.
* `enabled` - boolean(optional, default `true`). This is used to indicate whether the check is on or off by default. Checks that are off are not evaluated, even when included in a rule. Overriding this is a common way to disable a particular check across multiple rules.
* `rules` - Used to add rules to the existing set of rules, or to override the properties of existing rules
* The rules attribute is an Array of rule objects
* each rule object can contain the following attributes
* `id` - string(required). This uniquely identifies the rule. If the rule already exists, it will be overridden with any of the attributes supplied. The attributes below that are marked required, are only required for new rules.
* `selector` - string(optional, default `*`). A CSS selector used to identify the elements that are passed into the rule for evaluation.
* `excludeHidden` - boolean(optional, default `true`). This indicates whether elements that are hidden from all users are to be passed into the rule for evaluation.
* `enabled` - boolean(optional, default `true`). Whether the rule is turned on. This is a common attribute for overriding.
* `pageLevel` - boolean(optional, default `false`). When set to true, this rule is only applied when the entire page is tested. Results from nodes on different frames are combined into a single result. See [page level rules](#page-level-rules).
* `any` - array(optional, default `[]`). This is the list of checks that must all "pass" or else there is a violation.
* `all` - array(optional, default `[]`). This is the list of checks that, if any "fails", will generate a violation.
* `none` - array(optional, default `[]`). This is a list of the checks that, if none "pass", will generate a violation.
* `tags` - array(optional, default `[]`). A list if the tags that "classify" the rule. In practice, you must supply some valid tags or the default evaluation will not invoke the rule. The convention is to include the standard (WCAG 2 and/or section 508), the WCAG 2 level, Section 508 paragraph, and the WCAG 2 success criteria. Tags are constructed by converting all letters to lower case, removing spaces and periods and concatinating the result. E.g. WCAG 2 A success criteria 1.1.1 would become ["wcag2a", "wcag111"]
* `matches` - string(optional, default `*`). A filtering CSS selector that will exclude elements that do not match the CSS selector.
* `disableOtherRules` - Disables all rules not included in the `rules` property.

@@ -260,6 +260,6 @@ **Returns:** Nothing

* An array of arrays of CSS selectors
* If the nested array contains a single string, that string is the CSS selector
* If the nested array contains multiple strings
* The last string is the final CSS selector
* All other's are the nested structure of iframes inside the document
* If the nested array contains a single string, that string is the CSS selector
* If the nested array contains multiple strings
* The last string is the final CSS selector
* All other's are the nested structure of iframes inside the document

@@ -274,4 +274,4 @@ In most cases, the component arrays will contain only one CSS selector. Multiple CSS selectors are only required if you want to include or exclude regions of a page that are inside iframes (or iframes within iframes within iframes). In this case, the first n-1 selectors are selectors that select the iframe(s) and the nth selector, selects the region(s) within the iframe.

{
include: $fixture[0],
exclude: $fixture[0].firstChild
include: $fixture[0],
exclude: $fixture[0].firstChild
}

@@ -283,4 +283,4 @@ ```

{
include: [['#fix']],
exclude: [['#fix div']]
include: [['#fix']],
exclude: [['#fix div']]
}

@@ -292,3 +292,3 @@ ```

{
exclude: [['.exclude1'], ['.exclude2']]
exclude: [['.exclude1'], ['.exclude2']]
}

@@ -298,28 +298,28 @@ ```

```javascript
{
include: [['#frame', '#fix']]
}
```
```javascript
{
include: [['#frame', '#fix']]
}
```
5. Include the element with the ID of `fix`, within the iframe with id `frame2`, within the iframe with id `frame1`
```javascript
{
include: [['#frame1', '#frame2', '#fix']]
}
```
```javascript
{
include: [['#frame1', '#frame2', '#fix']]
}
```
6. Include the following:
* The element with the ID of `fix`, within the iframe with id `frame2`, within the iframe with id `frame1`
* The element with id `header`
* All links
* The element with the ID of `fix`, within the iframe with id `frame2`, within the iframe with id `frame1`
* The element with id `header`
* All links
```javascript
{
include: [
['#header'],
['a'],
['#frame1', '#frame2', '#fix']
]
}
```
```javascript
{
include: [
['#header'],
['a'],
['#frame1', '#frame2', '#fix']
]
}
```

@@ -368,5 +368,5 @@

{
runOnly: {
type: "tag",
values: ["wcag2a"]
runOnly: {
type: "tag",
values: ["wcag2a"]
}

@@ -380,9 +380,17 @@ }

{
runOnly: {
type: "tag",
values: ["wcag2a", "wcag2aa"]
}
runOnly: {
type: "tag",
values: ["wcag2a", "wcag2aa"]
}
}
```
Alternatively, runOnly can be passed an array of tags:
```javascript
{
runOnly: ["wcag2a", "wcag2aa"]
}
```
2. Run only a specified list of Rules

@@ -394,6 +402,6 @@

{
runOnly: {
type: "rule",
values: [ "ruleId1", "ruleId2", "ruleId3" ]
}
runOnly: {
type: "rule",
values: [ "ruleId1", "ruleId2", "ruleId3" ]
}
}

@@ -409,6 +417,6 @@ ```

{
"rules": {
"color-contrast": { enabled: false },
"valid-lang": { enabled: false }
}
"rules": {
"color-contrast": { enabled: false },
"valid-lang": { enabled: false }
}
}

@@ -424,10 +432,10 @@ ```

{
runOnly: {
type: "tag",
values: ["wcag2a"]
},
"rules": {
"color-contrast": { enabled: true },
"valid-lang": { enabled: false }
}
runOnly: {
type: "tag",
values: ["wcag2a"]
},
"rules": {
"color-contrast": { enabled: true },
"valid-lang": { enabled: false }
}
}

@@ -443,9 +451,9 @@ ```

{
runOnly: {
type: 'tags',
values: {
include: ['wcag2a', 'wcag2aa'],
exclude: ['experimental']
}
}
runOnly: {
type: 'tags',
values: {
include: ['wcag2a', 'wcag2aa'],
exclude: ['experimental']
}
}
}

@@ -540,4 +548,4 @@ ```

axe.run(document, function(err, results) {
if (err) throw err;
console.log(results);
if (err) throw err;
console.log(results);
});

@@ -549,11 +557,11 @@ ```

* `passes[0]`
...
* `help` - `"Elements must have sufficient color contrast"`
* `helpUrl` - `"https://dequeuniversity.com/courses/html-css/visual-layout/color-contrast"`
* `id` - `"color-contrast"`
* `nodes`
* `target[0]` - `"#js_off-canvas-wrap > .inner-wrap >.kinja-title.proxima.js_kinja-title-desktop"`
...
* `help` - `"Elements must have sufficient color contrast"`
* `helpUrl` - `"https://dequeuniversity.com/courses/html-css/visual-layout/color-contrast"`
* `id` - `"color-contrast"`
* `nodes`
* `target[0]` - `"#js_off-canvas-wrap > .inner-wrap >.kinja-title.proxima.js_kinja-title-desktop"`
* `passes[1]`
...
...

@@ -563,8 +571,8 @@ ###### `violations`

* `violations[0]`
* `help` - `"<button> elements must have alternate text"`
* `helpUrl` - `"https://dequeuniversity.com/courses/html-css/forms/form-labels#id84_example_button"`
* `id` - `"button-name"`
* `nodes`
* `target[0]` - `"post_5919997 > .row.content-wrapper > .column > span > iframe"`
* `target[1]` - `"#u_0_1 > .pluginConnectButton > .pluginButtonImage > button"`
* `help` - `"<button> elements must have alternate text"`
* `helpUrl` - `"https://dequeuniversity.com/courses/html-css/forms/form-labels#id84_example_button"`
* `id` - `"button-name"`
* `nodes`
* `target[0]` - `"post_5919997 > .row.content-wrapper > .column > span > iframe"`
* `target[1]` - `"#u_0_1 > .pluginConnectButton > .pluginButtonImage > button"`

@@ -599,9 +607,9 @@ * `violations[1]` ...

axe.run(document, {
rules: {
"heading-order": { enabled: true },
"label-title-only": { enabled: true }
}
rules: {
"heading-order": { enabled: true },
"label-title-only": { enabled: true }
}
}, function(err, results) {
if (err) throw err;
console.log(results);
if (err) throw err;
console.log(results);
});

@@ -642,3 +650,3 @@ ```

```
axe.cleanup(resolve, reject)
axe.cleanup(resolve, reject)
```

@@ -758,3 +766,3 @@

{
resultTypes: ['violations']
resultTypes: ['violations']
}

@@ -761,0 +769,0 @@ ```

@@ -5,22 +5,28 @@ # Projects that use axe-core

## Deque Projects
1. [WorldSpace Attest](https://www.deque.com/products/worldspace-attest/)
1. [WorldSpace Assure](https://www.deque.com/products/worldspace-assure/)
1. [WorldSpace Comply](https://www.deque.com/products/worldspace-comply/)
1. [aXe Chrome plugin](https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd)
1. [aXe Chrome Extension](https://chrome.google.com/webstore/detail/axe/lhdoppojpmngadmnindnejefpokejbdd)
1. [aXe Firefox Extension](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/)
1. [axe-cli](https://www.npmjs.com/package/axe-cli)
1. [axe-webdriverjs](https://www.npmjs.com/package/axe-webdriverjs)
1. [ember-a11y-testing](https://www.npmjs.com/package/ember-a11y-testing)
1. [axe-firefox-devtools](https://github.com/dequelabs/axe-firefox-devtools) and on the [Firefox extension page](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/)
1. [grunt-axe-webdriver](https://www.npmjs.com/package/grunt-axe-webdriver)
1. [react-axe](https://github.com/dequelabs/react-axe)
1. [axe-matchers (Ruby)](https://github.com/dequelabs/axe-matchers)
1. [axe-selenium-java](https://github.com/dequelabs/axe-selenium-java)
1. [a11yChromePlugin - not the official Chrome plugin source code](https://github.com/ptrstpp950/a11yChromePlugin)
1. [grunt-axe-webdriver](https://www.npmjs.com/package/grunt-axe-webdriver)
1. [R-Spec and Cucumber](https://github.com/dequelabs/axe-matchers)
## Community Projects
1. [gulp-axe-webdriver](https://github.com/felixzapata/gulp-axe-webdriver)
1. [Lighthouse](https://github.com/GoogleChrome/lighthouse)
1. [Sonarwhal](https://sonarwhal.com/)
1. [Web Accessibility Checker for Visual Studio](https://visualstudiogallery.msdn.microsoft.com/3aabefab-1681-4fea-8f95-6a62e2f0f1ec)
1. [Ace, by DAISY](https://daisy.github.io/ace)
1. [aXe audit runner for CrawlKit](https://github.com/crawlkit/runner-axe)
1. [Web Accessibility Checker for Visual Studio](https://visualstudiogallery.msdn.microsoft.com/3aabefab-1681-4fea-8f95-6a62e2f0f1ec)
1. [ReactJS Accessibility Checker](https://github.com/dylanb/react-axe) (react-axe)
1. [Vorlon.js Remote Debugger](https://github.com/MicrosoftDX/Vorlonjs)
1. [Selenium IDE aXe Extension](https://github.com/bkardell/selenium-ide-axe)
1. [gulp-axe-webdriver](https://github.com/felixzapata/gulp-axe-webdriver)
1. [Lighthouse](https://github.com/GoogleChrome/lighthouse)
1. [Axegrinder](https://github.com/claflamme/axegrinder)
1. [Ghost-Axe](https://www.npmjs.com/package/ghost-axe)
1. [ember-a11y-testing](https://www.npmjs.com/package/ember-a11y-testing)
1. [Protractor accessibility plugin](https://github.com/angular/protractor-accessibility-plugin)

@@ -30,6 +36,8 @@ 1. [Storybook accessibility addon](https://github.com/jbovenschen/storybook-addon-a11y)

1. [Protractor-axe-report Plugin](https://github.com/E1Edatatracker/protractor-axe-report-plugin)
1. [Jest-axe](https://github.com/nickcolley/jest-axe)
1. [Rocket Validator](https://rocketvalidator.com)
1. [aXe Reports](https://github.com/louis-reed/axe-reports)
1. [aXe WebdriverIO](https://github.com/snagi/axe-webdriverio)
1. [aXe-TestCafe](https://github.com/helen-dikareva/axe-testcafe)
1. [Web Audit University of Nebraska-Lincoln](https://webaudit.unl.edu/)
1. [Ace, by DAISY](https://daisy.github.io/ace)
1. [Vorlon.js Remote Debugger](https://github.com/MicrosoftDX/Vorlonjs)

@@ -26,7 +26,7 @@ | Rule ID | Description | Tags | Enabled by default |

| focus-order-semantics | Ensures elements in the focus order have an appropriate role | cat.keyboard, best-practice, experimental | true |
| frame-tested | Ensures &lt;iframe&gt; and &lt;frame&gt; elements contain the axe-core script | wcag2a, wcag2aa, best-practice | true |
| frame-tested | Ensures &lt;iframe&gt; and &lt;frame&gt; elements contain the axe-core script | cat.structure, review-item | true |
| frame-title-unique | Ensures &lt;iframe&gt; and &lt;frame&gt; elements contain a unique title attribute | cat.text-alternatives, best-practice | true |
| frame-title | Ensures &lt;iframe&gt; and &lt;frame&gt; elements contain a non-empty title attribute | cat.text-alternatives, wcag2a, wcag241, section508, section508.22.i | true |
| heading-order | Ensures the order of headings is semantically correct | cat.semantics, best-practice | true |
| hidden-content | Informs users about hidden content. | experimental, review-item | true |
| hidden-content | Informs users about hidden content. | cat.structure, experimental, review-item | true |
| html-has-lang | Ensures every HTML document has a lang attribute | cat.language, wcag2a, wcag311 | true |

@@ -39,8 +39,8 @@ | html-lang-valid | Ensures the lang attribute of the &lt;html&gt; element has a valid value | cat.language, wcag2a, wcag311 | true |

| label | Ensures every form element has a label | cat.forms, wcag2a, wcag332, wcag131, section508, section508.22.n | true |
| landmark-banner-is-top-level | The banner landmark should not be contained in another landmark | best-practice | true |
| landmark-contentinfo-is-top-level | The contentinfo landmark should not be contained in another landmark | best-practice | true |
| landmark-main-is-top-level | The main landmark should not be contained in another landmark | best-practice | true |
| landmark-no-duplicate-banner | Ensures the document has no more than one banner landmark | best-practice | true |
| landmark-no-duplicate-contentinfo | Ensures the document has no more than one contentinfo landmark | best-practice | true |
| landmark-one-main | Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one | best-practice | true |
| landmark-banner-is-top-level | The banner landmark should not be contained in another landmark | cat.semantics, best-practice | true |
| landmark-contentinfo-is-top-level | The contentinfo landmark should not be contained in another landmark | cat.semantics, best-practice | true |
| landmark-main-is-top-level | The main landmark should not be contained in another landmark | cat.semantics, best-practice | true |
| landmark-no-duplicate-banner | Ensures the document has no more than one banner landmark | cat.semantics, best-practice | true |
| landmark-no-duplicate-contentinfo | Ensures the document has no more than one contentinfo landmark | cat.semantics, best-practice | true |
| landmark-one-main | Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one | cat.semantics, best-practice | true |
| layout-table | Ensures presentational &lt;table&gt; elements do not use &lt;th&gt;, &lt;caption&gt; elements or the summary attribute | cat.semantics, wcag2a, wcag131 | true |

@@ -57,3 +57,3 @@ | link-in-text-block | Links can be distinguished without relying on color | cat.color, experimental, wcag2a, wcag141 | true |

| p-as-heading | Ensure p elements are not used to style headings | cat.semantics, wcag2a, wcag131, experimental | true |
| page-has-heading-one | Ensure that the page, or at least one of its frames contains a level-one heading | best-practice | true |
| page-has-heading-one | Ensure that the page, or at least one of its frames contains a level-one heading | cat.semantics, best-practice | true |
| radiogroup | Ensures related &lt;input type=&quot;radio&quot;&gt; elements have a group and that the group designation is consistent | cat.forms, best-practice | true |

@@ -60,0 +60,0 @@ | region | Ensures all content is contained within a landmark region | cat.keyboard, best-practice | true |

@@ -16,3 +16,3 @@ /* global dom */

if (fragment && fragment.charAt(0) === '#') {
fragment = fragment.substring(1);
fragment = decodeURIComponent(fragment.substring(1));

@@ -19,0 +19,0 @@ let candidate = document.getElementById(fragment);

@@ -145,5 +145,4 @@ /*global Rule, Check, RuleResult, commons: true */

'use strict';
this.validateOptions(options);
this.normalizeOptions(options);
axe._tree = axe.utils.getFlattenedTree(document.documentElement); //cache the flattened tree
axe._selectCache = [];

@@ -201,2 +200,6 @@ var q = axe.utils.queue();

var rule = axe.utils.findBy(rules, 'id', ruleResult.id);
if (!rule) {
// If you see this, you're probably running the Mocha tests with the aXe extension installed
throw new Error('Result for unknown rule. You may be running mismatch aXe-core versions');
}

@@ -222,3 +225,4 @@ return rule.after(ruleResult, options);

*/
Audit.prototype.validateOptions = function (options) {
Audit.prototype.normalizeOptions = function (options) {
/* eslint max-statements: ["error", 22] */
'use strict';

@@ -229,7 +233,22 @@ var audit = this;

if (typeof options.runOnly === 'object') {
var only = options.runOnly;
if (Array.isArray(options.runOnly)) {
options.runOnly = {
type: 'tag',
values: options.runOnly
};
}
const only = options.runOnly;
if (only.value && !only.values) {
only.values = only.value;
delete only.value;
}
if (!Array.isArray(only.values) || only.values.length === 0) {
throw new Error('runOnly.values must be a non-empty array');
}
// Check if every value in options.runOnly is a known rule ID
if (only.type === 'rule' && Array.isArray(only.value)) {
only.value.forEach(function (ruleId) {
if (['rule', 'rules'].includes(only.type)) {
only.type = 'rule';
only.values.forEach(function (ruleId) {
if (!audit.getRule(ruleId)) {

@@ -241,21 +260,16 @@ throw new Error('unknown rule `' + ruleId + '` in options.runOnly');

// Validate 'tags' (e.g. anything not 'rule')
} else if (Array.isArray(only.value) && only.value.length > 0) {
var tags = [].concat(only.value);
} else if (['tag', 'tags', undefined].includes(only.type)) {
only.type = 'tag';
const unmatchedTags = audit.rules.reduce((unmatchedTags, rule) => {
return (unmatchedTags.length
? unmatchedTags.filter(tag => !rule.tags.includes(tag))
: unmatchedTags
);
}, only.values);
audit.rules.forEach(function (rule) {
var tagPos, i, l;
if (!tags) {
return;
}
// Remove any known tag
for (i = 0, l = rule.tags.length; i < l; i++) {
tagPos = tags.indexOf(rule.tags[i]);
if (tagPos !== -1) {
tags.splice(tagPos, 1);
}
}
});
if (tags.length !== 0) {
throw new Error('could not find tags `' + tags.join('`, `') + '`');
if (unmatchedTags.length !== 0) {
throw new Error('Could not find tags `' + unmatchedTags.join('`, `') + '`');
}
} else {
throw new Error(`Unknown runOnly type '${only.type}'`);
}

@@ -262,0 +276,0 @@ }

@@ -78,3 +78,2 @@ /*exported Context */

if (context && typeof context === 'object' || context instanceof NodeList) {
if (context instanceof Node) {

@@ -134,3 +133,3 @@ return {

result = result.concat(nodeList.map((node) => {
return axe.utils.getFlattenedTree(node)[0];
return axe.utils.getNodeFromTree(context.flatTree[0], node);
}));

@@ -146,8 +145,11 @@ break;

result = result.concat(nodeList.map((node) => {
return axe.utils.getFlattenedTree(node)[0];
return axe.utils.getNodeFromTree(context.flatTree[0], node);
}));
}
} else if (item instanceof Node) {
result.push(axe.utils.getFlattenedTree(item)[0]);
if (item.documentElement instanceof Node) {
result.push(context.flatTree[0]);
} else {
result.push(axe.utils.getNodeFromTree(context.flatTree[0], item));
}
}

@@ -187,2 +189,21 @@ }

/**
* For a context-like object, find its shared root node
*/
function getRootNode ({ include, exclude }) {
const selectors = Array.from(include).concat(Array.from(exclude));
// Find the first Element.ownerDocument or Document
const localDocument = selectors.reduce((result, item) => {
if (result) {
return result;
} else if (item instanceof Element) {
return item.ownerDocument
} else if (item instanceof Document) {
return item
}
}, null);
return (localDocument || document).documentElement;
}
/**
* Holds context of includes, excludes and frames for analysis.

@@ -208,5 +229,4 @@ *

function Context(spec) {
/* eslint max-statements:["error",19], no-unused-vars:0 */
/* eslint max-statements:["error",22], no-unused-vars:0 */
'use strict';
var self = this;

@@ -218,2 +238,5 @@ this.frames = [];

spec = normalizeContext(spec);
//cache the flattened tree
this.flatTree = axe.utils.getFlattenedTree(getRootNode(spec));
this.exclude = spec.exclude;

@@ -225,5 +248,5 @@ this.include = spec.include;

axe.utils.select('frame, iframe', this).forEach(function (frame) {
if (isNodeInContext(frame, self)) {
pushUniqueFrame(self.frames, frame.actualNode);
axe.utils.select('frame, iframe', this).forEach((frame) => {
if (isNodeInContext(frame, this)) {
pushUniqueFrame(this.frames, frame.actualNode);
}

@@ -230,0 +253,0 @@ });

@@ -21,3 +21,7 @@ /*global Audit, runRules, cleanupPlugins */

case 'rules':
return runRules(context, options, resolve, reject);
return runRules(context, options, function (results, cleanup) {
resolve(results);
// Cleanup AFTER resolve so that selectors can be generated
cleanup();
}, reject);
case 'cleanup-plugin':

@@ -24,0 +28,0 @@ return cleanupPlugins(resolve, reject);

/*global Context */
/*exported runRules */
// Clean up after resolve / reject
function cleanup () {
axe._tree = undefined;
axe._selectorData = undefined;
}
/**

@@ -9,3 +15,4 @@ * Starts analysis on the current document and its subframes

* @param {Array} options Optional RuleOptions
* @param {Function} callback The function to invoke when analysis is complete; receives an array of `RuleResult`s
* @param {Function} resolve Called when done running rules, receives ([results : Object], cleanup : Function)
* @param {Function} reject Called when execution failed, receives (err : Error)
*/

@@ -16,3 +23,6 @@ function runRules(context, options, resolve, reject) {

context = new Context(context);
axe._tree = context.flatTree;
axe._selectorData = axe.utils.getSelectorData(context.flatTree);
} catch (e) {
cleanup();
return reject(e);

@@ -50,6 +60,4 @@ }

// Add wrapper object so that we may use the same "merge" function for results from inside and outside frames
var results = axe.utils.mergeResults(data.map(function (d) {
return {
results: d
};
var results = axe.utils.mergeResults(data.map(function (results) {
return { results };
}));

@@ -65,12 +73,17 @@

try {
resolve(results);
resolve(results, cleanup);
} catch(e) {
cleanup();
axe.log(e);
}
} catch (e) {
cleanup();
reject(e);
}
}).catch(reject);
}).catch((e) => {
cleanup();
reject(e);
});
}
axe._runRules = runRules;

@@ -115,33 +115,33 @@ /* global Promise */

axe._runRules(context, options, function (rawResults) {
let respond = function (results) {
try {
callback(null, results);
} catch(e) {
axe.log(e);
}
resolve(results);
};
if (options.performanceTimer) {
axe.utils.performanceTimer.end();
}
try {
let reporter = axe.getReporter(options.reporter);
let results = reporter(rawResults, options, respond);
axe._selectorData = undefined;
axe._tree = undefined;
if (results !== undefined) {
respond(results);
}
} catch (err) {
callback(err);
reject(err);
}
}, function (err) {
callback(err);
reject(err);
});
return p;
};
axe._runRules(context, options, function (rawResults, cleanup) {
let respond = function (results) {
cleanup();
try {
callback(null, results);
} catch(e) {
axe.log(e);
}
resolve(results);
};
if (options.performanceTimer) {
axe.utils.performanceTimer.end();
}
try {
let reporter = axe.getReporter(options.reporter);
let results = reporter(rawResults, options, respond);
if (results !== undefined) {
respond(results);
}
} catch (err) {
cleanup();
callback(err);
reject(err);
}
}, function (err) {
callback(err);
reject(err);
});
return p;
};

@@ -25,8 +25,13 @@ const escapeSelector = axe.utils.escapeSelector;

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;
}
let friendly = axe.utils.getFriendlyUriEnd(node.getAttribute(name));
if (friendly) {
let value = encodeURI(friendly);
if (value) {
atnv = escapeSelector(at.name) + '$="' + value + '"';
} else {
return;
}
} else {
atnv = escapeSelector(at.name) + '="' + node.getAttribute(name) + '"';
}
} else {

@@ -306,7 +311,5 @@ atnv = escapeSelector(name) + '="' + escapeSelector(at.value) + '"';

if (!axe._selectorData) {
axe._selectorData = axe.utils.getSelectorData(axe._tree);
throw new Error('Expect axe._selectorData to be set up');
}
const {
toRoot = false
} = options;
const { toRoot = false } = options;
let selector;

@@ -313,0 +316,0 @@ let similar;

@@ -5,3 +5,7 @@ {

"matches": "inserted-into-focus-order-matches.js",
"tags": ["cat.keyboard", "best-practice", "experimental"],
"tags": [
"cat.keyboard",
"best-practice",
"experimental"
],
"metadata": {

@@ -8,0 +12,0 @@ "description": "Ensures elements in the focus order have an appropriate role",

@@ -5,5 +5,4 @@ {

"tags": [
"wcag2a",
"wcag2aa",
"best-practice"
"cat.structure",
"review-item"
],

@@ -10,0 +9,0 @@ "metadata": {

@@ -6,2 +6,3 @@ {

"tags": [
"cat.structure",
"experimental",

@@ -8,0 +9,0 @@ "review-item"

@@ -6,2 +6,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -8,0 +9,0 @@ ],

@@ -6,2 +6,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -8,0 +9,0 @@ ],

@@ -5,3 +5,4 @@ {

"tags": [
"best-practice"
"cat.semantics",
"best-practice"
],

@@ -8,0 +9,0 @@ "metadata": {

@@ -5,2 +5,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -7,0 +8,0 @@ ],

@@ -5,2 +5,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -7,0 +8,0 @@ ],

@@ -5,2 +5,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -7,0 +8,0 @@ ],

@@ -5,2 +5,3 @@ {

"tags": [
"cat.semantics",
"best-practice"

@@ -7,0 +8,0 @@ ],

@@ -16,2 +16,6 @@ {

},
"aria-dpub-role-fallback": {
"description": "サポートされていないDPUBロールが暗黙のフォールバックロールを持つ要素でのみ使用されていることを確認してください",
"help": "サポートされていないDPUB ARIAロールは、暗黙のフォールバックロールを持つ要素で使用しなければなりません"
},
"aria-hidden-body": {

@@ -58,3 +62,3 @@ "description": "ドキュメント本体にaria-hidden='true'が存在していないことを確認してください。",

"bypass": {
"description": "ページには少なくとも一つ以上、ユーザーがナビゲーション部分をスキップして直接本文へ移動できるメカニズムが存在することを確認してください",
"description": "ページには少なくとも1つ以上、ユーザーがナビゲーション部分をスキップして直接本文へ移動できるメカニズムが存在することを確認してください",
"help": "ページには繰り返されるブロックをスキップする手段が存在しなければなりません"

@@ -94,2 +98,6 @@ },

},
"frame-tested": {
"description": "<iframe>及び<frame>要素にaxe-coreスクリプトが含まれていることを確認してください",
"help": "フレームはaxe-coreでテストする必要があります"
},
"frame-title-unique": {

@@ -105,3 +113,3 @@ "description": "<iframe>及び<frame>要素に一意のタイトル属性が含まれていることを確認してください",

"description": " 見出しの順序が意味的に正しいことを確認してください",
"help": "見出しのレベルは一つずつ増加させなければなりません"
"help": "見出しのレベルは1つずつ増加させなければなりません"
},

@@ -140,9 +148,25 @@ "hidden-content": {

},
"landmark-banner-is-top-level": {
"description": "bannerランドマークは他のランドマークに含まれるべきではありません",
"help": "Bannerランドマークはトップレベルにあるべきです"
},
"landmark-contentinfo-is-top-level": {
"description": "contentinfoランドマークは他のランドマークに含まれるべきではありません",
"help": "Contentinfoランドマークはトップレベルにあるべきです"
},
"landmark-main-is-top-level": {
"description": "mainランドマークは他のランドマークに含まれるべきではありません",
"help": "mainランドマークがトップレベルにありません"
"help": "mainランドマークはトップレベルにあるべきです"
},
"landmark-no-duplicate-banner": {
"description": "ドキュメントにbannerランドマークが1つしかないことを確認してください",
"help": "ドキュメントに最大で1つのbannerランドマークが含まれています"
},
"landmark-no-duplicate-contentinfo": {
"description": "ドキュメントにcontentinfoランドマークが1つしかないことを確認してください",
"help": "ドキュメントに最大で1つのcontentinfoランドマークが含まれています"
},
"landmark-one-main": {
"description": "ページの主要コンテンツへのナビゲーションポイントを確認してください。ページにiframeが含まれている場合、各iframeにmainランドマークが含まれていないか一つだけでなければなりません",
"help": "ページには一つのmainランドマークを含まなければなりません"
"description": "ページの主要コンテンツへのナビゲーションポイントを確認してください。ページにiframeが含まれている場合、各iframeにmainランドマークが含まれていないか1つだけでなければなりません",
"help": "ページには1つのmainランドマークを含まなければなりません"
},

@@ -193,2 +217,6 @@ "layout-table": {

},
"page-has-heading-one": {
"description": "ページ、またはそのフレームの少なくとも1つにはレベル1の見出しが含まれていることを確認してください",
"help": "ページにはレベル1の見出しが含まれていなければなりません"
},
"radiogroup": {

@@ -272,2 +300,6 @@ "description": "関連している<input type=\"radio\">要素にグループがあり、そのグループの指定が一貫していることを確認してください",

},
"implicit-role-fallback": {
"pass": "要素の暗黙的なARIAロールは適切なフォールバックです",
"fail": "要素の暗黙的なARIAロールは(サポートされていない)ロールに対して、適切なフォールバックではありません"
},
"invalidrole": {

@@ -318,4 +350,4 @@ "pass": "ARIAロールが有効です",

"link-in-text-block": {
"pass": "リンクは色に依存しない方法で周囲のテキストと区別できます",
"fail": "リンクは色に依存しない方法で周囲のテキストと区別できません",
"pass": "リンクは色以外の方法で周囲のテキストと区別できます",
"fail": "リンクは色以外の方法で周囲のテキストと区別できません",
"incomplete": {

@@ -346,14 +378,26 @@ "bgContrast": "要素のコントラスト比を判定できません。明確なホバー/フォーカススタイルを確認してください",

},
"has-at-least-one-main": {
"pass": "ドキュメントには少なくとも一つのmainランドマークがあります",
"fail": "ドキュメントにはmainランドマークがありません"
"landmark-is-top-level": {
"pass": " {{=it.data.role }} ランドマークはトップレベルにあります。",
"fail": "{{=it.data.role }} ランドマークが他のランドマークに含まれています。"
},
"has-no-more-than-one-main": {
"pass": "ドキュメントには一つのmainランドマークがあります",
"fail": "ドキュメントには一つ以上のmainランドマークがあります"
"page-has-heading-one": {
"pass": "ページには少なくとも1つのレベル1の見出しがあります",
"fail": "ページにはレベル1の見出しがなければなりません"
},
"main-is-top-level": {
"pass": "mainランドマークはトップレベルにあります。",
"fail": "mainランドマークが他のランドマークに含まれています。"
"page-has-main": {
"pass": "ページには少なくとも1つのmainランドマークがあります",
"fail": "ページにはmainランドマークがなければなりません"
},
"page-no-duplicate-banner": {
"pass": "ドキュメントにはbannerランドマークが1つしかありません",
"fail": "ドキュメントに1つ以上のbannerランドマークがあります"
},
"page-no-duplicate-contentinfo": {
"pass": "ドキュメントにはcontentinfoランドマークが1つしかありません",
"fail": "ドキュメントに1つ以上のcontentinfoランドマークがあります"
},
"page-no-duplicate-main": {
"pass": "ドキュメントにはmainランドマークが1つしかありません",
"fail": "ドキュメントに1つ以上のmainランドマークがあります"
},
"tabindex": {

@@ -429,2 +473,7 @@ "pass": "要素に0より大きいtabindexは存在していません",

},
"frame-tested": {
"pass": "iframeはaxe-coreでテストされました",
"fail": "iframeはaxe-coreでテストできませんでした",
"incomplete": "iframeはまだaxe-coreでテストする必要があります"
},
"meta-viewport-large": {

@@ -431,0 +480,0 @@ "pass": "<meta>タグはモバイルデバイスでの拡大を阻止しません",

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

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

"dependencies": {}
}
}

@@ -97,3 +97,7 @@ {

"axe.min.js": "sha256-yzD9M6lgRosBZtC6x3acx5XaiLgR2jAWe1dDMqutmbs="
},
"3.0.0": {
"axe.js": "sha256-VQ4MojWEmpw/SEcrFSqtGd/urpIJlU2hz+9ZH632h1I=",
"axe.min.js": "sha256-tCJvwM5MLx5oRdDZMhyqF4uu4m7DmjaSsSiJXfFDdC8="
}
}

@@ -47,2 +47,8 @@ describe('skip-link', function () {

});
it('should return true if the URI encoded href points to an element with an ID', function () {
fixture.innerHTML = '<a href="#%3Ctarget%3E">Click Here</a><h1 id="&lt;target&gt;">Introduction</h1>';
var node = fixture.querySelector('a');
assert.isTrue(checks['skip-link'].evaluate(node));
});
});

@@ -35,2 +35,3 @@ /*global Audit, Rule */

selector: 'input',
tags: ['positive'],
any: [{

@@ -42,2 +43,3 @@ id: 'positive1-check1',

selector: '#monkeys',
tags: ['positive'],
any: ['positive2-check1']

@@ -47,2 +49,3 @@ }, {

selector: 'div',
tags: ['negative'],
none: ['negative1-check1']

@@ -52,2 +55,3 @@ }, {

selector: 'blink',
tags: ['positive'],
any: ['positive3-check1']

@@ -478,30 +482,2 @@ }];

});
it('should call axe.utils.getFlattenedTree', function (done) {
var called = false;
axe.utils.getFlattenedTree = function () {
called = true;
};
a.run({ include: [document] }, {
rules: {}
}, function () {
assert.isTrue(called);
axe.utils.getFlattenedTree = getFlattenedTree;
done();
}, isNotCalled);
});
it('should assign the result of getFlattenedTree to axe._tree', function (done) {
var thing = 'honey badger';
var saved = axe.utils.ruleShouldRun;
axe.utils.ruleShouldRun = function () {
assert.equal(axe._tree, thing);
return false;
};
axe.utils.getFlattenedTree = function () {
return thing;
};
a.run({ include: [document] }, {}, function () {
axe.utils.ruleShouldRun = saved;
done();
}, isNotCalled);
});
it('should assign an empty array to axe._selectCache', function (done) {

@@ -657,3 +633,3 @@ var saved = axe.utils.ruleShouldRun;

it('should run audit.validateOptions to ensure valid input', function () {
it('should run audit.normalizeOptions to ensure valid input', function () {
fixture.innerHTML = '<input type="text" aria-label="monkeys">' +

@@ -665,3 +641,3 @@ '<div id="monkeys">bananas</div>' +

a.validateOptions = function () {
a.normalizeOptions = function () {
checked = 'options validated';

@@ -725,3 +701,3 @@ };

describe('Audit#validateOptions', function () {
describe('Audit#normalizeOptions', function () {

@@ -732,3 +708,3 @@ it('returns the options object when it is valid', function () {

type: 'rule',
value: ['positive1', 'positive2']
values: ['positive1', 'positive2']
},

@@ -739,11 +715,92 @@ rules: {

};
assert(a.validateOptions(opt), opt);
assert(a.normalizeOptions(opt), opt);
});
it('allows `value` as alternative to `values`', function () {
var opt = {
runOnly: {
type: 'rule',
value: ['positive1', 'positive2']
}
};
var out = a.normalizeOptions(opt)
assert.deepEqual(out.runOnly.values, ['positive1', 'positive2']);
assert.isUndefined(out.runOnly.value);
});
it('allows type: rules as an alternative to type: rule', function () {
var opt = {
runOnly: {
type: 'rules',
values: ['positive1', 'positive2']
}
};
assert(a.normalizeOptions(opt).runOnly.type, 'rule');
});
it('allows type: tags as an alternative to type: tag', function () {
var opt = {
runOnly: {
type: 'tags',
values: ['positive']
}
};
assert(a.normalizeOptions(opt).runOnly.type, 'tag');
});
it('allows type: undefined as an alternative to type: tag', function () {
var opt = {
runOnly: {
values: ['positive']
}
};
assert(a.normalizeOptions(opt).runOnly.type, 'tag');
});
it('allows runOnly as an array as an alternative to type: tag', function () {
var opt = { runOnly: ['positive', 'negative'] };
var out = a.normalizeOptions(opt);
assert(out.runOnly.type, 'tag');
assert.deepEqual(out.runOnly.values, ['positive', 'negative']);
});
it('throws an error runOnly.values not an array', function () {
assert.throws(function () {
a.normalizeOptions({
runOnly: {
type: 'rule',
values: { badProp: 'badValue' }
}
});
});
});
it('throws an error runOnly.values an empty', function () {
assert.throws(function () {
a.normalizeOptions({
runOnly: {
type: 'rule',
values: []
}
});
});
});
it('throws an error runOnly.type is unknown', function () {
assert.throws(function () {
a.normalizeOptions({
runOnly: {
type: 'something-else',
values: ['wcag2aa']
}
});
});
});
it('throws an error when option.runOnly has an unknown rule', function () {
assert.throws(function () {
a.validateOptions({
a.normalizeOptions({
runOnly: {
type: 'rule',
value: ['frakeRule']
values: ['frakeRule']
}

@@ -756,6 +813,6 @@ });

assert.throws(function () {
a.validateOptions({
a.normalizeOptions({
runOnly: {
type: 'tags',
value: ['fakeTag']
values: ['fakeTag']
}

@@ -768,3 +825,3 @@ });

assert.throws(function () {
a.validateOptions({
a.normalizeOptions({
rules: {

@@ -771,0 +828,0 @@ fakeRule: { enabled: false}

@@ -330,2 +330,8 @@ /*global Context, axe */

it('should create a flatTree property', function () {
var context = new Context({ include: [document] });
// WARNING: This only works because there is now Shadow DOM on this page
assert.deepEqual(context.flatTree, axe.utils.getFlattenedTree(document));
});
it('should throw when frame could not be found', function (done) {

@@ -347,3 +353,3 @@ fixture.innerHTML = '<div id="outer"></div>';

it('should assign include/exclude', function() {
var flatTree = axe.utils.getFlattenedTree(document);
assert.deepEqual(new Context({

@@ -353,4 +359,5 @@ include: ['#fixture'],

}), {
include: [axe.utils.getFlattenedTree(document.getElementById('fixture'))[0]],
exclude: [axe.utils.getFlattenedTree(document.getElementById('mocha'))[0]],
include: axe.utils.querySelectorAll(flatTree, '#fixture'),
exclude: axe.utils.querySelectorAll(flatTree, '#mocha'),
flatTree: flatTree,
initiator: true,

@@ -360,6 +367,6 @@ page: false,

});
});
});
it('should disregard bad input, non-matching selectors', function() {
var flatTree = axe.utils.getFlattenedTree(document);
assert.deepEqual(new Context({

@@ -369,4 +376,5 @@ include: ['#fixture', '#monkeys'],

}), {
include: [axe.utils.getFlattenedTree(document.getElementById('fixture'))[0]],
include: axe.utils.querySelectorAll(flatTree, '#fixture'),
exclude: [],
flatTree: flatTree,
initiator: true,

@@ -437,2 +445,3 @@ page: false,

spec.hasOwnProperty = undefined;
var result = new Context(spec);

@@ -439,0 +448,0 @@

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

axe._audit = null;
axe._tree = undefined;
});

@@ -76,3 +77,2 @@

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

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

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

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

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

@@ -239,3 +237,2 @@ 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 () {

@@ -661,2 +658,41 @@ assert.fail('This selector should not exist.');

});
it('should return a cleanup method', function (done) {
axe._load({ rules: [{
id: 'html',
selector: 'html',
any: ['html']
}], checks: [{
id: 'html',
evaluate: function () {
return true;
}
}], messages: {}});
runRules(document, {}, function resolve(out, cleanup) {
assert.isDefined(axe._tree);
assert.isDefined(axe._selectorData);
cleanup();
assert.isUndefined(axe._tree);
assert.isUndefined(axe._selectorData);
done();
}, isNotCalled);
});
it('should clear up axe._tree / axe._selectorData after an error', function (done) {
axe._load({ rules: [{
id: 'invalidRule'
}], checks: [], messages: {}});
createFrames(function () {
setTimeout(function () {
runRules(document, {}, isNotCalled, function () {
assert.isUndefined(axe._tree);
assert.isUndefined(axe._selectorData);
done();
});
}, 100);
});
});
});

@@ -125,3 +125,3 @@ describe('axe.run', function () {

axe._runRules = origRunRules;
resolve('MB Bomb');
resolve('MB Bomb', noop);
};

@@ -139,3 +139,3 @@

axe._runRules = function (ctxt, opt, resolve) {
resolve([]);
resolve([], noop);
};

@@ -160,2 +160,18 @@

});
it('is called after cleanup', function (done) {
var isClean = false;
axe._runRules = function (ctxt, opt, resolve) {
axe._runRules = origRunRules;
// Check that cleanup is called before the callback is executed
resolve('MB Bomb', function cleanup() {
isClean = true;
});
};
axe.run({ reporter: 'raw' }, function () {
assert.isTrue(isClean, 'cleanup must be called first');
done();
});
});
});

@@ -166,4 +182,5 @@

/*eslint indent: 0*/
it('returns an error to catch if axe fails',
(!window.Promise) ? undefined : function (done) {
var promiseIt = window.Promise ? it : it.skip;
promiseIt('returns an error to catch if axe fails', function (done) {
axe._runRules = function (ctxt, opt, resolve, reject) {

@@ -184,7 +201,6 @@ axe._runRules = origRunRules;

it('returns a promise if no callback was given',
(!window.Promise) ? undefined : function (done) {
promiseIt('returns a promise if no callback was given', function (done) {
axe._runRules = function (ctxt, opt, resolve) {
axe._runRules = origRunRules;
resolve('World party');
resolve('World party', noop);
};

@@ -201,6 +217,5 @@

it('does not error if then() throws',
(!window.Promise) ? undefined : function (done) {
promiseIt('does not error if then() throws', function (done) {
axe._runRules = function (ctxt, opt, resolve) {
resolve([]);
resolve([], noop);
};

@@ -220,2 +235,20 @@

});
promiseIt('is called after cleanup', function (done) {
var isClean = false;
axe._runRules = function (ctxt, opt, resolve) {
axe._runRules = origRunRules;
// Check that cleanup is called before the callback is executed
resolve('MB Bomb', function cleanup () {
isClean = true;
});
};
axe.run({ reporter: 'raw' })
.then(function () {
assert(isClean, 'cleanup must be called first');
done();
})
.catch(done);
});
});

@@ -222,0 +255,0 @@

@@ -87,3 +87,3 @@ describe('reporters - na', function() {

axe._runRules = function(ctxt, options, cb) {
cb(results);
cb(results, function noop () {});
};

@@ -90,0 +90,0 @@ });

@@ -77,3 +77,3 @@ describe('reporters - no-passes', function() {

axe._runRules = function(ctxt, options, cb) {
cb(results);
cb(results, function noop () {});
};

@@ -80,0 +80,0 @@ });

@@ -8,3 +8,3 @@ describe('reporters - raw', function () {

axe._runRules = function (_, __, cb) {
cb('foo');
cb('foo', function noop () {});
};

@@ -11,0 +11,0 @@

@@ -135,3 +135,3 @@ describe('reporters - v1', function() {

axe._runRules = function(ctxt, options, cb) {
cb(results);
cb(results, function noop () {});
};

@@ -138,0 +138,0 @@ });

@@ -77,3 +77,3 @@ describe('reporters - v2', function() {

axe._runRules = function(ctxt, options, cb) {
cb(results);
cb(results, function noop () {});
};

@@ -80,0 +80,0 @@ });

@@ -8,2 +8,10 @@ /*global Context */

function contextSetup (scope) {
var context = new Context(scope);
axe._tree = context.flatTree;
axe._selectorData = axe.utils.getSelectorData(context.flatTree);
return context
}
afterEach(function () {

@@ -29,4 +37,3 @@ fixture.innerHTML = '';

frame.addEventListener('load', function () {
var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var context = contextSetup(document);
axe.utils.collectResultsFromFrames(context, {}, 'stuff', 'morestuff', noop,

@@ -45,3 +52,2 @@ function (err) {

fixture.appendChild(frame);
});

@@ -63,5 +69,5 @@

frame.addEventListener('load', function () {
var context = new Context(document);
var context = contextSetup(document);
var params = { frameWaitTime: 90000 };
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
axe.utils.collectResultsFromFrames(context, params, 'stuff', 'morestuff', noop,

@@ -80,3 +86,2 @@ function (err) {

fixture.appendChild(frame);
});

@@ -101,4 +106,4 @@

frame.addEventListener('load', function () {
var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var context = contextSetup(document);
axe.utils.collectResultsFromFrames(context, {}, 'rules', 'morestuff', function () {

@@ -115,3 +120,2 @@ done();

fixture.appendChild(frame);
});

@@ -122,4 +126,3 @@

frame.addEventListener('load', function () {
var context = new Context(document);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var context = contextSetup(document);
axe.utils.collectResultsFromFrames(context, {}, 'command', 'params', noop,

@@ -126,0 +129,0 @@ function (err) {

@@ -6,2 +6,3 @@ /*global DqElement */

var fixture = document.getElementById('fixture');
var fixtureSetup = axe.testUtils.fixtureSetup;

@@ -37,3 +38,4 @@ afterEach(function () {

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

@@ -146,4 +148,4 @@

it('creates a path all the way to root', function () {
fixture.innerHTML = '<div id="foo" class="bar">Hello!</div>';
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup('<div id="foo" class="bar">Hello!</div>');
var result = new DqElement(fixture.firstChild, {

@@ -150,0 +152,0 @@ absolutePaths: true

@@ -48,2 +48,3 @@ function createContentGetSelector() {

var shadowSupported = axe.testUtils.shadowSupport.v1;
var fixtureSetup = axe.testUtils.fixtureSetup;

@@ -60,7 +61,13 @@ afterEach(function () {

it('throws if axe._selectorData is undefined', function () {
assert.throws(function () {
var node = document.createElement('div');
fixture.appendChild(node);
axe.utils.getSelector(node);
});
});
it('should generate a unique CSS selector', function () {
var node = document.createElement('div');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);
var sel = axe.utils.getSelector(node);

@@ -76,5 +83,3 @@

node.className = ' ';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);
var sel = axe.utils.getSelector(node);

@@ -90,4 +95,3 @@

node.id = 'monkeys#are.animals\\ok';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);

@@ -102,4 +106,3 @@ var result = document.querySelectorAll(axe.utils.getSelector(node));

node.className = '. bb-required';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);

@@ -113,5 +116,6 @@ var result = document.querySelectorAll(axe.utils.getSelector(node));

var node, expected;
var nodes = []
for (var i = 0; i < 10; i++) {
node = document.createElement('div');
fixture.appendChild(node);
nodes.push(node);
if (i === 5) {

@@ -121,4 +125,3 @@ expected = node;

}
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(nodes);
var result = document.querySelectorAll(axe.utils.getSelector(expected));

@@ -132,4 +135,3 @@ assert.lengthOf(result, 1);

node.id = 'monkeys';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);

@@ -147,31 +149,25 @@ var sel = axe.utils.getSelector(node);

it('should not use ids if they are not unique', function () {
var node = document.createElement('div');
node.id = 'monkeys';
fixture.appendChild(node);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node1.id = 'monkeys';
node2.id = 'monkeys';
node = document.createElement('div');
node.id = 'monkeys';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var sel = axe.utils.getSelector(node);
assert.notInclude(sel, '#monkeys');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
it('should use classes if available and unique', function () {
var node = document.createElement('div');
node.className = 'monkeys simian';
fixture.appendChild(node);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node1.className = 'monkeys simian';
node2.className = 'dogs cats';
node = document.createElement('div');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var sel = axe.utils.getSelector(node);
assert.equal(sel, '.dogs');

@@ -181,3 +177,3 @@

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);

@@ -187,13 +183,9 @@ });

it('should use classes if more unique than the tag', function () {
var node = document.createElement('p');
node.className = 'monkeys simian cats';
fixture.appendChild(node);
var node1 = document.createElement('p');
var node2 = document.createElement('p');
node1.className = 'monkeys simian cats';
node2.className = 'dogs cats';
node = document.createElement('p');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
assert.equal(sel, '.dogs');

@@ -203,18 +195,14 @@

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
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);
var node1 = document.createElement('p');
var node2 = document.createElement('p');
node1.className = 'dogs cats';
node2.className = 'dogs cats';
node = document.createElement('p');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var sel = axe.utils.getSelector(node);
assert.isTrue(sel.indexOf('.dogs') === -1);

@@ -225,38 +213,30 @@ assert.isTrue(sel.indexOf('p') === 0);

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
it('should use the most unique class', function () {
var node = document.createElement('div');
node.className = 'dogs';
fixture.appendChild(node);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node1.className = 'dogs';
node2.className = 'dogs cats';
node = document.createElement('div');
node.className = 'dogs cats';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
assert.equal(sel, '.cats')
var sel = axe.utils.getSelector(node);
assert.equal(sel, '.cats');
var result = document.querySelectorAll(sel);
assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
it('should use the most unique class and not the unique attribute', function () {
var node = document.createElement('div');
node.className = 'dogs';
fixture.appendChild(node);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node = document.createElement('div');
node.className = 'dogs cats';
node.setAttribute('data-axe', 'hello');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
node1.className = 'dogs';
node2.className = 'dogs cats';
node2.setAttribute('data-axe', 'hello');
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);

@@ -267,18 +247,15 @@ assert.equal(sel, '.cats');

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
it('should use only a single unique attribute', function () {
var node = document.createElement('div');
node.setAttribute('data-thing', 'hello');
fixture.appendChild(node);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node = document.createElement('div');
node.setAttribute('data-axe', 'hello');
node.setAttribute('data-thing', 'hello');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
node1.setAttribute('data-thing', 'hello');
node2.setAttribute('data-thing', 'hello');
node2.setAttribute('data-axe', 'hello');
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);

@@ -289,21 +266,18 @@ assert.equal(sel, 'div[data-axe="hello"]');

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
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);
var node1 = document.createElement('div');
node1.setAttribute('data-axe', 'hello');
node1.setAttribute('data-thing', 'hello');
node1.className = 'thing';
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 node2 = document.createElement('div');
node2.setAttribute('data-axe', 'hello');
node2.setAttribute('data-thing', 'hello');
node2.className = 'thing';
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var clsIndex = sel.indexOf('.thing');

@@ -321,23 +295,20 @@ var attIndex = Math.min(sel.indexOf('[data-axe="hello"]'),

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
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);
var node1 = document.createElement('div');
node1.setAttribute('data-axe', 'hello');
node1.setAttribute('data-thing', 'hello');
node1.setAttribute('data-thang', 'hello');
node1.className = 'thing thang';
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 node2 = document.createElement('div');
node2.setAttribute('data-axe', 'hello');
node2.setAttribute('data-thing', 'hello');
node2.setAttribute('data-thang', 'hello');
node2.className = 'thing thang';
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var parts = sel.split('.');

@@ -354,16 +325,13 @@ parts = parts.reduce(function (val, item) {

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
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);
var node1 = document.createElement('div');
var node2 = document.createElement('div');
node1.className = 'thing thang thug thick';
node2.className = 'thing thang thug thick';
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);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var parts = sel.split('.');

@@ -380,22 +348,20 @@ parts = parts.reduce(function (val, item) {

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});
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);
var node1 = document.createElement('div');
node1.setAttribute('data-axe', 'hello');
node1.setAttribute('data-thug', 'hello');
node1.setAttribute('data-thing', 'hello');
node1.setAttribute('data-thang', 'hello');
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 node2 = document.createElement('div');
node2.setAttribute('data-axe', 'hello');
node2.setAttribute('data-thing', 'hello');
node2.setAttribute('data-thang', 'hello');
node2.setAttribute('data-thug', 'hello');
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);
var parts = sel.split('.');

@@ -412,3 +378,3 @@ parts = parts.reduce(function (val, item) {

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);
});

@@ -418,4 +384,3 @@

var node = makeNonuniqueLongAttributes(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup();
var sel = axe.utils.getSelector(node, {});

@@ -426,7 +391,5 @@ 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);
fixtureSetup(node);

@@ -438,12 +401,10 @@ var sel = axe.utils.getSelector(document.documentElement, {});

it('should use position if classes are not unique', function () {
var node = document.createElement('div');
node.className = 'monkeys simian';
fixture.appendChild(node);
var node1 = document.createElement('div');
node1.className = 'monkeys simian';
node = document.createElement('div');
node.className = 'monkeys simian';
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var node2 = document.createElement('div');
node2.className = 'monkeys simian';
var sel = axe.utils.getSelector(node);
fixtureSetup([node1, node2]);
var sel = axe.utils.getSelector(node2);

@@ -454,3 +415,3 @@ assert.equal(sel, '.monkeys.simian:nth-child(2)');

assert.lengthOf(result, 1);
assert.equal(result[0], node);
assert.equal(result[0], node2);

@@ -460,3 +421,3 @@ });

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

@@ -472,3 +433,3 @@ var sel = axe.utils.getSelector(document.documentElement);

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

@@ -483,6 +444,6 @@ var sel = axe.utils.getSelector(document.documentElement);

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

@@ -493,5 +454,4 @@ assert.equal(result[0], document.body);

it('should work on namespaced elements', function () {
fixture.innerHTML = '<hx:include>Hello</hx:include>';
fixtureSetup('<hx:include>Hello</hx:include>');
var node = fixture.firstChild;
axe._tree = axe.utils.getFlattenedTree(document.documentElement);

@@ -505,3 +465,3 @@ var sel = axe.utils.getSelector(node);

it('should work on complex namespaced elements', function () {
fixture.innerHTML = '<m:math xmlns:m="http://www.w3.org/1998/Math/MathML">' +
fixtureSetup('<m:math xmlns:m="http://www.w3.org/1998/Math/MathML">' +
'<m:mi>x</m:mi>' +

@@ -511,4 +471,3 @@ '<m:annotation-xml encoding="MathML-Content">' +

'</m:annotation-xml>' +
'</m:math>';
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
'</m:math>');

@@ -536,4 +495,3 @@ var node = fixture.querySelector('m\\:ci');

});
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);

@@ -546,24 +504,20 @@ assert.isTrue(

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/');
fixture.appendChild(link);
var link1 = document.createElement('a');
link1.setAttribute('href', '//deque.com/thang/');
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);
var link2 = document.createElement('a');
link2.setAttribute('href', '//deque.com/about/');
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var img1 = document.createElement('img');
img1.setAttribute('src', '//deque.com/thang.png');
var img2 = document.createElement('img');
img2.setAttribute('src', '//deque.com/logo.png');
fixtureSetup([ link1, link2, img1, img2 ]);
assert.equal(
axe.utils.getSelector(link),
axe.utils.getSelector(link2),
'a[href$="about/"]'
);
assert.equal(
axe.utils.getSelector(img),
axe.utils.getSelector(img2),
'img[src$="logo.png"]'

@@ -576,4 +530,3 @@ );

node.setAttribute('role', 'menuitem');
fixture.appendChild(node);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup(node);

@@ -586,35 +539,47 @@ assert.equal(

it('no options: should work with shadow DOM', function () {
var shadEl;
it('should work correctly when a URL attribute cannot be shortened', function () {
var href1 = 'mars2.html?a=be_bold';
var node1 = document.createElement('a');
node1.setAttribute('href', href1);
if (shadowSupported) {
// shadow DOM v1 - note: v0 is compatible with this code, so no need
// to specifically test this
fixture.innerHTML = '<div></div>';
makeShadowTreeGetSelector(fixture.firstChild);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
var href2 = 'mars2.html?a=be_italic';
var node2 = document.createElement('a');
node2.setAttribute('href', href2);
fixtureSetup([node1, node2]);
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');
assert.deepEqual(axe.utils.getSelector(shadEl), [
'#fixture > div',
'#myinput'
]);
}
assert.include(axe.utils.getSelector(node1), href1);
assert.include(axe.utils.getSelector(node2), href2);
});
it('toRoot: should work with shadow DOM', function () {
// shadow DOM v1 - note: v0 is compatible with this code, so no need
// to specifically test this
(shadowSupported ? it : xit)
('no options: should work with shadow DOM', function () {
var shadEl;
fixture.innerHTML = '<div></div>';
makeShadowTreeGetSelector(fixture.firstChild);
fixtureSetup();
if (shadowSupported) {
// shadow DOM v1 - note: v0 is compatible with this code, so no need
// to specifically test this
fixture.innerHTML = '<div></div>';
makeShadowTreeGetSelector(fixture.firstChild);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');
assert.deepEqual(axe.utils.getSelector(shadEl), [
'#fixture > div',
'#myinput'
]);
});
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');
assert.deepEqual(axe.utils.getSelector(shadEl, { toRoot: true }), [
'html > body > #fixture > div',
'.parent > div > #myinput'
]);
}
// shadow DOM v1 - note: v0 is compatible with this code, so no need
// to specifically test this
(shadowSupported ? it : xit)
('toRoot: should work with shadow DOM', function () {
var shadEl;
fixture.innerHTML = '<div></div>';
makeShadowTreeGetSelector(fixture.firstChild);
axe._tree = axe.utils.getFlattenedTree(document);
axe._selectorData = axe.utils.getSelectorData(axe._tree);
shadEl = fixture.firstChild.shadowRoot.querySelector('input#myinput');
assert.deepEqual(axe.utils.getSelector(shadEl, { toRoot: true }), [
'html > body > #fixture > div',
'.parent > div > #myinput'
]);
});

@@ -624,3 +589,3 @@

var node = makeNonunique(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup();

@@ -634,3 +599,3 @@ var sel = axe.utils.getSelector(node, {});

var node = makeNonunique(fixture);
axe._tree = axe.utils.getFlattenedTree(document.documentElement);
fixtureSetup();

@@ -637,0 +602,0 @@ var top = fixture.querySelector('div:nth-child(4)');

@@ -5,7 +5,9 @@ describe('context test', function () {

var config = { runOnly: { type: 'rule', values: ['html-has-lang'] } };
var shadowSupported = axe.testUtils.shadowSupport.v1;
before(function (done) {
axe.testUtils.awaitNestedLoad(done);
axe._tree = undefined;
});
describe('direct exclude', function () {

@@ -109,2 +111,15 @@

(shadowSupported ? it : xit)
('should find no nodes in Shadow DOM', function (done) {
var sConfig = { runOnly: { type: 'rule', values: ['color-contrast'] } };
axe.run({ include: [['#shadow-container']], exclude: [['#shadow-host']] }, sConfig, function (err, results) {
try {
assert.isNull(err);
assert.lengthOf(results.violations, 0, 'violations');
assert.lengthOf(results.passes, 1, 'passes');
done();
} catch (e) { done(e); }
});
});
describe('no include', function () {

@@ -111,0 +126,0 @@

@@ -71,3 +71,6 @@ /*eslint indent: 0*/

var fixture = document.querySelector('#fixture');
fixture.innerHTML = '';
if (typeof content !== 'undefined') {
fixture.innerHTML = '';
}
if (typeof content === 'string') {

@@ -77,6 +80,13 @@ fixture.innerHTML = content;

fixture.appendChild(content);
} else if (Array.isArray(content)) {
content.forEach(function (node) {
fixture.appendChild(node);
});
}
axe._tree = axe.utils.getFlattenedTree(fixture);
axe._selectorData = axe.utils.getSelectorData(axe._tree);
return fixture;
};
/**

@@ -83,0 +93,0 @@ * Create check arguments

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

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