diff --git a/lib/checks/generic/attr-non-space-content-evaluate.js b/lib/checks/generic/attr-non-space-content-evaluate.js index 3b199e005f..28a4eda74c 100644 --- a/lib/checks/generic/attr-non-space-content-evaluate.js +++ b/lib/checks/generic/attr-non-space-content-evaluate.js @@ -7,8 +7,22 @@ function attrNonSpaceContentEvaluate(node, options = {}, vNode) { ); } + if (!vNode.hasAttr(options.attribute)) { + this.data({ + messageKey: 'noAttr' + }); + return false; + } + const attribute = vNode.attr(options.attribute) || ''; - return !!sanitize(attribute.trim()); + const attributeIsEmpty = !sanitize(attribute.trim()); + if (attributeIsEmpty) { + this.data({ + messageKey: 'emptyAttr' + }); + return false; + } + return true; } export default attrNonSpaceContentEvaluate; diff --git a/lib/checks/shared/non-empty-alt.json b/lib/checks/shared/non-empty-alt.json index 83700bad45..bced206aa8 100644 --- a/lib/checks/shared/non-empty-alt.json +++ b/lib/checks/shared/non-empty-alt.json @@ -8,7 +8,10 @@ "impact": "critical", "messages": { "pass": "Element has a non-empty alt attribute", - "fail": "Element has no alt attribute or the alt attribute is empty" + "fail": { + "noAttr": "Element has no alt attribute", + "emptyAttr": "Element has an empty alt attribute" + } } } } diff --git a/lib/checks/shared/non-empty-placeholder.json b/lib/checks/shared/non-empty-placeholder.json index 809a3df626..12969f20a4 100644 --- a/lib/checks/shared/non-empty-placeholder.json +++ b/lib/checks/shared/non-empty-placeholder.json @@ -8,7 +8,10 @@ "impact": "serious", "messages": { "pass": "Element has a placeholder attribute", - "fail": "Element has no placeholder attribute or the placeholder attribute is empty" + "fail": { + "noAttr": "Element has no placeholder attribute", + "emptyAttr": "Element has an empty placeholder attribute" + } } } } diff --git a/lib/checks/shared/non-empty-title.json b/lib/checks/shared/non-empty-title.json index 5f5c39e047..b9f1849b3f 100644 --- a/lib/checks/shared/non-empty-title.json +++ b/lib/checks/shared/non-empty-title.json @@ -8,7 +8,10 @@ "impact": "serious", "messages": { "pass": "Element has a title attribute", - "fail": "Element has no title attribute or the title attribute is empty" + "fail": { + "noAttr": "Element has no title attribute", + "emptyAttr": "Element has an empty title attribute" + } } } } diff --git a/lib/checks/shared/non-empty-value.json b/lib/checks/shared/non-empty-value.json index 7d3e14cde8..b5fdce396b 100644 --- a/lib/checks/shared/non-empty-value.json +++ b/lib/checks/shared/non-empty-value.json @@ -8,7 +8,10 @@ "impact": "critical", "messages": { "pass": "Element has a non-empty value attribute", - "fail": "Element has no value attribute or the value attribute is empty" + "fail": { + "noAttr": "Element has no value attribute", + "emptyAttr": "Element has an empty value attribute" + } } } } diff --git a/test/checks/shared/non-empty-alt.js b/test/checks/shared/non-empty-alt.js index 53a92b50bd..83047c948d 100644 --- a/test/checks/shared/non-empty-alt.js +++ b/test/checks/shared/non-empty-alt.js @@ -4,28 +4,33 @@ describe('non-empty-alt', function() { var fixture = document.getElementById('fixture'); var checkSetup = axe.testUtils.checkSetup; var checkEvaluate = axe.testUtils.getCheckEvaluate('non-empty-alt'); + var checkContext = axe.testUtils.MockCheckContext(); afterEach(function() { fixture.innerHTML = ''; + checkContext.reset(); }); it('should return true if an alt is present', function() { var params = checkSetup('woohoo'); - assert.isTrue(checkEvaluate.apply(null, params)); + assert.isTrue(checkEvaluate.apply(checkContext, params)); }); it('should return false if an alt is not present', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noAttr'); }); it('should return false if an alt is present, but empty', function() { var params = checkSetup(' '); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); it('should collapse whitespace', function() { var params = checkSetup(' \t \n \r \t  \t\r\n '); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); }); diff --git a/test/checks/shared/non-empty-placeholder.js b/test/checks/shared/non-empty-placeholder.js index 78ed141659..654190739b 100644 --- a/test/checks/shared/non-empty-placeholder.js +++ b/test/checks/shared/non-empty-placeholder.js @@ -4,27 +4,31 @@ describe('non-empty-placeholder', function() { var fixture = document.getElementById('fixture'); var checkSetup = axe.testUtils.checkSetup; var checkEvaluate = axe.testUtils.getCheckEvaluate('non-empty-placeholder'); + var checkContext = axe.testUtils.MockCheckContext(); afterEach(function() { fixture.innerHTML = ''; + checkContext.reset(); }); it('should return true if a placeholder is present', function() { var params = checkSetup(''); - assert.isTrue(checkEvaluate.apply(null, params)); + assert.isTrue(checkEvaluate.apply(checkContext, params)); }); it('should return false if a placeholder is not present', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noAttr'); }); it('should return false if a placeholder is present, but empty', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); it('should collapse whitespace', function() { @@ -32,6 +36,7 @@ describe('non-empty-placeholder', function() { '' ); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); }); diff --git a/test/checks/shared/non-empty-title.js b/test/checks/shared/non-empty-title.js index 234429106d..81c181a4d7 100644 --- a/test/checks/shared/non-empty-title.js +++ b/test/checks/shared/non-empty-title.js @@ -4,27 +4,31 @@ describe('non-empty-title', function() { var fixture = document.getElementById('fixture'); var checkSetup = axe.testUtils.checkSetup; var checkEvaluate = axe.testUtils.getCheckEvaluate('non-empty-title'); + var checkContext = axe.testUtils.MockCheckContext(); afterEach(function() { fixture.innerHTML = ''; + checkContext.reset(); }); it('should return true if a title is present', function() { var params = checkSetup(''); - assert.isTrue(checkEvaluate.apply(null, params)); + assert.isTrue(checkEvaluate.apply(checkContext, params)); }); it('should return false if a title is not present', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noAttr'); }); it('should return false if a title is present, but empty', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); it('should collapse whitespace', function() { @@ -32,6 +36,7 @@ describe('non-empty-title', function() { '' ); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); }); diff --git a/test/checks/shared/non-empty-value.js b/test/checks/shared/non-empty-value.js index 15a8689fd6..e81b61275b 100644 --- a/test/checks/shared/non-empty-value.js +++ b/test/checks/shared/non-empty-value.js @@ -4,6 +4,7 @@ describe('non-empty-value', function() { var fixture = document.getElementById('fixture'); var checkSetup = axe.testUtils.checkSetup; var checkEvaluate = axe.testUtils.getCheckEvaluate('non-empty-value'); + var checkContext = axe.testUtils.MockCheckContext(); afterEach(function() { fixture.innerHTML = ''; @@ -12,19 +13,21 @@ describe('non-empty-value', function() { it('should return true if an value is present', function() { var params = checkSetup(''); - assert.isTrue(checkEvaluate.apply(null, params)); + assert.isTrue(checkEvaluate.apply(checkContext, params)); }); it('should return false if an value is not present', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noAttr'); }); it('should return false if an value is present, but empty', function() { var params = checkSetup(''); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); it('should collapse whitespace', function() { @@ -32,6 +35,7 @@ describe('non-empty-value', function() { '' ); - assert.isFalse(checkEvaluate.apply(null, params)); + assert.isFalse(checkEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'emptyAttr'); }); });