diff --git a/lib/checks/aria/aria-errormessage-evaluate.js b/lib/checks/aria/aria-errormessage-evaluate.js
index 6986efdb78..bacb1c9c7c 100644
--- a/lib/checks/aria/aria-errormessage-evaluate.js
+++ b/lib/checks/aria/aria-errormessage-evaluate.js
@@ -1,7 +1,7 @@
import standards from '../../standards';
import { idrefs } from '../../commons/dom';
import { tokenList } from '../../core/utils';
-
+import { isVisible } from '../../commons/dom';
/**
* Check if `aria-errormessage` references an element that also uses a technique to announce the message (aria-live, aria-describedby, etc.).
*
@@ -55,6 +55,13 @@ function ariaErrormessageEvaluate(node, options, virtualNode) {
}
if (idref) {
+ if (!isVisible(idref, true)) {
+ this.data({
+ messageKey: 'hidden',
+ values: tokenList(attr)
+ });
+ return false;
+ }
return (
idref.getAttribute('role') === 'alert' ||
idref.getAttribute('aria-live') === 'assertive' ||
@@ -62,6 +69,7 @@ function ariaErrormessageEvaluate(node, options, virtualNode) {
tokenList(virtualNode.attr('aria-describedby')).indexOf(attr) > -1
);
}
+
return;
}
diff --git a/lib/checks/aria/aria-errormessage.json b/lib/checks/aria/aria-errormessage.json
index ce672a591c..84901729af 100644
--- a/lib/checks/aria/aria-errormessage.json
+++ b/lib/checks/aria/aria-errormessage.json
@@ -7,7 +7,8 @@
"pass": "aria-errormessage exists and references elements visible to screen readers that use a supported aria-errormessage technique",
"fail": {
"singular": "aria-errormessage value `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)",
- "plural": "aria-errormessage values `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)"
+ "plural": "aria-errormessage values `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)",
+ "hidden": "aria-errormessage value `${data.values}` cannot reference a hidden element"
},
"incomplete": {
"singular": "ensure aria-errormessage value `${data.values}` references an existing element",
diff --git a/test/checks/aria/errormessage.js b/test/checks/aria/errormessage.js
index 1fc42bcb92..e54f44ffed 100644
--- a/test/checks/aria/errormessage.js
+++ b/test/checks/aria/errormessage.js
@@ -144,6 +144,94 @@ describe('aria-errormessage', function() {
);
});
+ it('should return false when hidden attribute is used', function() {
+ var vNode = queryFixture(
+ '' +
+ '
Error message 1
'
+ );
+ assert.isFalse(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ assert.deepEqual(checkContext._data, {
+ messageKey: 'hidden',
+ values: ['id-message-1']
+ });
+ });
+
+ it('should return false when display: "none" is used', function() {
+ var vNode = queryFixture(
+ '' +
+ 'Error message 1
'
+ );
+ assert.isFalse(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ assert.deepEqual(checkContext._data, {
+ messageKey: 'hidden',
+ values: ['id-message-1']
+ });
+ });
+
+ it('should return false when visibility: "hidden" is used', function() {
+ var vNode = queryFixture(
+ '' +
+ 'Error message 1
'
+ );
+ assert.isFalse(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ assert.deepEqual(checkContext._data, {
+ messageKey: 'hidden',
+ values: ['id-message-1']
+ });
+ });
+
+ it('should return false when aria-hidden=true is used', function() {
+ var vNode = queryFixture(
+ '' +
+ 'Error message 1
'
+ );
+ assert.isFalse(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ assert.deepEqual(checkContext._data, {
+ messageKey: 'hidden',
+ values: ['id-message-1']
+ });
+ });
+
+ it('should return true when aria-hidden=false is used', function() {
+ var vNode = queryFixture(
+ '' +
+ 'Error message 1
'
+ );
+ assert.isTrue(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ });
+
+ it('should return true when no hidden functionality is used', function() {
+ var vNode = queryFixture(
+ '' +
+ 'Error message 1
'
+ );
+ assert.isTrue(
+ axe.testUtils
+ .getCheckEvaluate('aria-errormessage')
+ .call(checkContext, null, null, vNode)
+ );
+ });
+
(shadowSupported ? it : xit)(
'should return undefined if aria-errormessage value crosses shadow boundary',
function() {
diff --git a/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html b/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html
index 52448862ff..e34c9d38dc 100644
--- a/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html
+++ b/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html
@@ -51,6 +51,46 @@ Violations
hi
hi
+
+
+
+
+
+
+
+
Possible False Positives
@@ -276,6 +316,35 @@
Possible False Positives
hi
hi
+
+
+
+
+
hi
+
+
+
+
+
+
+
+
+
Hi
Hi2
diff --git a/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json b/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json
index 6abcb9708b..e6e23e5ec4 100644
--- a/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json
+++ b/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json
@@ -41,7 +41,11 @@
["#violation40"],
["#violation41"],
["#violation42"],
- ["#violation43"]
+ ["#violation43"],
+ ["#violation44"],
+ ["#violation45"],
+ ["#violation46"],
+ ["#violation47"]
],
"passes": [
["#pass1"],
@@ -220,7 +224,11 @@
["#pass183"],
["#pass184"],
["#pass185"],
- ["#pass186"]
+ ["#pass186"],
+ ["#pass187"],
+ ["#pass188"],
+ ["#pass189"],
+ ["#pass190"]
],
"incomplete": [
["#incomplete1"],