From 929085aad1fecc32686f42efb76e461484c920f1 Mon Sep 17 00:00:00 2001 From: Paul Grenier Date: Wed, 9 Oct 2019 16:17:49 -0400 Subject: [PATCH] fix: allows all roles on img tag with no alt attribute --- lib/commons/aria/index.js | 18 +++++++-- test/checks/aria/aria-allowed-role.js | 39 ++++++++++++++++++- .../aria/is-aria-role-allowed-on-element.js | 24 ++++++++++++ 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/lib/commons/aria/index.js b/lib/commons/aria/index.js index ebc240e181..36369b033a 100644 --- a/lib/commons/aria/index.js +++ b/lib/commons/aria/index.js @@ -2243,6 +2243,12 @@ lookupTable.elementsAllowedAnyRole = [ href: isNull } }, + { + nodeName: 'img', + attributes: { + alt: isNull + } + }, { nodeName: [ 'abbr', @@ -2310,11 +2316,15 @@ lookupTable.evaluateRoleForElement = { } return out; }, - IMG: ({ node, out }) => { - if (node.alt) { - return !out; + IMG: ({ node, role, out }) => { + switch (node.alt) { + case null: + return out; + case '': + return role === 'presentation' || role === 'none'; + default: + return role !== 'presentation' && role !== 'none'; } - return out; }, INPUT: ({ node, role, out }) => { switch (node.type) { diff --git a/test/checks/aria/aria-allowed-role.js b/test/checks/aria/aria-allowed-role.js index c7734a4cbd..1874b6dfab 100644 --- a/test/checks/aria/aria-allowed-role.js +++ b/test/checks/aria/aria-allowed-role.js @@ -87,14 +87,51 @@ describe('aria-allowed-role', function() { ); }); - it('returns false when img has no alt', function() { + it('returns true when img has no alt', function() { var node = document.createElement('img'); node.setAttribute('role', 'presentation'); fixture.appendChild(node); + assert.isTrue( + checks['aria-allowed-role'].evaluate.call(checkContext, node) + ); + assert.deepEqual(checkContext._data, null); + node.setAttribute('role', 'none'); + assert.isTrue( + checks['aria-allowed-role'].evaluate.call(checkContext, node) + ); + assert.deepEqual(checkContext._data, null); + }); + + it('returns true when img has empty alt', function() { + var node = document.createElement('img'); + node.setAttribute('alt', ''); + node.setAttribute('role', 'presentation'); + fixture.appendChild(node); + assert.isTrue( + checks['aria-allowed-role'].evaluate.call(checkContext, node) + ); + assert.deepEqual(checkContext._data, null); + node.setAttribute('role', 'none'); + assert.isTrue( + checks['aria-allowed-role'].evaluate.call(checkContext, node) + ); + assert.deepEqual(checkContext._data, null); + }); + + it('returns false when img has alt', function() { + var node = document.createElement('img'); + node.setAttribute('alt', 'not empty'); + node.setAttribute('role', 'presentation'); + fixture.appendChild(node); assert.isFalse( checks['aria-allowed-role'].evaluate.call(checkContext, node) ); assert.deepEqual(checkContext._data, ['presentation']); + node.setAttribute('role', 'none'); + assert.isFalse( + checks['aria-allowed-role'].evaluate.call(checkContext, node) + ); + assert.deepEqual(checkContext._data, ['none']); }); it('returns true when input of type image and no role', function() { diff --git a/test/commons/aria/is-aria-role-allowed-on-element.js b/test/commons/aria/is-aria-role-allowed-on-element.js index 623fc741cb..0b09b07ae2 100644 --- a/test/commons/aria/is-aria-role-allowed-on-element.js +++ b/test/commons/aria/is-aria-role-allowed-on-element.js @@ -249,6 +249,7 @@ describe('aria.isAriaRoleAllowedOnElement', function() { } }; var node = document.createElement('img'); + node.setAttribute('alt', ''); node.setAttribute('role', 'presentation'); var actual = axe.commons.aria.isAriaRoleAllowedOnElement( node, @@ -258,6 +259,29 @@ describe('aria.isAriaRoleAllowedOnElement', function() { assert.isFalse(actual); }); + it('returns true, ensure evaluateRoleForElement in lookupTable is invoked', function() { + var overrideInvoked = false; + axe.commons.aria.lookupTable.evaluateRoleForElement = { + IMG: function(options) { + overrideInvoked = true; + assert.isDefined(options.node); + assert.equal(options.node.nodeName.toUpperCase(), 'IMG'); + assert.isBoolean(options.out); + return false; + } + }; + var node = document.createElement('img'); + node.setAttribute('role', 'presentation'); + var presentationAllowed = axe.commons.aria.isAriaRoleAllowedOnElement( + node, + 'presentation' + ); + var noneAllowed = axe.commons.aria.isAriaRoleAllowedOnElement(node, 'none'); + assert.isFalse(overrideInvoked); + assert.isTrue(presentationAllowed); + assert.isTrue(noneAllowed); + }); + it('returns false if element with role MENU type context', function() { var overrideInvoked = false; axe.commons.aria.lookupTable.evaluateRoleForElement = {