diff --git a/.travis.yml b/.travis.yml
index 51474a55..d5d5b4b7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ language: node_js
node_js:
# we recommend testing addons with the same minimum supported node version as Ember CLI
# so that your addon works for all apps
- - "4"
+ - "6"
sudo: required
dist: trusty
diff --git a/addon/services/concurrent-axe.js b/addon/services/concurrent-axe.js
new file mode 100644
index 00000000..4342fedd
--- /dev/null
+++ b/addon/services/concurrent-axe.js
@@ -0,0 +1,41 @@
+/* global axe */
+import Service from '@ember/service';
+import { next } from '@ember/runloop';
+
+export default Service.extend({
+ init() {
+ this._super(...arguments);
+ this._timer = null;
+ this._queue = [];
+ },
+
+ /**
+ * Axe v3 contains a concurrency issue which breaks the component auditing feature.
+ * This service defers axe.run calls on onto the next loop so that concurrent
+ * axe executions do not occur.
+ *
+ * @see(https://github.com/dequelabs/axe-core/issues/1041)
+ * @public
+ * @param {HTMLElement} element axe context
+ * @param {Object} options axe configuration options
+ * @param {Function} callback axe audit callback
+ * @return {Void}
+ */
+ run(element, options, callback) {
+ if (this._timer) {
+ this._queue.push(arguments);
+ } else {
+ this._timer = next(() => {
+ if (element && element.parentNode) {
+ axe.run(element, options, callback);
+ }
+
+ this._timer = null;
+
+ if (this._queue.length) {
+ this.run(...this._queue.shift());
+ }
+ });
+ }
+ }
+});
diff --git a/app/instance-initializers/axe-component.js b/app/instance-initializers/axe-component.js
index 629700ac..e56b1994 100644
--- a/app/instance-initializers/axe-component.js
+++ b/app/instance-initializers/axe-component.js
@@ -9,6 +9,7 @@ import ENV from '../config/environment';
import isBackgroundReplacedElement from 'ember-a11y-testing/utils/is-background-replaced-element';
import formatViolation from 'ember-a11y-testing/utils/format-violation';
import violationsHelper from 'ember-a11y-testing/utils/violations-helper';
+import { inject as service } from '@ember/service';
const VIOLATION_CLASS__LEVEL_1 = 'axe-violation--level-1';
const VIOLATION_CLASS__LEVEL_2 = 'axe-violation--level-2';
@@ -54,6 +55,15 @@ export function initialize() {
let turnAuditOff = configuredTurnAuditOff || false;
Component.reopen({
+ /**
+ * An Ember service which resolves concurrent axe.run v3 issue.
+ *
+ * @public
+ * @type {Object}
+ * @see(https://github.com/dequelabs/axe-core/issues/1041)
+ */
+ concurrentAxe: service('concurrent-axe'),
+
/**
* An optional callback to process the results from the a11yCheck.
* Defaults to `undefined` if not set in the application's configuration.
@@ -138,12 +148,15 @@ export function initialize() {
*/
audit() {
if (this.get('tagName') !== '') {
-
- axe.a11yCheck(this.$(), this.axeOptions, (results) => {
+ this.get('concurrentAxe').run(this.element, this.axeOptions, (error, results) => {
if (this.get('isDestroyed')) {
return;
}
+ if (error) {
+ throw error;
+ }
+
const violations = results.violations;
const violationClasses = this.get('violationClasses') || [];
const visualNoiseLevel = this.get('visualNoiseLevel');
diff --git a/app/services/concurrent-axe.js b/app/services/concurrent-axe.js
new file mode 100644
index 00000000..4a7e7fed
--- /dev/null
+++ b/app/services/concurrent-axe.js
@@ -0,0 +1 @@
+export { default } from 'ember-a11y-testing/services/concurrent-axe';
diff --git a/package.json b/package.json
index f69b0804..bdd69571 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"test": "ember try:each"
},
"dependencies": {
- "axe-core": "^2.6.1",
+ "axe-core": "^3.1.2",
"broccoli-funnel": "^2.0.1",
"ember-cli-babel": "^6.8.2",
"ember-cli-version-checker": "^2.1.0",
diff --git a/tests/acceptance/a11y-audit-test.js b/tests/acceptance/a11y-audit-test.js
index 6a8f3de2..4387311b 100644
--- a/tests/acceptance/a11y-audit-test.js
+++ b/tests/acceptance/a11y-audit-test.js
@@ -93,7 +93,7 @@ test('a11yAudit can accept an options hash as a single argument', function(asser
a11yAudit({
runOnly: {
type: "rule",
- values: []
+ values: ["accesskeys"]
}
});
diff --git a/tests/dummy/app/components/x-text-input.js b/tests/dummy/app/components/x-text-input.js
index 264b747f..c0980ff5 100644
--- a/tests/dummy/app/components/x-text-input.js
+++ b/tests/dummy/app/components/x-text-input.js
@@ -2,6 +2,5 @@ import Component from '@ember/component';
export default Component.extend({
- classNames: ['c-text-input'],
- tagName: 'input',
+ classNames: ['c-text-input']
});
diff --git a/tests/dummy/app/templates/components/x-text-input.hbs b/tests/dummy/app/templates/components/x-text-input.hbs
index 330ee755..1e5ebdd7 100644
--- a/tests/dummy/app/templates/components/x-text-input.hbs
+++ b/tests/dummy/app/templates/components/x-text-input.hbs
@@ -1,6 +1,6 @@
diff --git a/tests/dummy/app/templates/violations.hbs b/tests/dummy/app/templates/violations.hbs
index 94cdbc48..3b1ac0c7 100644
--- a/tests/dummy/app/templates/violations.hbs
+++ b/tests/dummy/app/templates/violations.hbs
@@ -55,7 +55,7 @@
value=3
name="noise-level"
class="c-radio-track__item-input"
- radioId="noise-level-3"
+ id="noise-level-3"
changed="updateCurrentNoiseLevel"
}}
Level 3
@@ -74,7 +74,7 @@
{{! Empty button }}
- {{#violations-grid-item class="p-violations__grid-item" title="Button without title"}}
+ {{#violations-grid-item class="p-violations__grid-item" title="Button without title" turnAuditOff=true}}
{{x-button
id="violations__empty-button"
@@ -85,12 +85,12 @@
{{/violations-grid-item}}
{{! Labeless text input }}
- {{#violations-grid-item class="p-violations__grid-item" title="Input without label"}}
- {{x-text-input id="violations__labeless-input" data-test-selector="labeless-text-input" visualNoiseLevel=model.currentNoiseLevel}}
+ {{#violations-grid-item class="p-violations__grid-item" title="Input without label" turnAuditOff=true}}
+ {{x-text-input inputId="violations__labeless-input" data-test-selector="labeless-text-input" visualNoiseLevel=model.currentNoiseLevel}}
{{/violations-grid-item}}
{{! Poorly Contrasting Text color }}
- {{#violations-grid-item class="p-violations__grid-item" title="Poorly Contrasting Text Color"}}
+ {{#violations-grid-item class="p-violations__grid-item" title="Poorly Contrasting Text Color" turnAuditOff=true}}
{{#x-paragraph
class="p-violations__grid-item-content--low-contrast-text"
data-test-selector="labeless-text-input"
@@ -101,19 +101,19 @@
{{/violations-grid-item}}
{{! Usage of the