From 87cfc0b4f4d998a88a2d534438e4f2ccf9427a86 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 3 Aug 2021 09:14:18 -0600 Subject: [PATCH 01/88] feat(aria-allowed-attr): report violations for non-global ARIA attributes on elements without a role (#3102) * feat(aria-allowed-attr): report violations for non-global ARIA attributes on elements without a role * fix tests * remove wrong test --- lib/checks/aria/aria-allowed-attr-evaluate.js | 2 +- test/checks/aria/allowed-attr.js | 17 +++++++++++++++-- .../rules/aria-allowed-attr/failures.html | 6 ++++++ .../rules/aria-allowed-attr/failures.json | 3 ++- .../virtual-rules/aria-allowed-attr.js | 17 +++++++++++++++-- .../virtual-rules/aria-allowed-role.js | 13 ------------- 6 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/checks/aria/aria-allowed-attr-evaluate.js b/lib/checks/aria/aria-allowed-attr-evaluate.js index 59da14c22a..19775a9528 100644 --- a/lib/checks/aria/aria-allowed-attr-evaluate.js +++ b/lib/checks/aria/aria-allowed-attr-evaluate.js @@ -38,7 +38,7 @@ function ariaAllowedAttrEvaluate(node, options, virtualNode) { allowed = uniqueArray(options[role].concat(allowed)); } - if (role && allowed) { + if (allowed) { for (let i = 0; i < attrs.length; i++) { const attrName = attrs[i]; if (validateAttr(attrName) && !allowed.includes(attrName)) { diff --git a/test/checks/aria/allowed-attr.js b/test/checks/aria/allowed-attr.js index cbba61b843..e63e64bbb9 100644 --- a/test/checks/aria/allowed-attr.js +++ b/test/checks/aria/allowed-attr.js @@ -46,9 +46,9 @@ describe('aria-allowed-attr', function() { assert.deepEqual(checkContext._data, ['aria-selected="true"']); }); - it('should return true if there is no role', function() { + it('should return true for global attributes if there is no role', function() { var vNode = queryFixture( - '
' + '
' ); assert.isTrue( @@ -59,6 +59,19 @@ describe('aria-allowed-attr', function() { assert.isNull(checkContext._data); }); + it('should return false for non-global attributes if there is no role', function() { + var vNode = queryFixture( + '
' + ); + + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-allowed-attr') + .call(checkContext, null, null, vNode) + ); + assert.deepEqual(checkContext._data, ['aria-selected="true"']); + }); + it('should not report on invalid attributes', function() { var vNode = queryFixture( '' diff --git a/test/integration/rules/aria-allowed-attr/failures.html b/test/integration/rules/aria-allowed-attr/failures.html index f4839431e7..0f77954a3f 100644 --- a/test/integration/rules/aria-allowed-attr/failures.html +++ b/test/integration/rules/aria-allowed-attr/failures.html @@ -28,3 +28,9 @@ + diff --git a/test/integration/rules/aria-allowed-attr/failures.json b/test/integration/rules/aria-allowed-attr/failures.json index 6b48f87d29..bbc6f0a214 100644 --- a/test/integration/rules/aria-allowed-attr/failures.json +++ b/test/integration/rules/aria-allowed-attr/failures.json @@ -30,6 +30,7 @@ ["#fail26"], ["#fail27"], ["#fail28"], - ["#fail29"] + ["#fail29"], + ["#fail30"] ] } diff --git a/test/integration/virtual-rules/aria-allowed-attr.js b/test/integration/virtual-rules/aria-allowed-attr.js index dab04984fb..d25619137d 100644 --- a/test/integration/virtual-rules/aria-allowed-attr.js +++ b/test/integration/virtual-rules/aria-allowed-attr.js @@ -42,11 +42,11 @@ describe('aria-allowed-attr virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should pass for element with no role', function() { + it('should pass for global attributes and element with no role', function() { var results = axe.runVirtualRule('aria-allowed-attr', { nodeName: 'div', attributes: { - 'aria-checked': true + 'aria-busy': true } }); @@ -55,6 +55,19 @@ describe('aria-allowed-attr virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); + it('should fail for non-global attributes and element with no role', function() { + var results = axe.runVirtualRule('aria-allowed-attr', { + nodeName: 'div', + attributes: { + 'aria-checked': true + } + }); + + assert.lengthOf(results.passes, 0); + assert.lengthOf(results.violations, 1); + assert.lengthOf(results.incomplete, 0); + }); + it('should fail for unallowed attributes', function() { var results = axe.runVirtualRule('aria-allowed-attr', { nodeName: 'div', diff --git a/test/integration/virtual-rules/aria-allowed-role.js b/test/integration/virtual-rules/aria-allowed-role.js index 8d2fcdd947..9b579e56e3 100644 --- a/test/integration/virtual-rules/aria-allowed-role.js +++ b/test/integration/virtual-rules/aria-allowed-role.js @@ -17,19 +17,6 @@ describe('aria-allowed-role virtual-rule', function() { assert.lengthOf(results.incomplete, 0); }); - it('should pass for element with no role', function() { - var results = axe.runVirtualRule('aria-allowed-attr', { - nodeName: 'div', - attributes: { - 'aria-checked': true - } - }); - - assert.lengthOf(results.passes, 1); - assert.lengthOf(results.violations, 0); - assert.lengthOf(results.incomplete, 0); - }); - it('should fail for unallowed role', function() { var results = axe.runVirtualRule('aria-allowed-role', { nodeName: 'dd', From b494d090b7dc0a1d26e72cc4f59059c7283beaad Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 3 Aug 2021 09:14:57 -0600 Subject: [PATCH 02/88] tests: locally host webfonts for is-icon-ligature test (#3105) * tests: locally host webfonts for is-icon-ligature test * license --- test/assets/FiraCode-Regular.woff | Bin 0 -> 105980 bytes test/assets/LigatureSymbols.woff | Bin 0 -> 62636 bytes test/assets/MaterialIcons.woff2 | Bin 0 -> 60840 bytes test/assets/Roboto.woff2 | Bin 0 -> 11016 bytes test/assets/webfont-attribution-license.md | 21 +++++++++++++++++++++ test/commons/text/is-icon-ligature.js | 11 ++++------- 6 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 test/assets/FiraCode-Regular.woff create mode 100644 test/assets/LigatureSymbols.woff create mode 100644 test/assets/MaterialIcons.woff2 create mode 100644 test/assets/Roboto.woff2 create mode 100644 test/assets/webfont-attribution-license.md diff --git a/test/assets/FiraCode-Regular.woff b/test/assets/FiraCode-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..a82d5565c1a5b97a556c6e4c6bec5752281d816d GIT binary patch literal 105980 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 |y#WFK|sr%YHq78$#SRf!6%!YTDCmfHn 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 L^FC5HmVR&!=0P_3* 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 Bz_kDX literal 0 HcmV?d00001 diff --git a/test/assets/MaterialIcons.woff2 b/test/assets/MaterialIcons.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..34cdd2afba56b9dd3c7f0e3b758069a92db6b7bf GIT binary patch literal 60840 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 ZAW|PCr`Wg(XLM`IW|Ri_`Ahlk@&R}sbiDuo literal 0 HcmV?d00001 diff --git a/test/assets/Roboto.woff2 b/test/assets/Roboto.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4fc449afdba7aeb19b03c1f216e369f20a3e2191 GIT binary patch literal 11016 zcmV+jEBDlQPew8T0RR9104oRp4gdfE090@Q04lKn0RR9100000000000000000000 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 CxrlrK literal 0 HcmV?d00001 diff --git a/test/assets/webfont-attribution-license.md b/test/assets/webfont-attribution-license.md new file mode 100644 index 0000000000..4a2617d0cc --- /dev/null +++ b/test/assets/webfont-attribution-license.md @@ -0,0 +1,21 @@ +# Webfont Attribution and Licenses + +## FiraCode-Regular: + +https://github.com/tonsky/FiraCode +License: SIL Open Font License 1.1 + +## Ligature Symbols + +https://github.com/kudakurage/LigatureSymbols +License: SIL Open Font License 1.1 + +## Material Icons + +https://google.github.io/material-design-icons +License: Apache License Version 2.0 + +## Roboto + +https://fonts.google.com/specimen/Roboto +License: Apache License, Version 2.0 diff --git a/test/commons/text/is-icon-ligature.js b/test/commons/text/is-icon-ligature.js index 0908527779..de9f9f6d1b 100644 --- a/test/commons/text/is-icon-ligature.js +++ b/test/commons/text/is-icon-ligature.js @@ -12,20 +12,17 @@ describe('text.isIconLigature', function() { var firaFont = new FontFace( 'Fira Code', - 'url(https://cdn.jsdelivr.net/gh/tonsky/FiraCode@1.207/distr/woff/FiraCode-Regular.woff)' + 'url(/test/assets/FiraCode-Regular.woff)' ); var ligatureFont = new FontFace( 'LigatureSymbols', - 'url(https://cdn.jsdelivr.net/gh/kudakurage/LigatureSymbols/LigatureSymbols-2.11.woff)' + 'url(/test/assets/LigatureSymbols.woff)' ); var materialFont = new FontFace( 'Material Icons', - 'url(https://fonts.gstatic.com/s/materialicons/v48/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2)' - ); - var robotoFont = new FontFace( - 'Roboto', - 'url(https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2)' + 'url(/test/assets/MaterialIcons.woff2)' ); + var robotoFont = new FontFace('Roboto', 'url(/test/assets/Roboto.woff2)'); window.Promise.all([ firaFont.load(), From a9e03c84a657624248708a56f6898dc0d05ad285 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 3 Aug 2021 15:24:13 -0600 Subject: [PATCH 03/88] chore: use standards in aria-supported script (#3104) * chore: use standards in aria-supported script * fixes --- build/tasks/aria-supported.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/tasks/aria-supported.js b/build/tasks/aria-supported.js index 81de153d75..cccf92ebbf 100644 --- a/build/tasks/aria-supported.js +++ b/build/tasks/aria-supported.js @@ -37,16 +37,17 @@ module.exports = function(grunt) { attributesMdTableHeader: ['aria-attribute', 'axe-core support'] }; + const { ariaRoles, ariaAttrs } = axe.utils.getStandards(); const { diff: rolesTable, notes: rolesFootnotes } = getDiff( roles, - axe.commons.aria.lookupTable.role, + ariaRoles, listType ); const ariaQueryAriaAttributes = getAriaQueryAttributes(); const { diff: attributesTable, notes: attributesFootnotes } = getDiff( ariaQueryAriaAttributes, - axe.commons.aria.lookupTable.attributes, + ariaAttrs, listType ); const attributesTableMarkdown = mdTable([ From e3631384170e3250629a9d96d70da3310904b665 Mon Sep 17 00:00:00 2001 From: Alain Vagner Date: Wed, 11 Aug 2021 17:55:14 +0200 Subject: [PATCH 04/88] chore(i18n): updated french translation (#3106) * chore(i18n): updated french translation * integrated proofreading by @audreymaniez * translation improvement after discussion with @audreymaniez --- locales/fr.json | 249 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 210 insertions(+), 39 deletions(-) diff --git a/locales/fr.json b/locales/fr.json index a6054530c4..a1cba7785d 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -17,6 +17,14 @@ "description": "Vérifier que l’attribut role a une valeur valide pour cet élément", "help": "Le rôle ARIA doit être valide pour cet élément" }, + "aria-command-name": { + "description": "Vérifier que chaque \"button\", \"link\" et \"menuitem\" ARIA a un nom accessible", + "help": "Les commandes ARIA doivent avoir un nom accessible" + }, + "aria-dialog-name": { + "description": "Vérifier que chaque nœud ARIA \"dialog\" et \"alertdialog\" a un nom accessible", + "help": "Les nœuds ARIA \"dialog\" and \"alertdialog\" doivent avoir un nom accessible" + }, "aria-hidden-body": { "description": "Vérifier qu’aria-hidden='true' n’est pas présent sur le corps du document (élément body)", "help": "aria-hidden='true' ne doit pas être présent sur " @@ -29,6 +37,14 @@ "description": "Vérifier que chaque champ de formulaire avec ARIA est doté d’un intitulé accessible", "help": "Les champs de formulaire ARIA ont un intitulé accessible" }, + "aria-meter-name": { + "description": "Vérifier que chaque nœud ARIA \"meter\" a un nom accessible", + "help": "Les nœuds ARIA \"meter\" doivent avoir un nom accessible" + }, + "aria-progressbar-name": { + "description": "Vérifier que chaque nœud ARIA \"progressbar\" a un nom accessible", + "help": "Les nœuds ARIA \"progressbar\" doivent avoir un nom accessible" + }, "aria-required-attr": { "description": "Vérifier que les éléments avec des rôles ARIA ont les attributs ARIA requis", "help": "Les attributs ARIA requis doivent être présents" @@ -49,10 +65,22 @@ "description": "Vérifier que les éléments avec un attribut role utilisent une valeur valide", "help": "Les rôles ARIA doivent se conformer aux valeurs valides" }, + "aria-text": { + "description": "Vérifier que \"role=text\" est uniquement utilisé sur des éléments sans descendants focalisables", + "help": "\"role=text\" ne doit pas avoir de descendant focalisable" + }, "aria-toggle-field-name": { "description": "Vérifier que chaque champ de basculement ARIA a un libellé accessible", "help": "Les champs de basculement ARIA ont un libellé accessible" }, + "aria-tooltip-name": { + "description": "Vérifier que chaque nœud ARIA \"tooltip\" a un nom accessible", + "help": "Les nœuds ARIA \"tooltip\" doivent avoir un nom accessible" + }, + "aria-treeitem-name": { + "description": "Vérifier que chaque nœud ARIA \"treeitem\" a un nom accessible", + "help": "Les nœuds ARIA \"treeitem\" doivent avoir un nom accessible" + }, "aria-valid-attr-value": { "description": "Vérifier que tous les attributs ARIA comportent des valeurs valides", "help": "Les attributs ARIA doivent comporter des valeurs valides" @@ -121,6 +149,10 @@ "description": "Vérifier que les niveaux de titre ont un texte perceptible", "help": "Les niveaux de titre ne doivent pas être vides" }, + "empty-table-header": { + "description": "Vérifier que les entêtes de tableaux ont un texte perceptible", + "help": "Les textes d’entêtes de tableaux ne doivent pas être vides" + }, "focus-order-semantics": { "description": "Vérifier que les éléments dans le parcours du focus ont un rôle approprié", "help": "Les éléments dans le parcours du focus doivent avoir un rôle approprié pour le contenu interactif" @@ -129,6 +161,10 @@ "description": "Vérifier que le champ de formulaire n’a pas plusieurs éléments d’étiquettes", "help": "Le champ de formulaire ne devrait pas comporter plusieurs éléments d’étiquettes" }, + "frame-focusable-content": { + "description": "Vérifier que les éléments et + + +

+ + + + + diff --git a/test/integration/full/isolated-env/isolated-env.js b/test/integration/full/isolated-env/isolated-env.js new file mode 100644 index 0000000000..0359b9d46c --- /dev/null +++ b/test/integration/full/isolated-env/isolated-env.js @@ -0,0 +1,133 @@ +/* global chai */ + +describe('isolated-env test', function() { + 'use strict'; + var fixture = document.querySelector('#fixture'); + var isIE11 = axe.testUtils.isIE11; + var origPartialResults; + var partialResults; + var win; + + // just a nicer assertion error rather than just doing + // done(err) + function doesNotThrow(err, done) { + if (err instanceof chai.AssertionError) { + return done(err); + } + + var error = new chai.AssertionError( + "expected [Function] to not throw an error but '" + + err.toString() + + "' was thrown" + ); + done(error); + } + + function setEmptyReporter() { + win.axeConfigure({ + reporter: function(results, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + callback(results); + } + }); + } + + before(function(done) { + if (isIE11) { + return this.skip(); + } + + axe.testUtils.awaitNestedLoad(function() { + win = fixture.querySelector('#isolated-frame').contentWindow; + var focusableFrame = fixture.querySelector('#focusable-iframe'); + + // trigger frame-focusable-content rule + var iframePromise = focusableFrame.contentWindow.axe.runPartial({ + include: [], + exclude: [], + initiator: false, + focusable: false, + size: { width: 10, height: 10 } + }); + + var promises = [axe.runPartial(), iframePromise]; + Promise.all(promises) + .then(function(r) { + origPartialResults = r; + done(); + }) + .catch(done); + }); + }); + + beforeEach(function() { + // calling axe.finishRun mutates the partial results + // object and prevents calling finishRun again with + // the same object + partialResults = axe.utils.clone(origPartialResults); + + if (win.axeConfigure) { + win.axeConfigure({ reporter: 'v1' }); + } + }); + + it('successfully isolates axe object in iframe', function() { + assert.isUndefined(win.axe); + assert.isDefined(win.axeFinishRun); + assert.isDefined(win.axeConfigure); + }); + + it('after methods do not error by calling window or DOM methods', function(done) { + setEmptyReporter(); + + win + .axeFinishRun(partialResults) + .then(function(results) { + assert.isDefined(results); + done(); + }) + .catch(function(err) { + doesNotThrow(err, done); + }); + }); + + it('runs all rules and after methods', function(done) { + win + .axeFinishRun(partialResults) + .then(function(results) { + assert.lengthOf(results.inapplicable, 0); + done(); + }) + .catch(function(err) { + doesNotThrow(err, done); + }); + }); + + describe('reporters', function() { + var reporters = axe._thisWillBeDeletedDoNotUse.public.reporters; + Object.keys(reporters).forEach(function(reporterName) { + it( + reporterName + + ' reporter does not error by calling window or DOM methods', + function(done) { + win.axeConfigure({ + reporter: reporterName + }); + + win + .axeFinishRun(partialResults) + .then(function(results) { + assert.isDefined(results); + done(); + }) + .catch(function(err) { + doesNotThrow(err, done); + }); + } + ); + }); + }); +}); From 035c14845402f9442519bddac0c5bbb613116c00 Mon Sep 17 00:00:00 2001 From: Dan Tripp <88439449+dan-tripp@users.noreply.github.com> Date: Tue, 31 Aug 2021 18:22:42 -0400 Subject: [PATCH 11/88] refactor(checks/navigation): improve `internal-link-present-evaluate` (#3128) Make `internal-link-present-evaluate` work with virtualNode rather than actualNode. Closes issue #2466 --- .../internal-link-present-evaluate.js | 20 +-- .../navigation/internal-link-present.js | 155 +++++++++--------- 2 files changed, 88 insertions(+), 87 deletions(-) diff --git a/lib/checks/navigation/internal-link-present-evaluate.js b/lib/checks/navigation/internal-link-present-evaluate.js index acf086d43f..d235bfbe2b 100644 --- a/lib/checks/navigation/internal-link-present-evaluate.js +++ b/lib/checks/navigation/internal-link-present-evaluate.js @@ -1,10 +1,10 @@ -import { querySelectorAll } from '../../core/utils'; - -function internalLinkPresentEvaluate(node, options, virtualNode) { - const links = querySelectorAll(virtualNode, 'a[href]'); - return links.some(vLink => { - return /^#[^/!]/.test(vLink.actualNode.getAttribute('href')); - }); -} - -export default internalLinkPresentEvaluate; +import { querySelectorAll } from '../../core/utils'; + +function internalLinkPresentEvaluate(node, options, virtualNode) { + const links = querySelectorAll(virtualNode, 'a[href]'); + return links.some(vLink => { + return /^#[^/!]/.test(vLink.attr('href')); + }); +} + +export default internalLinkPresentEvaluate; diff --git a/test/checks/navigation/internal-link-present.js b/test/checks/navigation/internal-link-present.js index 5ea7efed12..2f3d34d561 100644 --- a/test/checks/navigation/internal-link-present.js +++ b/test/checks/navigation/internal-link-present.js @@ -1,77 +1,78 @@ -describe('internal-link-present', function() { - 'use strict'; - - var fixture = document.getElementById('fixture'); - var shadowSupported = axe.testUtils.shadowSupport.v1; - var checkContext = axe.testUtils.MockCheckContext(); - var checkSetup = axe.testUtils.checkSetup; - var shadowCheckSetup = axe.testUtils.shadowCheckSetup; - - afterEach(function() { - fixture.innerHTML = ''; - axe._tree = undefined; - checkContext.reset(); - }); - - it('should return true when an internal link is found', function() { - var params = checkSetup(''); - assert.isTrue( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hashbang URL was used', function() { - var params = checkSetup(''); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hash route URL was used', function() { - var params = checkSetup(''); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should return false when a hashbang + slash route URL was used', function() { - var params = checkSetup(''); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - it('should otherwise return false', function() { - var params = checkSetup( - '' - ); - assert.isFalse( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - }); - - (shadowSupported ? it : xit)( - 'should return true when internal link is found in shadow dom', - function() { - var params = shadowCheckSetup( - '
', - 'hi' - ); - assert.isTrue( - axe.testUtils - .getCheckEvaluate('internal-link-present') - .apply(checkContext, params) - ); - } - ); -}); +describe('internal-link-present', function() { + 'use strict'; + + var fixture = document.getElementById('fixture'); + var shadowSupported = axe.testUtils.shadowSupport.v1; + var checkContext = axe.testUtils.MockCheckContext(); + var shadowCheckSetup = axe.testUtils.shadowCheckSetup; + var queryFixture = axe.testUtils.queryFixture; + + afterEach(function() { + fixture.innerHTML = ''; + axe._tree = undefined; + checkContext.reset(); + }); + + it('should return true when an internal link is found', function() { + var vNode = queryFixture(''); + assert.isTrue( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hashbang URL was used', function() { + var vNode = queryFixture(''); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hash route URL was used', function() { + var vNode = queryFixture(''); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should return false when a hashbang + slash route URL was used', function() { + var vNode = queryFixture(''); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + it('should otherwise return false', function() { + var vNode = queryFixture( + '' + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + }); + + (shadowSupported ? it : xit)( + 'should return true when internal link is found in shadow dom', + function() { + var params = shadowCheckSetup( + '
', + 'hi' + ); + var vNode = params[2]; + assert.isTrue( + axe.testUtils + .getCheckEvaluate('internal-link-present') + .call(checkContext, null, {}, vNode) + ); + } + ); +}); From 61be7e555152d89c6770679fd6fdac10038f7cd3 Mon Sep 17 00:00:00 2001 From: Gabe <41127686+Zidious@users.noreply.github.com> Date: Tue, 7 Sep 2021 19:54:14 +0100 Subject: [PATCH 12/88] feat: add new ARIA roles (#3138) * Added new roles: mark, suggestion, and comment. Closes issue: https://github.com/dequelabs/axe-core/issues/3122 * added changes requested * tests: add suggestion no children and amend comment * changes requested * fix comment role * amend comment role Co-authored-by: Gabe Olesen --- lib/standards/aria-roles.js | 16 ++++++++++++++++ .../rules/aria-allowed-attr/failures.html | 4 ++++ .../rules/aria-allowed-attr/failures.json | 6 +++++- .../rules/aria-allowed-attr/passes.html | 10 ++++++++++ .../rules/aria-allowed-attr/passes.json | 3 ++- .../aria-required-children.html | 7 +++++++ .../aria-required-children.json | 6 ++++-- .../integration/rules/aria-roles/aria-roles.html | 3 +++ .../integration/rules/aria-roles/aria-roles.json | 5 ++++- 9 files changed, 55 insertions(+), 5 deletions(-) diff --git a/lib/standards/aria-roles.js b/lib/standards/aria-roles.js index de372b3dd5..a21fe4a2b1 100644 --- a/lib/standards/aria-roles.js +++ b/lib/standards/aria-roles.js @@ -147,6 +147,11 @@ const ariaRoles = { allowedAttrs: ['aria-expanded'], superclassRole: ['landmark'] }, + comment: { + type: 'structure', + allowedAttrs: ['aria-level', 'aria-posinset', 'aria-setsize'], + superclassRole: ['article'] + }, definition: { type: 'structure', allowedAttrs: ['aria-expanded'], @@ -391,6 +396,11 @@ const ariaRoles = { accessibleNameRequired: true, childrenPresentational: true }, + mark: { + type: 'structure', + superclassRole: ['section'], + prohibitedAttrs: ['aria-label', 'aria-labelledby'] + }, navigation: { type: 'landmark', allowedAttrs: ['aria-expanded'], @@ -674,6 +684,12 @@ const ariaRoles = { nameFromContent: true, childrenPresentational: true }, + suggestion: { + type: 'structure', + requiredOwned: ['insertion', 'deletion'], + superclassRole: ['section'], + prohibitedAttrs: ['aria-label', 'aria-labelledby'] + }, tab: { type: 'widget', requiredContext: ['tablist'], diff --git a/test/integration/rules/aria-allowed-attr/failures.html b/test/integration/rules/aria-allowed-attr/failures.html index 0f77954a3f..985a64363f 100644 --- a/test/integration/rules/aria-allowed-attr/failures.html +++ b/test/integration/rules/aria-allowed-attr/failures.html @@ -34,3 +34,7 @@ aria-orientation="horizontal" id="fail30" > +
fail
+
fail
+
fail
+
fail
diff --git a/test/integration/rules/aria-allowed-attr/failures.json b/test/integration/rules/aria-allowed-attr/failures.json index bbc6f0a214..5c5fb11ee7 100644 --- a/test/integration/rules/aria-allowed-attr/failures.json +++ b/test/integration/rules/aria-allowed-attr/failures.json @@ -31,6 +31,10 @@ ["#fail27"], ["#fail28"], ["#fail29"], - ["#fail30"] + ["#fail30"], + ["#fail31"], + ["#fail32"], + ["#fail33"], + ["#fail34"] ] } diff --git a/test/integration/rules/aria-allowed-attr/passes.html b/test/integration/rules/aria-allowed-attr/passes.html index b02bd1f62b..d27880688a 100644 --- a/test/integration/rules/aria-allowed-attr/passes.html +++ b/test/integration/rules/aria-allowed-attr/passes.html @@ -1941,3 +1941,13 @@ + + diff --git a/test/integration/rules/aria-allowed-attr/passes.json b/test/integration/rules/aria-allowed-attr/passes.json index 454213f927..769cb1f931 100644 --- a/test/integration/rules/aria-allowed-attr/passes.json +++ b/test/integration/rules/aria-allowed-attr/passes.json @@ -93,6 +93,7 @@ ["#pass88"], ["#pass89"], ["#pass90"], - ["#treegrid"] + ["#treegrid"], + ["#pass91"] ] } diff --git a/test/integration/rules/aria-required-children/aria-required-children.html b/test/integration/rules/aria-required-children/aria-required-children.html index aff30c2ae3..89024d8623 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.html +++ b/test/integration/rules/aria-required-children/aria-required-children.html @@ -55,3 +55,10 @@ + +
+ option + option +
+ +
diff --git a/test/integration/rules/aria-required-children/aria-required-children.json b/test/integration/rules/aria-required-children/aria-required-children.json index 695071b043..05bcfa7185 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.json +++ b/test/integration/rules/aria-required-children/aria-required-children.json @@ -8,7 +8,8 @@ ["#fail4"], ["#fail5"], ["#fail6"], - ["#fail7"] + ["#fail7"], + ["#fail8"] ], "passes": [ ["#pass1"], @@ -17,7 +18,8 @@ ["#pass4"], ["#pass5"], ["#pass6"], - ["#pass7"] + ["#pass7"], + ["#pass8"] ], "incomplete": [ ["#incomplete1"], diff --git a/test/integration/rules/aria-roles/aria-roles.html b/test/integration/rules/aria-roles/aria-roles.html index b00823f4c0..1e96194ace 100644 --- a/test/integration/rules/aria-roles/aria-roles.html +++ b/test/integration/rules/aria-roles/aria-roles.html @@ -111,6 +111,9 @@
ok
ok
ok
+ +
ok
+
ok
diff --git a/test/integration/rules/aria-roles/aria-roles.json b/test/integration/rules/aria-roles/aria-roles.json index 141df46da2..1e744aa129 100644 --- a/test/integration/rules/aria-roles/aria-roles.json +++ b/test/integration/rules/aria-roles/aria-roles.json @@ -129,6 +129,9 @@ ["#pass110"], ["#pass111"], ["#pass112"], - ["#pass113"] + ["#pass113"], + ["#pass114"], + ["#pass115"], + ["#pass116"] ] } From d0d1d59c96d2c618f65cd0f4d8b34f4aa3547609 Mon Sep 17 00:00:00 2001 From: forsti0506 <38582064+forsti0506@users.noreply.github.com> Date: Wed, 8 Sep 2021 17:28:19 +0200 Subject: [PATCH 13/88] docs: add a11y-sitechecker to community projects (#3147) --- doc/projects.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/projects.md b/doc/projects.md index 2d7780f9d6..f5a43bbed4 100644 --- a/doc/projects.md +++ b/doc/projects.md @@ -54,3 +54,4 @@ Add your project/integration to this file and submit a pull request. 1. [axe-sarif-converter](https://github.com/microsoft/axe-sarif-converter) 1. [Selenium.Axe for .NET](https://github.com/TroyWalshProf/SeleniumAxeDotnet) 1. [vue-axe](https://github.com/vue-a11y/vue-axe-next) +1. [a11y-sitechecker](https://github.com/forsti0506/a11y-sitechecker) From 1ee88cb4bb557560f10eab136464c321d4dee81e Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Mon, 13 Sep 2021 23:32:03 +0800 Subject: [PATCH 14/88] fix(nativeSelectValue): update selected value on change (#3154) * Fix nativeSelectValue not picking up selection * Use props instead * Add test for selected prop --- lib/commons/text/form-control-value.js | 2 +- lib/core/base/virtual-node/virtual-node.js | 6 ++++-- test/commons/text/form-control-value.js | 14 ++++++++++++++ test/core/base/virtual-node/virtual-node.js | 10 ++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/commons/text/form-control-value.js b/lib/commons/text/form-control-value.js index 0692b3ae2d..2a4b672649 100644 --- a/lib/commons/text/form-control-value.js +++ b/lib/commons/text/form-control-value.js @@ -106,7 +106,7 @@ function nativeSelectValue(node) { } const options = querySelectorAll(vNode, 'option'); - const selectedOptions = options.filter(option => option.hasAttr('selected')); + const selectedOptions = options.filter(option => option.props.selected); // browser automatically selects the first option if (!selectedOptions.length) { diff --git a/lib/core/base/virtual-node/virtual-node.js b/lib/core/base/virtual-node/virtual-node.js index 55010b977b..4235b23c20 100644 --- a/lib/core/base/virtual-node/virtual-node.js +++ b/lib/core/base/virtual-node/virtual-node.js @@ -62,7 +62,8 @@ class VirtualNode extends AbstractVirtualNode { id, multiple, nodeValue, - value + value, + selected } = this.actualNode; this._cache.props = { @@ -72,7 +73,8 @@ class VirtualNode extends AbstractVirtualNode { type: this._type, multiple, nodeValue, - value + value, + selected }; } diff --git a/test/commons/text/form-control-value.js b/test/commons/text/form-control-value.js index e4eda28157..88f6d39345 100644 --- a/test/commons/text/form-control-value.js +++ b/test/commons/text/form-control-value.js @@ -2,6 +2,7 @@ describe('text.formControlValue', function() { var formControlValue = axe.commons.text.formControlValue; var queryFixture = axe.testUtils.queryFixture; var fixtureSetup = axe.testUtils.fixtureSetup; + var injectIntoFixture = axe.testUtils.injectIntoFixture; var fixture = document.querySelector('#fixture'); function getNodeType(node) { @@ -149,6 +150,19 @@ describe('text.formControlValue', function() { assert.equal(nativeSelectValue(target), 'baz'); }); + it('returns the selected option text after selection', function() { + injectIntoFixture( + '' + ); + fixture.querySelector('#target').value = 'bar'; + var rootNode = axe.setup(fixture); + var target = axe.utils.querySelectorAll(rootNode, '#target')[0]; + assert.equal(nativeSelectValue(target), 'baz'); + }); + it('returns multiple options, space seperated', function() { // Can't apply multiple "selected" props without setting "multiple" var target = queryFixture( diff --git a/test/core/base/virtual-node/virtual-node.js b/test/core/base/virtual-node/virtual-node.js index dbd5459ae0..976035e942 100644 --- a/test/core/base/virtual-node/virtual-node.js +++ b/test/core/base/virtual-node/virtual-node.js @@ -39,6 +39,16 @@ describe('VirtualNode', function() { assert.equal(vNode.props.type, 'text'); }); + it('should reflect selected property', function() { + node = document.createElement('option'); + var vNode = new VirtualNode(node); + assert.equal(vNode.props.selected, false); + + node.selected = true; + vNode = new VirtualNode(node); + assert.equal(vNode.props.selected, true); + }); + it('should lowercase type', function() { var node = document.createElement('input'); node.setAttribute('type', 'COLOR'); From 95d37dd794dc8552d731fabf45244b260da53d8f Mon Sep 17 00:00:00 2001 From: Gabe <41127686+Zidious@users.noreply.github.com> Date: Fri, 24 Sep 2021 16:33:16 +0100 Subject: [PATCH 15/88] fix: check for hidden elements on `aria-errormessage` (#3156) * add visible checks and tests * fix typo * enable screenreader on isVisible * add tests * revert playground * add aria-hidden tests * add test and clean up * fix test to pass if aria-invalid is false on hidden element --- lib/checks/aria/aria-errormessage-evaluate.js | 10 ++- lib/checks/aria/aria-errormessage.json | 3 +- test/checks/aria/errormessage.js | 88 +++++++++++++++++++ .../aria-valid-attr-value.html | 69 +++++++++++++++ .../aria-valid-attr-value.json | 12 ++- 5 files changed, 178 insertions(+), 4 deletions(-) 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( + '' + + '' + ); + 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( + '' + + '' + ); + 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( + '' + + '' + ); + 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( + '' + + '' + ); + 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"], From ad4b165a0e019cd65f70fa5d085d83cea3e7338c Mon Sep 17 00:00:00 2001 From: Kaelig Deloumeau-Prigent Date: Mon, 27 Sep 2021 07:33:16 -0700 Subject: [PATCH 16/88] fix(typescript): allow passing a NodeList to ElementContext (#3161) As per the spec, the context parameter can be passed one of the following: > A `NodeList` such as returned by `document.querySelectorAll`. Source: https://www.deque.com/axe/core-documentation/api-documentation/#context-parameter --- axe.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axe.d.ts b/axe.d.ts index f0ba24b635..8554f4381d 100644 --- a/axe.d.ts +++ b/axe.d.ts @@ -56,7 +56,7 @@ declare namespace axe { type RunCallback = (error: Error, results: AxeResults) => void; - type ElementContext = Node | string | ContextObject; + type ElementContext = Node | NodeList | string | ContextObject; interface TestEngine { name: string; From 404608773abf7b4d069a64931adf4ac7e942b663 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 28 Sep 2021 11:09:23 -0600 Subject: [PATCH 17/88] fix(is-visible): do not error if window.Node does not exist (#3168) * fix(is-visible): do not error if window.Node does not exist * circle * Update test/test-virtual-rules.js Co-authored-by: Wilco Fiers Co-authored-by: Wilco Fiers --- .circleci/config.yml | 16 ++++++++++++++++ lib/commons/dom/is-visible.js | 2 +- package.json | 1 + test/test-virtual-rules.js | 23 +++++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/test-virtual-rules.js diff --git a/.circleci/config.yml b/.circleci/config.yml index c7b1f920a4..fc17df756b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -129,6 +129,16 @@ jobs: - run: npm run build - run: npm run test:locales + # Test virtual rules + test_virtual_rules: + <<: *defaults + <<: *unix_box + steps: + - checkout + - <<: *restore_dependency_cache_unix + - run: npm run build + - run: npm run test:virtual-rules + # Run the test suite for nightly builds. test_nightly: <<: *defaults @@ -262,6 +272,9 @@ workflows: - test_locales: requires: - test_unix + - test_virtual_rules: + requires: + - test_unix - build_api_docs: requires: - test_unix @@ -279,6 +292,7 @@ workflows: - test_win - test_examples - test_locales + - test_virtual_rules - build_api_docs - test_rule_help_version - test_node @@ -293,6 +307,7 @@ workflows: - test_unix - test_examples - test_locales + - test_virtual_rules - build_api_docs filters: branches: @@ -304,6 +319,7 @@ workflows: - test_unix - test_examples - test_locales + - test_virtual_rules - build_api_docs - test_rule_help_version - test_node diff --git a/lib/commons/dom/is-visible.js b/lib/commons/dom/is-visible.js index 7a89d525e9..2a3ae2ffa3 100644 --- a/lib/commons/dom/is-visible.js +++ b/lib/commons/dom/is-visible.js @@ -117,7 +117,7 @@ function isVisible(el, screenReader, recursed) { el = vNode ? vNode.actualNode : el; const cacheName = '_isVisible' + (screenReader ? 'ScreenReader' : ''); - const { DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE } = window.Node; + const { DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE } = window.Node ?? {}; const nodeType = vNode ? vNode.props.nodeType : el.nodeType; const nodeName = vNode ? vNode.props.nodeName : el.nodeName.toLowerCase(); diff --git a/package.json b/package.json index adfdc009af..c125bd919f 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "test:act": "karma start test/act-mapping/karma.config.js", "test:act:debug": "npm run test:act -- --no-single-run --browsers=Chrome", "test:locales": "mocha test/test-locales.js", + "test:virtual-rules": "mocha test/test-virtual-rules.js", "test:rule-help-version": "mocha test/test-rule-help-version.js", "test:node": "mocha test/node/*.js", "version": "echo \"use 'npm run release' to bump axe-core version\" && exit 1", diff --git a/test/test-virtual-rules.js b/test/test-virtual-rules.js new file mode 100644 index 0000000000..b00291d56d --- /dev/null +++ b/test/test-virtual-rules.js @@ -0,0 +1,23 @@ +var path = require('path'); +var assert = require('chai').assert; +var glob = require('glob'); +var axe = require('../axe'); + +var files = glob.sync(path.join(__dirname, 'integration/virtual-rules/*.js')); + +before(function() { + global.axe = axe; + global.assert = assert; +}); + +after(function() { + delete global.axe; + delete global.assert; +}); + +describe('virtual-rule node tests', function() { + files.forEach(function(file) { + // load the test file and run with global axe and assert now defined + require(file); + }); +}); From cfa900d57265907b638dad36ba405a5b40dbde9c Mon Sep 17 00:00:00 2001 From: Gabe <41127686+Zidious@users.noreply.github.com> Date: Fri, 1 Oct 2021 16:50:29 +0100 Subject: [PATCH 18/88] fix(aria-allowed-attr): check for invalid `aria-attributes` for `role="row"` (#3160) --- doc/check-options.md | 28 +++++ lib/checks/aria/aria-allowed-attr-evaluate.js | 41 +++++- lib/checks/aria/aria-allowed-attr.json | 8 ++ lib/checks/aria/aria-allowed-role-evaluate.js | 1 - test/checks/aria/allowed-attr.js | 117 ++++++++++++++++++ .../rules/aria-allowed-attr/failures.html | 14 +++ .../rules/aria-allowed-attr/failures.json | 10 +- 7 files changed, 213 insertions(+), 6 deletions(-) diff --git a/doc/check-options.md b/doc/check-options.md index 17f5adac6c..4a95f84dd7 100644 --- a/doc/check-options.md +++ b/doc/check-options.md @@ -199,6 +199,34 @@ All checks allow these global options: +### aria-allowed-attr + + + + + + + + + + + + + + + + +
OptionDefaultDescription
+ validTreeRowAttrs + +
[
+  'aria-posinset',
+  'aria-setsize',
+  'aria-expanded',
+  'aria-level',
+]
+
List of ARIA attributes that are not allowed on role=row when a descendant of a table or a grid
+ ### color-contrast | Option | Default | Description | diff --git a/lib/checks/aria/aria-allowed-attr-evaluate.js b/lib/checks/aria/aria-allowed-attr-evaluate.js index 19775a9528..add21f2b7b 100644 --- a/lib/checks/aria/aria-allowed-attr-evaluate.js +++ b/lib/checks/aria/aria-allowed-attr-evaluate.js @@ -1,5 +1,6 @@ -import { uniqueArray } from '../../core/utils'; +import { uniqueArray, closest } from '../../core/utils'; import { getRole, allowedAttr, validateAttr } from '../../commons/aria'; +import cache from '../../core/base/cache'; /** * Check if each ARIA attribute on an element is allowed for its semantic role. @@ -27,21 +28,53 @@ import { getRole, allowedAttr, validateAttr } from '../../commons/aria'; */ function ariaAllowedAttrEvaluate(node, options, virtualNode) { const invalid = []; - const role = getRole(virtualNode); const attrs = virtualNode.attrNames; let allowed = allowedAttr(role); - // @deprecated: allowed attr options to pass more attrs. // configure the standards spec instead if (Array.isArray(options[role])) { allowed = uniqueArray(options[role].concat(allowed)); } + let tableMap = cache.get('aria-allowed-attr-table'); + if (!tableMap) { + tableMap = new WeakMap(); + cache.set('aria-allowed-attr-table', tableMap); + } + + function validateRowAttrs() { + // check if the parent exists otherwise a TypeError will occur (virtual-nodes specifically) + if (virtualNode.parent && role === 'row') { + const table = closest( + virtualNode, + 'table, [role="treegrid"], [role="table"], [role="grid"]' + ); + + let tableRole = tableMap.get(table); + if (table && !tableRole) { + tableRole = getRole(table); + tableMap.set(table, tableRole); + } + if (['table', 'grid'].includes(tableRole) && role === 'row') { + return true; + } + } + } + // Allows options to be mapped to object e.g. {'aria-level' : validateRowAttrs} + const ariaAttr = Array.isArray(options.validTreeRowAttrs) + ? options.validTreeRowAttrs + : []; + const preChecks = {}; + ariaAttr.forEach(attr => { + preChecks[attr] = validateRowAttrs; + }); if (allowed) { for (let i = 0; i < attrs.length; i++) { const attrName = attrs[i]; - if (validateAttr(attrName) && !allowed.includes(attrName)) { + if (validateAttr(attrName) && preChecks[attrName]?.()) { + invalid.push(attrName + '="' + virtualNode.attr(attrName) + '"'); + } else if (validateAttr(attrName) && !allowed.includes(attrName)) { invalid.push(attrName + '="' + virtualNode.attr(attrName) + '"'); } } diff --git a/lib/checks/aria/aria-allowed-attr.json b/lib/checks/aria/aria-allowed-attr.json index 9d8386d570..4079b3ebcb 100644 --- a/lib/checks/aria/aria-allowed-attr.json +++ b/lib/checks/aria/aria-allowed-attr.json @@ -1,6 +1,14 @@ { "id": "aria-allowed-attr", "evaluate": "aria-allowed-attr-evaluate", + "options": { + "validTreeRowAttrs": [ + "aria-posinset", + "aria-setsize", + "aria-expanded", + "aria-level" + ] + }, "metadata": { "impact": "critical", "messages": { diff --git a/lib/checks/aria/aria-allowed-role-evaluate.js b/lib/checks/aria/aria-allowed-role-evaluate.js index e681e812de..5ca99e9fc9 100644 --- a/lib/checks/aria/aria-allowed-role-evaluate.js +++ b/lib/checks/aria/aria-allowed-role-evaluate.js @@ -27,7 +27,6 @@ function ariaAllowedRoleEvaluate(node, options = {}, virtualNode) { } const unallowedRoles = getElementUnallowedRoles(virtualNode, allowImplicit); - if (unallowedRoles.length) { this.data(unallowedRoles); if (!isVisible(virtualNode, true)) { diff --git a/test/checks/aria/allowed-attr.js b/test/checks/aria/allowed-attr.js index e63e64bbb9..8a6cc452a2 100644 --- a/test/checks/aria/allowed-attr.js +++ b/test/checks/aria/allowed-attr.js @@ -97,6 +97,123 @@ describe('aria-allowed-attr', function() { ); assert.isNull(checkContext._data); }); + describe('invalid aria-attributes when used on role=row as a descendant of a table or a grid', function() { + [ + 'aria-posinset="1"', + 'aria-setsize="1"', + 'aria-expanded="true"', + 'aria-level="1"' + ].forEach(function(attrName) { + it( + 'should return false when ' + + attrName + + ' is used on role=row thats parent is a table', + function() { + var vNode = queryFixture( + '
' + + '
' + + '
' + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-allowed-attr') + .call(checkContext, null, null, vNode) + ); + assert.isNotNull(checkContext._data); + } + ); + }); + + [ + 'aria-posinset="1"', + 'aria-setsize="1"', + 'aria-expanded="true"', + 'aria-level="1"' + ].forEach(function(attrName) { + it( + 'should return false when ' + + attrName + + ' is used on role=row thats parent is a grid', + function() { + var vNode = queryFixture( + '
' + + '
' + + '
' + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-allowed-attr') + .call(checkContext, null, null, vNode) + ); + assert.isNotNull(checkContext._data); + } + ); + }); + }); + + describe('options.invalidRowAttrs on role=row when a descendant of a table or a grid', function() { + it('should return false when provided a single aria-attribute is provided for a table', function() { + axe.configure({ + checks: [ + { + id: 'aria-allowed-attr', + options: { + validTreeRowAttrs: ['aria-posinset'] + } + } + ] + }); + + var options = { + validTreeRowAttrs: ['aria-posinset'] + }; + var vNode = queryFixture( + '
' + + '
' + + '
' + ); + + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-allowed-attr') + .call(checkContext, null, options, vNode) + ); + assert.isNotNull(checkContext._data); + }); + + it('should return false when provided a single aria-attribute is provided for a grid', function() { + axe.configure({ + checks: [ + { + id: 'aria-allowed-attr', + options: { + validTreeRowAttrs: ['aria-level'] + } + } + ] + }); + + var options = { + validTreeRowAttrs: ['aria-level'] + }; + var vNode = queryFixture( + '
' + + '
' + + '
' + ); + + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-allowed-attr') + .call(checkContext, null, options, vNode) + ); + assert.isNotNull(checkContext._data); + }); + }); describe('options', function() { it('should allow provided attribute names for a role', function() { diff --git a/test/integration/rules/aria-allowed-attr/failures.html b/test/integration/rules/aria-allowed-attr/failures.html index 985a64363f..578b339141 100644 --- a/test/integration/rules/aria-allowed-attr/failures.html +++ b/test/integration/rules/aria-allowed-attr/failures.html @@ -38,3 +38,17 @@
fail
fail
fail
+ +
+ +
+
+
+
+ +
+ +
+
+
+
diff --git a/test/integration/rules/aria-allowed-attr/failures.json b/test/integration/rules/aria-allowed-attr/failures.json index 5c5fb11ee7..ccedf0b10f 100644 --- a/test/integration/rules/aria-allowed-attr/failures.json +++ b/test/integration/rules/aria-allowed-attr/failures.json @@ -35,6 +35,14 @@ ["#fail31"], ["#fail32"], ["#fail33"], - ["#fail34"] + ["#fail34"], + ["#fail35"], + ["#fail36"], + ["#fail37"], + ["#fail38"], + ["#fail39"], + ["#fail40"], + ["#fail41"], + ["#fail42"] ] } From 5908f0d644c20e7091329bd8bbeb191837d27feb Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 1 Oct 2021 10:44:09 -0600 Subject: [PATCH 19/88] fix(color-contrast): account for 0 width scroll regions with children (#3172) --- lib/commons/dom/is-visible.js | 8 ++++++-- test/commons/dom/is-visible.js | 8 ++++++++ test/integration/rules/color-contrast/color-contrast.html | 6 ++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/commons/dom/is-visible.js b/lib/commons/dom/is-visible.js index 2a3ae2ffa3..8cb847719d 100644 --- a/lib/commons/dom/is-visible.js +++ b/lib/commons/dom/is-visible.js @@ -186,12 +186,15 @@ function isVisible(el, screenReader, recursed) { // hidden from visual users const elHeight = parseInt(style.getPropertyValue('height')); + const elWidth = parseInt(style.getPropertyValue('width')); // ways to hide content visually - const scrollableWithZeroHeight = getScroll(el) && elHeight === 0; + const scroll = getScroll(el); + const scrollableWithZeroHeight = scroll && elHeight === 0; + const scrollableWithZeroWidth = scroll && elWidth === 0; const posAbsoluteOverflowHiddenAndSmall = style.getPropertyValue('position') === 'absolute' && - elHeight < 2 && + (elHeight < 2 || elWidth < 2) && style.getPropertyValue('overflow') === 'hidden'; if ( @@ -199,6 +202,7 @@ function isVisible(el, screenReader, recursed) { (isClipped(style) || style.getPropertyValue('opacity') === '0' || scrollableWithZeroHeight || + scrollableWithZeroWidth || posAbsoluteOverflowHiddenAndSmall) ) { return false; diff --git a/test/commons/dom/is-visible.js b/test/commons/dom/is-visible.js index d1b390d4f8..a85276cab0 100644 --- a/test/commons/dom/is-visible.js +++ b/test/commons/dom/is-visible.js @@ -261,6 +261,14 @@ describe('dom.isVisible', function() { assert.isFalse(axe.commons.dom.isVisible(el)); }); + it('should return false for 0 width scrollable region', function() { + fixture.innerHTML = + '
Hello!
'; + var el = document.getElementById('target'); + + assert.isFalse(axe.commons.dom.isVisible(el)); + }); + it('returns false for `AREA` without closest `MAP` element', function() { var vNode = queryFixture( '' diff --git a/test/integration/rules/color-contrast/color-contrast.html b/test/integration/rules/color-contrast/color-contrast.html index 17a3d133c3..2a0d3ed153 100644 --- a/test/integration/rules/color-contrast/color-contrast.html +++ b/test/integration/rules/color-contrast/color-contrast.html @@ -248,3 +248,9 @@ ₠ ₡ ₢ ₣
+ +
+
+ Hello World +
+
From 400a2308510246d64d37fac3db375201610cd7e7 Mon Sep 17 00:00:00 2001 From: Gabe <41127686+Zidious@users.noreply.github.com> Date: Mon, 4 Oct 2021 16:56:57 +0100 Subject: [PATCH 20/88] fix(p-as-heading): `p-as-heading` rule to account for `textContent` length (#3145) --- doc/check-options.md | 19 ++++- doc/rule-descriptions.md | 2 +- .../navigation/p-as-heading-evaluate.js | 13 +++ lib/checks/navigation/p-as-heading.json | 7 +- test/checks/navigation/p-as-heading.js | 83 ++++++++++++++++--- .../rules/p-as-heading/p-as-heading.html | 13 ++- .../rules/p-as-heading/p-as-heading.json | 3 +- 7 files changed, 118 insertions(+), 22 deletions(-) diff --git a/doc/check-options.md b/doc/check-options.md index 4a95f84dd7..0d733f4b14 100644 --- a/doc/check-options.md +++ b/doc/check-options.md @@ -443,8 +443,25 @@ h6:not([role]), { "size": 1.4 } ] - Common CSS values used to display `p` elements as `h1-h6` elements determining if a `p` element is being improperly repurposed + + + passLength + + +
"passLength": 1
+ + Relative length, if the the candidate heading is X times or greater the length of the candidate paragraph, it will pass. + + + + faiLength + + +
"failLength": 0.5
+ + Relative length, if the the candidate heading is X times or less the length of the candidate paragraph, it can fail. + diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 372def1e2b..e145658a76 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -124,7 +124,7 @@ Rules we are still testing and developing. They are not enabled by default in ax | [label-content-name-mismatch](https://dequeuniversity.com/rules/axe/4.3/label-content-name-mismatch?application=RuleDescription) | Ensures that elements labelled through their content must have their visible text as part of their accessible name | Serious | cat.semantics, wcag21a, wcag253, experimental | failure | [2ee8b8](https://act-rules.github.io/rules/2ee8b8) | | [link-in-text-block](https://dequeuniversity.com/rules/axe/4.3/link-in-text-block?application=RuleDescription) | Links can be distinguished without relying on color | Serious | cat.color, experimental, wcag2a, wcag141 | failure, needs review | | | [no-autoplay-audio](https://dequeuniversity.com/rules/axe/4.3/no-autoplay-audio?application=RuleDescription) | Ensures <video> or <audio> elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio | Moderate | cat.time-and-media, wcag2a, wcag142, experimental | failure, needs review | [80f0bf](https://act-rules.github.io/rules/80f0bf) | -| [p-as-heading](https://dequeuniversity.com/rules/axe/4.3/p-as-heading?application=RuleDescription) | Ensure p elements are not used to style headings | Serious | cat.semantics, wcag2a, wcag131, experimental | failure | | +| [p-as-heading](https://dequeuniversity.com/rules/axe/4.3/p-as-heading?application=RuleDescription) | Ensure p elements are not used to style headings | Serious | cat.semantics, wcag2a, wcag131, experimental | failure, needs review | | | [table-fake-caption](https://dequeuniversity.com/rules/axe/4.3/table-fake-caption?application=RuleDescription) | Ensure that tables with a caption use the <caption> element. | Serious | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | | [td-has-header](https://dequeuniversity.com/rules/axe/4.3/td-has-header?application=RuleDescription) | Ensure that each non-empty data cell in a large table has one or more table headers | Critical | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | failure | | diff --git a/lib/checks/navigation/p-as-heading-evaluate.js b/lib/checks/navigation/p-as-heading-evaluate.js index 61a9a1f3d1..4a7e35917f 100644 --- a/lib/checks/navigation/p-as-heading-evaluate.js +++ b/lib/checks/navigation/p-as-heading-evaluate.js @@ -79,6 +79,16 @@ function pAsHeadingEvaluate(node, options, virtualNode) { const nextStyle = nextSibling ? getStyleValues(nextSibling) : null; const prevStyle = prevSibling ? getStyleValues(prevSibling) : null; + const optionsPassLength = options.passLength; + const optionsFailLength = options.failLength; + + const headingLength = node.textContent.trim().length; + const paragraphLength = nextSibling?.textContent.trim().length; + + if (headingLength > paragraphLength * optionsPassLength) { + return true; + } + if (!nextStyle || !isHeaderStyle(currStyle, nextStyle, margins)) { return true; } @@ -92,6 +102,9 @@ function pAsHeadingEvaluate(node, options, virtualNode) { return undefined; } + if (headingLength > paragraphLength * optionsFailLength) { + return undefined; + } return false; } diff --git a/lib/checks/navigation/p-as-heading.json b/lib/checks/navigation/p-as-heading.json index 38272045c6..bb7d78a91c 100644 --- a/lib/checks/navigation/p-as-heading.json +++ b/lib/checks/navigation/p-as-heading.json @@ -18,13 +18,16 @@ { "size": 1.4 } - ] + ], + "passLength": 1, + "failLength": 0.5 }, "metadata": { "impact": "serious", "messages": { "pass": "

elements are not styled as headings", - "fail": "Heading elements should be used instead of styled p elements" + "fail": "Heading elements should be used instead of styled

elements", + "incomplete": "Unable to determine if

elements are styled as headings" } } } diff --git a/test/checks/navigation/p-as-heading.js b/test/checks/navigation/p-as-heading.js index 97d1fde38b..40edbfef05 100644 --- a/test/checks/navigation/p-as-heading.js +++ b/test/checks/navigation/p-as-heading.js @@ -36,7 +36,7 @@ describe('p-as-heading', function() { it('returns false if the font-weight is heavier', function() { var params = checkSetup( - '

elm 1

' + '

elm 2

', + '

elm 1

' + '

elm 2elm 2

', testOptions ); assert.isFalse( @@ -46,7 +46,7 @@ describe('p-as-heading', function() { it('returns false if the font-size is bigger', function() { var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', testOptions ); assert.isFalse( @@ -56,7 +56,7 @@ describe('p-as-heading', function() { it('returns false if the fake heading is italic and the text is not', function() { var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', testOptions ); assert.isFalse( @@ -67,7 +67,7 @@ describe('p-as-heading', function() { it('returns true if both texts are bold, italic and larger', function() { var params = checkSetup( '

elm 1

' + - '

elm 2

', + '

elm 2elm 2

', testOptions ); assert.isTrue( @@ -77,7 +77,7 @@ describe('p-as-heading', function() { it('considers styles of elements inside the paragraph', function() { var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', testOptions ); assert.isFalse( @@ -87,7 +87,7 @@ describe('p-as-heading', function() { it('ignores empty child element for style', function() { var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', testOptions ); assert.isFalse( @@ -97,7 +97,7 @@ describe('p-as-heading', function() { it('considers styles of elements that do not contain all the text', function() { var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', testOptions ); assert.isTrue( @@ -108,7 +108,7 @@ describe('p-as-heading', function() { it('returns undefined instead of false if the element is inside a blockquote', function() { var params = checkSetup( '
' + - '

elm 1

elm 2

' + + '

elm 1

elm 2elm 2

' + '
', testOptions ); @@ -120,7 +120,7 @@ describe('p-as-heading', function() { it('returns true over undefined from within a blockquote', function() { var params = checkSetup( '
' + - '

elm 1

elm 2

' + + '

elm 1

elm 2elm 2

' + '
', testOptions ); @@ -141,12 +141,68 @@ describe('p-as-heading', function() { ); }); + it('returns true if the heading is greater than the paragraph', function() { + var params = checkSetup( + '

elm1elm1

' + '

elm2

', + testOptions + ); + assert.isTrue( + axe.testUtils.getCheckEvaluate('p-as-heading').apply(checkContext, params) + ); + }); + + it('returns undefined if the heading is twice as long but not greater than the length of the pararaph', function() { + var params = checkSetup( + '

elm1elm

' + '

elm2elm2

', + testOptions + ); + assert.isUndefined( + axe.testUtils.getCheckEvaluate('p-as-heading').apply(checkContext, params) + ); + }); + + describe('options.passLength and options.failLength', function() { + it('returns true if the heading is greater than the paragraph using options.passLength', function() { + var options = { + margins: [{ weight: 100 }, { italic: true }, { size: 1.2 }], + passLength: 2 + }; + + var params = checkSetup( + '

elm1elm1elm1

' + '

elm2

', + options + ); + assert.isTrue( + axe.testUtils + .getCheckEvaluate('p-as-heading') + .apply(checkContext, params) + ); + }); + + it('returns undefined if the heading is twice as long but not greater than the length of the pararaph using options.failLength ', function() { + var options = { + margins: [{ weight: 100 }, { italic: true }, { size: 1.2 }], + failLength: 0.6 + }; + var params = checkSetup( + '

elm1elm

' + + '

elm2elm2elm2

', + options + ); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('p-as-heading') + .apply(checkContext, params) + ); + }); + }); + describe('option.margin', function() { it('passes if no margins are set', function() { var options = {}; var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', options ); assert.isTrue( @@ -162,7 +218,7 @@ describe('p-as-heading', function() { }; var params = checkSetup( - '

elm 1

elm 2

', + '

elm 1

elm 2elm 2

', options ); assert.isTrue( @@ -179,7 +235,7 @@ describe('p-as-heading', function() { var params = checkSetup( '

elm 1

' + - '

elm 2

', + '

elm 2elm 2

', options ); assert.isFalse( @@ -211,7 +267,8 @@ describe('p-as-heading', function() { }; var params = checkSetup( - '

elm 1

' + '

elm 2

', + '

elm 1

' + + '

elm 2elm 2

', options ); assert.isFalse( diff --git a/test/integration/rules/p-as-heading/p-as-heading.html b/test/integration/rules/p-as-heading/p-as-heading.html index 5ffd17d5a0..1be3c19860 100644 --- a/test/integration/rules/p-as-heading/p-as-heading.html +++ b/test/integration/rules/p-as-heading/p-as-heading.html @@ -43,29 +43,34 @@

A paragraph!

+
+

Hello World

+

Hello

+
+

Some text

-

A paragraph!

+

A paragraph, A paragraph!

Some text

-

A paragraph!

+

A paragraph, A paragraph!

Some text

-

A paragraph!

+

A paragraph, A paragraph!

Some text

Some text

-

A paragraph!

+

A paragraph, A paragraph!

diff --git a/test/integration/rules/p-as-heading/p-as-heading.json b/test/integration/rules/p-as-heading/p-as-heading.json index b8c106884e..5a2a189659 100644 --- a/test/integration/rules/p-as-heading/p-as-heading.json +++ b/test/integration/rules/p-as-heading/p-as-heading.json @@ -7,7 +7,8 @@ ["#passed2"], ["#passed3"], ["#passed4"], - ["#passed5"] + ["#passed5"], + ["#passed6"] ], "incomplete": [["#canttell1"], ["#canttell2"]] } From a7ec0a830a705d355b9569bb1ab083b32783ab9d Mon Sep 17 00:00:00 2001 From: Gabe <41127686+Zidious@users.noreply.github.com> Date: Mon, 4 Oct 2021 17:43:01 +0100 Subject: [PATCH 21/88] chore(p-as-heading): add `margin` description back to `check-options.md` (#3180) --- doc/check-options.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/check-options.md b/doc/check-options.md index 0d733f4b14..d6204d859d 100644 --- a/doc/check-options.md +++ b/doc/check-options.md @@ -443,6 +443,7 @@ h6:not([role]), { "size": 1.4 } ] + Common CSS values used to display `p` elements as `h1-h6` elements determining if a `p` element is being improperly repurposed From 6e714f4bff6b0bcd219f43fff86df64bfec74356 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Tue, 5 Oct 2021 08:51:45 -0600 Subject: [PATCH 22/88] tests: check that every check has a message for every return type and messageKey (#3181) * tests: check that every check has a message for every return type and messageKey * finalize * fixes * typo --- lib/checks/color/color-contrast-evaluate.js | 42 ++++++----- test/checks/shared/non-empty-if-present.js | 2 +- test/testutils.js | 78 ++++++++++++++++++++- 3 files changed, 101 insertions(+), 21 deletions(-) diff --git a/lib/checks/color/color-contrast-evaluate.js b/lib/checks/color/color-contrast-evaluate.js index eabf6aa536..18a58f4e4b 100644 --- a/lib/checks/color/color-contrast-evaluate.js +++ b/lib/checks/color/color-contrast-evaluate.js @@ -41,7 +41,10 @@ export default function colorContrastEvaluate(node, options, virtualNode) { // if element or a parent has pseudo content then we need to mark // as needs review - const pseudoElm = findPseudoElement(virtualNode, { ignorePseudo, pseudoSizeThreshold }) + const pseudoElm = findPseudoElement(virtualNode, { + ignorePseudo, + pseudoSizeThreshold + }); if (pseudoElm) { this.data({ messageKey: 'pseudoContent' }); this.relatedNodes(pseudoElm.actualNode); @@ -103,7 +106,7 @@ export default function colorContrastEvaluate(node, options, virtualNode) { let missing; if (bgColor === null) { missing = incompleteData.get('bgColor'); - } else { + } else if (!isValid) { missing = contrastContributor; } @@ -111,7 +114,7 @@ export default function colorContrastEvaluate(node, options, virtualNode) { const shortTextContent = visibleText.length === 1; if (equalRatio) { missing = incompleteData.set('bgColor', 'equalRatio'); - } else if (shortTextContent && !ignoreLength) { + } else if (!isValid && shortTextContent && !ignoreLength) { // Check that the text content is a single character long missing = 'shortTextContent'; } @@ -148,27 +151,31 @@ export default function colorContrastEvaluate(node, options, virtualNode) { return isValid; } -function findPseudoElement(vNode, { - pseudoSizeThreshold = 0.25, - ignorePseudo = false -}) { +function findPseudoElement( + vNode, + { pseudoSizeThreshold = 0.25, ignorePseudo = false } +) { if (ignorePseudo) { return; } const rect = vNode.boundingClientRect; const minimumSize = rect.width * rect.height * pseudoSizeThreshold; do { - const beforeSize = getPseudoElementArea(vNode.actualNode, ':before') - const afterSize = getPseudoElementArea(vNode.actualNode, ':after') + const beforeSize = getPseudoElementArea(vNode.actualNode, ':before'); + const afterSize = getPseudoElementArea(vNode.actualNode, ':after'); if (beforeSize + afterSize > minimumSize) { - return vNode // Combined area of before and after exceeds the minimum size + return vNode; // Combined area of before and after exceeds the minimum size } - } while (vNode = vNode.parent); + } while ((vNode = vNode.parent)); } -const getPseudoElementArea = memoize(function getPseudoElementArea(node, pseudo) { +const getPseudoElementArea = memoize(function getPseudoElementArea( + node, + pseudo +) { const style = window.getComputedStyle(node, pseudo); - const matchPseudoStyle = (prop, value) => style.getPropertyValue(prop) === value; + const matchPseudoStyle = (prop, value) => + style.getPropertyValue(prop) === value; if ( matchPseudoStyle('content', 'none') || matchPseudoStyle('display', 'none') || @@ -190,9 +197,7 @@ const getPseudoElementArea = memoize(function getPseudoElementArea(node, pseudo) const pseudoHeight = parseUnit(style.getPropertyValue('height')); if (pseudoWidth.unit !== 'px' || pseudoHeight.unit !== 'px') { // IE doesn't normalize to px. Infinity gets everything to undefined - return (pseudoWidth.value === 0 || pseudoHeight.value === 0 - ? 0 : Infinity - ); + return pseudoWidth.value === 0 || pseudoHeight.value === 0 ? 0 : Infinity; } return pseudoWidth.value * pseudoHeight.value; }); @@ -200,8 +205,9 @@ const getPseudoElementArea = memoize(function getPseudoElementArea(node, pseudo) function textIsEmojis(visibleText) { const options = { nonBmp: true }; const hasUnicodeChars = hasUnicode(visibleText, options); - const hasNonUnicodeChars = sanitize(removeUnicode(visibleText, options)) === '' - return hasUnicodeChars && hasNonUnicodeChars + const hasNonUnicodeChars = + sanitize(removeUnicode(visibleText, options)) === ''; + return hasUnicodeChars && hasNonUnicodeChars; } function parseUnit(str) { diff --git a/test/checks/shared/non-empty-if-present.js b/test/checks/shared/non-empty-if-present.js index 48b772b4cd..ee0bf6ef36 100644 --- a/test/checks/shared/non-empty-if-present.js +++ b/test/checks/shared/non-empty-if-present.js @@ -23,7 +23,7 @@ describe('non-empty-if-present', function() { assert.isFalse( axe.testUtils - .getCheckEvaluate('non-empty-if-present') + .getCheckEvaluate('non-empty-if-present', { verifyMessage: false }) .call(checkContext, null, {}, vNode) ); assert.equal(checkContext._data.messageKey, 'has-label'); diff --git a/test/testutils.js b/test/testutils.js index 8c60d13a93..fdc5a8741d 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -25,6 +25,30 @@ if (!fixture) { document.body.insertBefore(fixture, document.body.firstChild); } +// determine which checks are used only in the `none` array of rules +var noneChecks = []; + +function verifyIsNoneCheck(check) { + var index = noneChecks.indexOf(check); + if (index !== -1) { + noneChecks.splice(index, 1); + } +} + +axe._audit.rules.forEach(function(rule) { + rule.none.forEach(function(check) { + check = check.id || check; + if (noneChecks.indexOf(check) === -1) { + noneChecks.push(check); + } + }); +}); + +axe._audit.rules.forEach(function(rule) { + rule.any.forEach(verifyIsNoneCheck); + rule.all.forEach(verifyIsNoneCheck); +}); + /** * Create a check context for mocking/resetting data and relatedNodes in tests * @@ -408,11 +432,61 @@ testUtils.queryFixture = function queryFixture(html, query) { * @param {String} checkId - ID of the check * @return Function */ -testUtils.getCheckEvaluate = function getCheckEvaluate(checkId) { +testUtils.getCheckEvaluate = function getCheckEvaluate(checkId, testOptions) { var check = checks[checkId]; + testOptions = testOptions || {}; + return function evaluateWrapper(node, options, virtualNode, context) { var opts = check.getOptions(options); - return check.evaluate.call(this, node, opts, virtualNode, context); + var result = check.evaluate.call(this, node, opts, virtualNode, context); + + // ensure that every result has a corresponding message + if (testOptions.verifyMessage !== false) { + var messages = axe._audit.data.checks[checkId].messages; + var messageKey = this._data && this._data.messageKey; + + // see how the check is used to know where to find the message + // e.g. a check used only in the `none` array of a rule will look at + // the messageKey of a passing result in the `fail` messages + var keyResult = result; + var isNoneCheck = noneChecks.indexOf(checkId) !== -1; + if (isNoneCheck) { + keyResult = result === true ? false : result === false ? true : result; + } + + var key = + keyResult === true + ? 'pass' + : keyResult === false + ? 'fail' + : 'incomplete'; + var noneCheckMessage = isNoneCheck + ? '. Note that since this check is only used in the "none" array of all rules, the messages use the inverse of the result (e.g. a result of false uses the "pass" messages)' + : ''; + + assert.exists( + messages[key], + 'Missing "' + + key + + '" message for check result of ' + + result + + noneCheckMessage + ); + if (messageKey) { + assert.exists( + messages[key][messageKey], + 'Missing ' + + key + + ' message key "' + + messageKey + + '" for check result of ' + + result + + noneCheckMessage + ); + } + } + + return result; }; }; From 699697bc237b6c69050e4572ba5cfdc5f338f450 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 6 Oct 2021 10:15:03 -0600 Subject: [PATCH 23/88] fix(color-contrast): account for elements that do not fill entire bounding size (#3186) * fix(color-contrast): account for elements that do not fill entire bounding size * not private --- lib/commons/dom/get-rect-stack.js | 45 ++++++---- test/checks/color/color-contrast.js | 121 ++++++++++++++++++-------- test/commons/dom/get-element-stack.js | 40 +++++++++ 3 files changed, 153 insertions(+), 53 deletions(-) diff --git a/lib/commons/dom/get-rect-stack.js b/lib/commons/dom/get-rect-stack.js index 06172262f4..2f9c5183e3 100644 --- a/lib/commons/dom/get-rect-stack.js +++ b/lib/commons/dom/get-rect-stack.js @@ -360,6 +360,8 @@ function addNodeToGrid(grid, vNode) { const endRow = ((y + rect.height) / gridSize) | 0; const endCol = ((x + rect.width) / gridSize) | 0; + grid.numCols = Math.max(grid.numCols ?? 0, endCol); + for (let row = startRow; row <= endRow; row++) { grid.cells[row] = grid.cells[row] || []; @@ -475,21 +477,34 @@ export function getRectStack(grid, rect, recursed = false) { // went with pixel perfect collision rather than rounding const row = (y / gridSize) | 0; const col = (x / gridSize) | 0; - let stack = grid.cells[row][col].filter(gridCellNode => { - return gridCellNode.clientRects.find(clientRect => { - const rectX = clientRect.left; - const rectY = clientRect.top; - - // perform an AABB (axis-aligned bounding box) collision check for the - // point inside the rect - return ( - x <= rectX + clientRect.width && - x >= rectX && - y <= rectY + clientRect.height && - y >= rectY - ); - }); - }); + + // we're making an assumption that there cannot be an element in the + // grid which escapes the grid bounds. For example, if the grid is 4x4 there + // can't be an element whose midpoint is at column 5. If this happens this + // means there's an error in our grid logic that needs to be fixed + if (row > grid.cells.length || col > grid.numCols) { + throw new Error('Element midpoint exceeds the grid bounds'); + } + + // it is acceptable if a row has empty cells due to client rects not filling + // the entire bounding rect of an element + // @see https://github.com/dequelabs/axe-core/issues/3166 + let stack = + grid.cells[row][col]?.filter(gridCellNode => { + return gridCellNode.clientRects.find(clientRect => { + const rectX = clientRect.left; + const rectY = clientRect.top; + + // perform an AABB (axis-aligned bounding box) collision check for the + // point inside the rect + return ( + x <= rectX + clientRect.width && + x >= rectX && + y <= rectY + clientRect.height && + y >= rectY + ); + }); + }) ?? []; const gridContainer = grid.container; if (gridContainer) { diff --git a/test/checks/color/color-contrast.js b/test/checks/color/color-contrast.js index f2f322eb4a..339e5d1a3b 100644 --- a/test/checks/color/color-contrast.js +++ b/test/checks/color/color-contrast.js @@ -358,13 +358,55 @@ describe('color-contrast', function() { ); }); - describe('with pseudo elements', function () { + it('should not error if client rects do not fill entire bounding rect', function() { + var params = checkSetup( + '
' +
+        '\nx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x ' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\nx' +
+        '\n
' + ); + assert.doesNotThrow(function() { + contrastEvaluate.apply(checkContext, params); + }); + }); + + describe('with pseudo elements', function() { it('should return undefined if :before pseudo element has a background color', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isUndefined(contrastEvaluate.apply(checkContext, params)); assert.deepEqual(checkContext._data, { messageKey: 'pseudoContent' @@ -374,13 +416,13 @@ describe('color-contrast', function() { document.querySelector('#background') ); }); - + it('should return undefined if :after pseudo element has a background color', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isUndefined(contrastEvaluate.apply(checkContext, params)); assert.deepEqual(checkContext._data, { messageKey: 'pseudoContent' @@ -390,21 +432,21 @@ describe('color-contrast', function() { document.querySelector('#background') ); }); - + it('should return undefined if pseudo element has a background image', function() { var dataURI = 'data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/' + 'XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkA' + 'ABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKU' + 'E1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7'; - + var params = checkSetup( '' + '

Content

' ); - + assert.isUndefined(contrastEvaluate.apply(checkContext, params)); assert.deepEqual(checkContext._data, { messageKey: 'pseudoContent' @@ -414,62 +456,62 @@ describe('color-contrast', function() { document.querySelector('#background') ); }); - + it('should not return undefined if pseudo element has no content', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - + it('should not return undefined if pseudo element is not absolutely positioned no content', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - + it('should not return undefined if pseudo element is has zero dimension', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - + it("should not return undefined if pseudo element doesn't have a background", function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - + it('should not return undefined if pseudo element has visibility: hidden', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - + it('should not return undefined if pseudo element has display: none', function() { var params = checkSetup( '' + '

Content

' ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - it('should return undefined if pseudo element is more than 25% of the element', function () { + it('should return undefined if pseudo element is more than 25% of the element', function() { var params = checkSetup( '' + @@ -478,7 +520,7 @@ describe('color-contrast', function() { assert.isUndefined(contrastEvaluate.apply(checkContext, params)); }); - it('should not return undefined if pseudo element is 25% of the element', function () { + it('should not return undefined if pseudo element is 25% of the element', function() { var params = checkSetup( '' + @@ -487,17 +529,20 @@ describe('color-contrast', function() { assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - (isIE11 ? it : xit)('should return undefined if the unit is not in px', function () { - var params = checkSetup( - '' + - '

Content

' - ); - assert.isUndefined(contrastEvaluate.apply(checkContext, params)); - }); + (isIE11 ? it : xit)( + 'should return undefined if the unit is not in px', + function() { + var params = checkSetup( + '' + + '

Content

' + ); + assert.isUndefined(contrastEvaluate.apply(checkContext, params)); + } + ); }); - describe('with special texts', function () { + describe('with special texts', function() { it('should return undefined for a single character text with insufficient contrast', function() { var params = checkSetup( '
' + @@ -582,7 +627,7 @@ describe('color-contrast', function() { }); }); - describe('options', function () { + describe('options', function() { it('should support options.boldValue', function() { var params = checkSetup( '
' + @@ -732,24 +777,24 @@ describe('color-contrast', function() { ignorePseudo: true } ); - + assert.isTrue(contrastEvaluate.apply(checkContext, params)); }); - - it('should adjust the pseudo element minimum size with the options.pseudoSizeThreshold', function () { + + it('should adjust the pseudo element minimum size with the options.pseudoSizeThreshold', function() { var params = checkSetup( - '' + + '' + '

Content

', { - pseudoSizeThreshold: 0.20 + pseudoSizeThreshold: 0.2 } ); assert.isUndefined(contrastEvaluate.apply(checkContext, params)); }); }); - describe('with shadowDOM', function () { + describe('with shadowDOM', function() { (shadowSupported ? it : xit)( 'returns colors across Shadow DOM boundaries', function() { diff --git a/test/commons/dom/get-element-stack.js b/test/commons/dom/get-element-stack.js index ed31136946..290213430e 100644 --- a/test/commons/dom/get-element-stack.js +++ b/test/commons/dom/get-element-stack.js @@ -348,6 +348,46 @@ describe('dom.getElementStack', function() { assert.deepEqual(stack, []); }); + it('should throw error if element midpoint-x exceeds the grid', function() { + fixture.innerHTML = '
Hello World
'; + axe.testUtils.flatTreeSetup(fixture); + var target = fixture.querySelector('#target'); + var vNode = axe.utils.getNodeFromTree(target); + Object.defineProperty(vNode, 'boundingClientRect', { + get: function() { + return { + left: 0, + top: 10, + width: 10000, + height: 10 + }; + } + }); + assert.throws(function() { + getElementStack(target); + }, 'Element midpoint exceeds the grid bounds'); + }); + + it('should throw error if element midpoint-y exceeds the grid', function() { + fixture.innerHTML = '
Hello World
'; + axe.testUtils.flatTreeSetup(fixture); + var target = fixture.querySelector('#target'); + var vNode = axe.utils.getNodeFromTree(target); + Object.defineProperty(vNode, 'boundingClientRect', { + get: function() { + return { + left: 0, + top: 10, + width: 10, + height: 10000 + }; + } + }); + assert.throws(function() { + getElementStack(target); + }, 'Element midpoint exceeds the grid bounds'); + }); + // IE11 either only supports clip paths defined by url() or not at all, // MDN and caniuse.com give different results... (isIE11 ? it.skip : it)( From 2bdd9538c3d71280a3d51fb02f44142007b41569 Mon Sep 17 00:00:00 2001 From: Dylan Barrell Date: Thu, 7 Oct 2021 04:10:05 -0400 Subject: [PATCH 24/88] docs: create issue impact documentation (#3164) * feat: create issue impact documentation * Update doc/issue_impact.md Co-authored-by: Wilco Fiers * Update issue_impact.md * Update doc/issue_impact.md Co-authored-by: Stephen Mathieson Co-authored-by: Wilco Fiers Co-authored-by: Stephen Mathieson --- doc/issue_impact.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 doc/issue_impact.md diff --git a/doc/issue_impact.md b/doc/issue_impact.md new file mode 100644 index 0000000000..be68f145db --- /dev/null +++ b/doc/issue_impact.md @@ -0,0 +1,21 @@ +# Issue Impacts + +Axe-core assigns an impact according to our assessment of the likely impact of an issue on a user with a disability that would be affected by this issue. In any given context the actual impact for the user could be lower; in some instances, it could be higher. For this reason, we encourage users of tools to evaluate each individual issue and assess the impact in the context of their application or content. + +## Definitions + +### Minor + +Considered to be a nuisance or an annoyance bug. Prioritize fixing if the fix only takes a few minutes and the developer is working on the same screen/feature at the same time, otherwise the issue should not be prioritized. Will still get in the way of compliance if not fixed. + +### Moderate + +Results in some difficulty for people with disabilities, but will generally not prevent them from accessing fundamental features or content. Users may be frustrated and abandon non-critical workflows. Prioritize fixing in this release, if there are no higher-priority issues. Will get in the way of compliance if not fixed. + +### Serious + +Results in serious barriers for people with disabilities, and will partially or fully prevent them from accessing fundamental features or content. People relying on assistive technologies will experience significant frustration and may abandon essential workflows. Issues falling under this category are major problems, and remediation should be a priority. + +### Critical + +Results in blocked content for people with disabilities, and will definitely prevent them from accessing fundamental features or content. This type of issue puts your organization at risk. Prioritize fixing as soon as possible, within the week if possible. Remediation should be a top priority. From cb019755d9cb52b997aae340f406ac26d0cf90e5 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 8 Oct 2021 09:33:11 -0600 Subject: [PATCH 25/88] fix(aria-allowed-children,aria-allowed-parent): allow group role in listbox (#3195) * fix(aria-allowed-children,aria-allowed-parent): allow group role in listbox * fix tests --- lib/standards/aria-roles.js | 4 ++-- test/checks/aria/required-children.js | 2 +- .../aria-required-children/aria-required-children.html | 6 ++++++ .../aria-required-children/aria-required-children.json | 3 ++- .../rules/aria-required-parent/aria-required-parent.html | 6 ++++++ .../rules/aria-required-parent/aria-required-parent.json | 3 ++- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/standards/aria-roles.js b/lib/standards/aria-roles.js index a21fe4a2b1..f1291d37f0 100644 --- a/lib/standards/aria-roles.js +++ b/lib/standards/aria-roles.js @@ -284,7 +284,7 @@ const ariaRoles = { }, listbox: { type: 'composite', - requiredOwned: ['option'], + requiredOwned: ['group', 'option'], allowedAttrs: [ 'aria-multiselectable', 'aria-readonly', @@ -418,7 +418,7 @@ const ariaRoles = { }, option: { type: 'widget', - requiredContext: ['listbox'], + requiredContext: ['group', 'listbox'], // Note: since the option role has an implicit // aria-selected value it is not required to be added by // the user diff --git a/test/checks/aria/required-children.js b/test/checks/aria/required-children.js index 38e1ccaae9..c5fba9de19 100644 --- a/test/checks/aria/required-children.js +++ b/test/checks/aria/required-children.js @@ -323,7 +323,7 @@ describe('aria-required-children', function() { it('should fail when role does not allow group', function() { var params = checkSetup( - '
  • Option
' + '
  • Option
' ); assert.isFalse( axe.testUtils diff --git a/test/integration/rules/aria-required-children/aria-required-children.html b/test/integration/rules/aria-required-children/aria-required-children.html index 89024d8623..0241ec6643 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.html +++ b/test/integration/rules/aria-required-children/aria-required-children.html @@ -62,3 +62,9 @@
+ +
+
+
option
+
+
diff --git a/test/integration/rules/aria-required-children/aria-required-children.json b/test/integration/rules/aria-required-children/aria-required-children.json index 05bcfa7185..3e75156fb2 100644 --- a/test/integration/rules/aria-required-children/aria-required-children.json +++ b/test/integration/rules/aria-required-children/aria-required-children.json @@ -19,7 +19,8 @@ ["#pass5"], ["#pass6"], ["#pass7"], - ["#pass8"] + ["#pass8"], + ["#pass9"] ], "incomplete": [ ["#incomplete1"], diff --git a/test/integration/rules/aria-required-parent/aria-required-parent.html b/test/integration/rules/aria-required-parent/aria-required-parent.html index 3c0d5588d1..be9ef5a4d9 100644 --- a/test/integration/rules/aria-required-parent/aria-required-parent.html +++ b/test/integration/rules/aria-required-parent/aria-required-parent.html @@ -58,3 +58,9 @@
+ +
+
+
option
+
+
diff --git a/test/integration/rules/aria-required-parent/aria-required-parent.json b/test/integration/rules/aria-required-parent/aria-required-parent.json index df291caf49..0092d17059 100644 --- a/test/integration/rules/aria-required-parent/aria-required-parent.json +++ b/test/integration/rules/aria-required-parent/aria-required-parent.json @@ -22,6 +22,7 @@ ["#pass9"], ["#pass10"], ["#pass11"], - ["#pass12"] + ["#pass12"], + ["#pass13"] ] } From e930a7081d4308549370f74e9d341badd9661584 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 8 Oct 2021 09:33:54 -0600 Subject: [PATCH 26/88] fix(color-contrast): properly blend multiple alpha colors (#3193) * fix(color-contrast): properly blend multiple alpha colors * revert shadow * add back shadow color flatten * fix * fix ie11 * type * typo --- lib/checks/color/color-contrast-evaluate.js | 4 +- lib/commons/color/flatten-colors.js | 64 ++++++- lib/commons/color/flatten-shadow-colors.js | 22 +++ lib/commons/color/get-background-color.js | 17 +- lib/commons/color/get-foreground-color.js | 3 +- lib/commons/color/index.js | 1 + test/commons/color/flatten-colors.js | 23 ++- test/integration/full/contrast/blending.html | 189 +++++++++++++++++++ test/integration/full/contrast/blending.js | 56 ++++++ 9 files changed, 365 insertions(+), 14 deletions(-) create mode 100644 lib/commons/color/flatten-shadow-colors.js create mode 100644 test/integration/full/contrast/blending.html create mode 100644 test/integration/full/contrast/blending.js diff --git a/lib/checks/color/color-contrast-evaluate.js b/lib/checks/color/color-contrast-evaluate.js index 18a58f4e4b..8aa165d37d 100644 --- a/lib/checks/color/color-contrast-evaluate.js +++ b/lib/checks/color/color-contrast-evaluate.js @@ -12,7 +12,7 @@ import { getContrast, getOwnBackgroundColor, getTextShadowColors, - flattenColors + flattenShadowColors } from '../../commons/color'; import { memoize } from '../../core/utils'; @@ -73,7 +73,7 @@ export default function colorContrastEvaluate(node, options, virtualNode) { } else if (fgColor && bgColor) { // Thin shadows can pass either by contrasting with the text color // or when contrasting with the background. - shadowColor = [...shadowColors, bgColor].reduce(flattenColors); + shadowColor = [...shadowColors, bgColor].reduce(flattenShadowColors); const bgContrast = getContrast(bgColor, shadowColor); const fgContrast = getContrast(shadowColor, fgColor); contrast = Math.max(bgContrast, fgContrast); diff --git a/lib/commons/color/flatten-colors.js b/lib/commons/color/flatten-colors.js index e4dc587fa6..2c3de0e033 100644 --- a/lib/commons/color/flatten-colors.js +++ b/lib/commons/color/flatten-colors.js @@ -1,5 +1,33 @@ import Color from './color'; +// how to combine background and foreground colors together when using +// the CSS property `mix-blend-mode`. Defaults to `normal` +// @see https://www.w3.org/TR/compositing-1/#blendingseparable +const blendFunctions = { + normal(Cb, Cs) { + return Cs; + } +}; + +// Simple Alpha Compositing written as non-premultiplied. +// formula: Rrgb × Ra = Srgb × Sa + Drgb × Da × (1 − Sa) +// Cs: the source color +// αs: the source alpha +// Cb: the backdrop color +// αb: the backdrop alpha +// @see https://www.w3.org/TR/compositing-1/#simplealphacompositing +// @see https://www.w3.org/TR/compositing-1/#blending +// @see https://ciechanow.ski/alpha-compositing/ +function simpleAlphaCompositing(Cs, αs, Cb, αb, blendMode) { + // RGB color space doesn't have decimal values so we will follow what browsers do and round + // e.g. rgb(255.2, 127.5, 127.8) === rgb(255, 128, 128) + return Math.round( + αs * (1 - αb) * Cs + + αs * αb * blendFunctions[blendMode](Cb, Cs) + + (1 - αs) * αb * Cb + ); +} + /** * Combine the two given color according to alpha blending. * @method flattenColors @@ -9,12 +37,36 @@ import Color from './color'; * @param {Color} bgColor Background color * @return {Color} Blended color */ -function flattenColors(fgColor, bgColor) { - var alpha = fgColor.alpha; - var r = (1 - alpha) * bgColor.red + alpha * fgColor.red; - var g = (1 - alpha) * bgColor.green + alpha * fgColor.green; - var b = (1 - alpha) * bgColor.blue + alpha * fgColor.blue; - var a = fgColor.alpha + bgColor.alpha * (1 - fgColor.alpha); +function flattenColors(fgColor, bgColor, blendMode = 'normal') { + // foreground is the "source" color and background is the "backdrop" color + const r = simpleAlphaCompositing( + fgColor.red, + fgColor.alpha, + bgColor.red, + bgColor.alpha, + blendMode + ); + const g = simpleAlphaCompositing( + fgColor.green, + fgColor.alpha, + bgColor.green, + bgColor.alpha, + blendMode + ); + const b = simpleAlphaCompositing( + fgColor.blue, + fgColor.alpha, + bgColor.blue, + bgColor.alpha, + blendMode + ); + + // formula: αo = αs + αb x (1 - αs) + // clamp alpha between 0 and 1 + const a = Math.max( + 0, + Math.min(fgColor.alpha + bgColor.alpha * (1 - fgColor.alpha), 1) + ); return new Color(r, g, b, a); } diff --git a/lib/commons/color/flatten-shadow-colors.js b/lib/commons/color/flatten-shadow-colors.js new file mode 100644 index 0000000000..404aae41ac --- /dev/null +++ b/lib/commons/color/flatten-shadow-colors.js @@ -0,0 +1,22 @@ +import Color from './color'; + +/** + * Combine the two given shadow colors according to alpha blending. + * @method flattenColors + * @memberof axe.commons.color.Color + * @instance + * @param {Color} fgColor Foreground color + * @param {Color} bgColor Background color + * @return {Color} Blended color + */ +function flattenColors(fgColor, bgColor) { + var alpha = fgColor.alpha; + var r = (1 - alpha) * bgColor.red + alpha * fgColor.red; + var g = (1 - alpha) * bgColor.green + alpha * fgColor.green; + var b = (1 - alpha) * bgColor.blue + alpha * fgColor.blue; + var a = fgColor.alpha + bgColor.alpha * (1 - fgColor.alpha); + + return new Color(r, g, b, a); +} + +export default flattenColors; diff --git a/lib/commons/color/get-background-color.js b/lib/commons/color/get-background-color.js index f281b7ebba..230fa9d568 100644 --- a/lib/commons/color/get-background-color.js +++ b/lib/commons/color/get-background-color.js @@ -4,6 +4,7 @@ import getOwnBackgroundColor from './get-own-background-color'; import elementHasImage from './element-has-image'; import Color from './color'; import flattenColors from './flatten-colors'; +import flattenShadowColors from './flatten-shadow-colors'; import getTextShadowColors from './get-text-shadow-colors'; import visuallyContains from '../dom/visually-contains'; @@ -38,6 +39,9 @@ function elmPartiallyObscured(elm, bgElm, bgColor) { */ function getBackgroundColor(elm, bgElms = [], shadowOutlineEmMax = 0.1) { let bgColors = getTextShadowColors(elm, { minRatio: shadowOutlineEmMax }); + if (bgColors.length) { + bgColors = [bgColors.reduce(flattenShadowColors)]; + } const elmStack = getBackgroundStack(elm); // Search the stack until we have an alpha === 1 background @@ -62,7 +66,7 @@ function getBackgroundColor(elm, bgElms = [], shadowOutlineEmMax = 0.1) { if (bgColor.alpha !== 0) { // store elements contributing to the br color. bgElms.push(bgElm); - bgColors.push(bgColor); + bgColors.unshift(bgColor); // Exit if the background is opaque return bgColor.alpha === 1; @@ -75,9 +79,14 @@ function getBackgroundColor(elm, bgElms = [], shadowOutlineEmMax = 0.1) { return null; } - // Mix the colors together, on top of a default white - bgColors.push(new Color(255, 255, 255, 1)); - var colors = bgColors.reduce(flattenColors); + // Mix the colors together, on top of a default white. Colors must be mixed + // in bottom up order (background to foreground order) to produce the correct + // result. + // @see https://github.com/dequelabs/axe-core/issues/2924 + bgColors.unshift(new Color(255, 255, 255, 1)); + var colors = bgColors.reduce((bgColor, fgColor) => { + return flattenColors(fgColor, bgColor); + }); return colors; } diff --git a/lib/commons/color/get-foreground-color.js b/lib/commons/color/get-foreground-color.js index 594d31cd15..d9b8139af3 100644 --- a/lib/commons/color/get-foreground-color.js +++ b/lib/commons/color/get-foreground-color.js @@ -2,6 +2,7 @@ import Color from './color'; import getBackgroundColor from './get-background-color'; import incompleteData from './incomplete-data'; import flattenColors from './flatten-colors'; +import flattenShadowColors from './flatten-shadow-colors'; import getTextShadowColors from './get-text-shadow-colors'; import { getNodeFromTree } from '../../core/utils'; @@ -66,7 +67,7 @@ function getForegroundColor(node, _, bgColor) { if (fgColor.alpha < 1) { const textShadowColors = getTextShadowColors(node, { minRatio: 0 }); - return [fgColor, ...textShadowColors, bgColor].reduce(flattenColors); + return [fgColor, ...textShadowColors, bgColor].reduce(flattenShadowColors); } return flattenColors(fgColor, bgColor); diff --git a/lib/commons/color/index.js b/lib/commons/color/index.js index c795340b85..156cb3eded 100644 --- a/lib/commons/color/index.js +++ b/lib/commons/color/index.js @@ -9,6 +9,7 @@ export { default as elementHasImage } from './element-has-image'; export { default as elementIsDistinct } from './element-is-distinct'; export { default as filteredRectStack } from './filtered-rect-stack'; export { default as flattenColors } from './flatten-colors'; +export { default as flattenShadowColors } from './flatten-shadow-colors'; export { default as getBackgroundColor } from './get-background-color'; export { default as getBackgroundStack } from './get-background-stack'; export { default as getContrast } from './get-contrast'; diff --git a/test/commons/color/flatten-colors.js b/test/commons/color/flatten-colors.js index c9244e40ca..bceb351f52 100644 --- a/test/commons/color/flatten-colors.js +++ b/test/commons/color/flatten-colors.js @@ -6,7 +6,10 @@ describe('color.flattenColors', function() { var fullblack = new axe.commons.color.Color(0, 0, 0, 1); var transparent = new axe.commons.color.Color(0, 0, 0, 0); var white = new axe.commons.color.Color(255, 255, 255, 1); - var gray = new axe.commons.color.Color(127.5, 127.5, 127.5, 1); + var gray = new axe.commons.color.Color(128, 128, 128, 1); + var halfRed = new axe.commons.color.Color(255, 0, 0, 0.5); + var quarterLightGreen = new axe.commons.color.Color(0, 128, 0, 0.25); + var flat = axe.commons.color.flattenColors(halfblack, white); assert.equal(flat.red, gray.red); assert.equal(flat.green, gray.green); @@ -21,5 +24,23 @@ describe('color.flattenColors', function() { assert.equal(flat3.red, white.red); assert.equal(flat3.green, white.green); assert.equal(flat3.blue, white.blue); + + var flat4 = axe.commons.color.flattenColors(halfRed, white); + assert.equal(flat4.red, 255); + assert.equal(flat4.green, 128); + assert.equal(flat4.blue, 128); + assert.equal(flat4.alpha, 1); + + var flat5 = axe.commons.color.flattenColors(quarterLightGreen, white); + assert.equal(flat5.red, 191); + assert.equal(flat5.green, 223); + assert.equal(flat5.blue, 191); + assert.equal(flat5.alpha, 1); + + var flat6 = axe.commons.color.flattenColors(quarterLightGreen, halfRed); + assert.equal(flat6.red, 96); + assert.equal(flat6.green, 32); + assert.equal(flat6.blue, 0); + assert.equal(flat6.alpha, 0.625); }); }); diff --git a/test/integration/full/contrast/blending.html b/test/integration/full/contrast/blending.html new file mode 100644 index 0000000000..2fbc1ad89e --- /dev/null +++ b/test/integration/full/contrast/blending.html @@ -0,0 +1,189 @@ + + + + Color Contrast Blending Verification Tests + + + + + + + + + +

+ Use this page to verify that axe-core produces the correct colors for each + blended background. If using Chrome, please ensure it is using the + sRGB color profile by navigating to chrome://flags/, searching for "Force + color profile" and setting it to "sRGB" (otherwise it uses the OS color + profile which for Mac, which we believe is "Display P3 D65" and will + produce the incorrect result color when blending). +

+

+ For more information, see + https://github.com/dequelabs/axe-core/issues/2924 +

+
+
+
+
+
+ Test1 +
+
+
+
Test1 result
+
+ +
+
+
+ Test2 +
+
+
Test2 result
+
+ +
+
+
+ Test3 +
+
+
Test3 result
+
+ +
+
+
+
+ Test4 +
+
+
+
Test4 result
+
+ +
+
+
+ Test5 +
+
+
Test5 result
+
+ +
+
+
+ Test6 +
+
+
Test6 result
+
+ +
+
+
+
+
+ Test7 +
+
+
+
+
Test7 result
+
+ +
+
+
+
+
+
+
+ Test8 +
+
+
+
+
+
+
Test8 result
+
+ +
+
+
+ Test9 +
+
+
Test9 result
+
+
+ +
+ + + + diff --git a/test/integration/full/contrast/blending.js b/test/integration/full/contrast/blending.js new file mode 100644 index 0000000000..7d1bde4859 --- /dev/null +++ b/test/integration/full/contrast/blending.js @@ -0,0 +1,56 @@ +describe('color-contrast blending test', function() { + var include = []; + var resultElms = []; + var expected = [ + 'rgb(223, 112, 96)', + 'rgb(255, 128, 128)', + 'rgb(191, 223, 191)', + 'rgb(125, 38, 54)', + 'rgb(179, 38, 0)', + 'rgb(179, 0, 77)', + 'rgb(143, 192, 80)', + 'rgb(147, 153, 119)', + 'rgb(221, 221, 221)' + ]; + var testElms = Array.from(document.querySelectorAll('#fixture > div')); + testElms.forEach(function(testElm) { + var id = testElm.id; + var target = testElm.querySelector('#' + id + '-target'); + var result = testElm.querySelector('#' + id + '-result'); + include.push(target); + resultElms.push(result); + }); + + before(function(done) { + axe.run({ include: include }, { runOnly: ['color-contrast'] }, function( + err, + res + ) { + assert.isNull(err); + + // don't care where the result goes as we just want to + // extract the background color for each one + var results = [] + .concat(res.passes) + .concat(res.violations) + .concat(res.incomplete); + results.forEach(function(result) { + result.nodes.forEach(function(node) { + var bgColor = node.any[0].data.bgColor; + var id = node.target[0].split('-')[0]; + var result = document.querySelector(id + '-result'); + result.style.backgroundColor = bgColor; + }); + }); + + done(); + }); + }); + + resultElms.forEach(function(elm, index) { + it('produces the correct blended color for ' + elm.id, function() { + var style = window.getComputedStyle(elm); + assert.equal(style.getPropertyValue('background-color'), expected[index]); + }); + }); +}); From 2f439b3fdb7e7fa3228e663c5313af0f08aa4327 Mon Sep 17 00:00:00 2001 From: Scott O'Hara Date: Fri, 8 Oct 2021 11:42:03 -0400 Subject: [PATCH 27/88] fix(aria-allowed-role): updates the allowed roles for the wbr element to none and presentation (#3192) related to issue #3177 --- lib/standards/html-elms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/standards/html-elms.js b/lib/standards/html-elms.js index 3b854e1b71..472529b5fe 100644 --- a/lib/standards/html-elms.js +++ b/lib/standards/html-elms.js @@ -936,7 +936,7 @@ const htmlElms = { }, wbr: { contentTypes: ['phrasing', 'flow'], - allowedRoles: true + allowedRoles: ['presentation', 'none'] } }; From cad39949c29bc3f83863e3484feef82e89e12118 Mon Sep 17 00:00:00 2001 From: Esteban Gehring Date: Fri, 8 Oct 2021 19:48:35 +0200 Subject: [PATCH 28/88] fix(label-title-only): allow hidden labels (#3183) --- doc/rule-descriptions.md | 64 +++++++++---------- lib/commons/aria/arialabelledby-text.js | 2 +- lib/commons/aria/label-virtual.js | 2 +- lib/rules/label-title-only.json | 2 +- .../label-title-only/label-title-only.html | 11 ++++ .../label-title-only/label-title-only.json | 5 +- test/integration/rules/label/label.html | 3 + test/integration/rules/label/label.json | 3 +- 8 files changed, 55 insertions(+), 37 deletions(-) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index e145658a76..089fe89db5 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -79,38 +79,38 @@ Rules that do not necessarily conform to WCAG success criterion but are industry accepted practices that improve the user experience. -| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | -| :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------- | :----------------- | :---------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------- | -| [accesskeys](https://dequeuniversity.com/rules/axe/4.3/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | -| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.3/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | -| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.3/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-text](https://dequeuniversity.com/rules/axe/4.3/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.3/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [empty-heading](https://dequeuniversity.com/rules/axe/4.3/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | -| [frame-tested](https://dequeuniversity.com/rules/axe/4.3/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | -| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.3/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, best-practice | failure | | -| [heading-order](https://dequeuniversity.com/rules/axe/4.3/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | -| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.3/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249, best-practice | needs review | [b20e66](https://act-rules.github.io/rules/b20e66), [fd3a94](https://act-rules.github.io/rules/fd3a94) | -| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.3/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | -| [label-title-only](https://dequeuniversity.com/rules/axe/4.3/label-title-only?application=RuleDescription) | Ensures that every form element is not solely labeled using the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | -| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.3/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-unique](https://dequeuniversity.com/rules/axe/4.3/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | -| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.3/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | -| [meta-viewport](https://dequeuniversity.com/rules/axe/4.3/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, best-practice, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | -| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.3/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | -| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.3/presentation-role-conflict?application=RuleDescription) | Flags elements whose role is none or presentation and which cause the role conflict resolution to trigger. | Minor | cat.aria, best-practice | failure | | -| [region](https://dequeuniversity.com/rules/axe/4.3/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | -| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.3/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | -| [skip-link](https://dequeuniversity.com/rules/axe/4.3/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | -| [tabindex](https://dequeuniversity.com/rules/axe/4.3/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | -| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.3/table-duplicate-name?application=RuleDescription) | Ensure that tables do not have the same summary and caption | Minor | cat.tables, best-practice | failure | | +| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | +| :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :---------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------- | +| [accesskeys](https://dequeuniversity.com/rules/axe/4.3/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | +| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.3/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | +| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.3/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-text](https://dequeuniversity.com/rules/axe/4.3/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.3/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [empty-heading](https://dequeuniversity.com/rules/axe/4.3/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | +| [frame-tested](https://dequeuniversity.com/rules/axe/4.3/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | +| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.3/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, best-practice | failure | | +| [heading-order](https://dequeuniversity.com/rules/axe/4.3/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | +| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.3/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249, best-practice | needs review | [b20e66](https://act-rules.github.io/rules/b20e66), [fd3a94](https://act-rules.github.io/rules/fd3a94) | +| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.3/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | +| [label-title-only](https://dequeuniversity.com/rules/axe/4.3/label-title-only?application=RuleDescription) | Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | +| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.3/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-unique](https://dequeuniversity.com/rules/axe/4.3/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | +| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.3/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | +| [meta-viewport](https://dequeuniversity.com/rules/axe/4.3/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, best-practice, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | +| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.3/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | +| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.3/presentation-role-conflict?application=RuleDescription) | Flags elements whose role is none or presentation and which cause the role conflict resolution to trigger. | Minor | cat.aria, best-practice | failure | | +| [region](https://dequeuniversity.com/rules/axe/4.3/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | +| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.3/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | +| [skip-link](https://dequeuniversity.com/rules/axe/4.3/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | +| [tabindex](https://dequeuniversity.com/rules/axe/4.3/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | +| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.3/table-duplicate-name?application=RuleDescription) | Ensure that tables do not have the same summary and caption | Minor | cat.tables, best-practice | failure | | ## Experimental Rules diff --git a/lib/commons/aria/arialabelledby-text.js b/lib/commons/aria/arialabelledby-text.js index e74c77370a..f1a7fa8745 100644 --- a/lib/commons/aria/arialabelledby-text.js +++ b/lib/commons/aria/arialabelledby-text.js @@ -13,7 +13,7 @@ import { getNodeFromTree } from '../../core/utils'; * @property {Bool} inControlContext Whether or not the lookup is part of a native label reference * @property {Element} startNode First node in accessible name computation * @property {Bool} debug Enable logging for formControlValue - * @return {string} Cancatinated text value for referenced elements + * @return {string} Concatenated text value for referenced elements */ function arialabelledbyText(vNode, context = {}) { if (!(vNode instanceof AbstractVirtualNode)) { diff --git a/lib/commons/aria/label-virtual.js b/lib/commons/aria/label-virtual.js index 04fabf688d..edd5b94480 100644 --- a/lib/commons/aria/label-virtual.js +++ b/lib/commons/aria/label-virtual.js @@ -21,7 +21,7 @@ function labelVirtual(virtualNode) { candidate = ref .map(thing => { const vNode = getNodeFromTree(thing); - return vNode ? visibleVirtual(vNode, true) : ''; + return vNode ? visibleVirtual(vNode) : ''; }) .join(' ') .trim(); diff --git a/lib/rules/label-title-only.json b/lib/rules/label-title-only.json index 5ac4a78549..79813f2183 100644 --- a/lib/rules/label-title-only.json +++ b/lib/rules/label-title-only.json @@ -4,7 +4,7 @@ "matches": "label-matches", "tags": ["cat.forms", "best-practice"], "metadata": { - "description": "Ensures that every form element is not solely labeled using the title or aria-describedby attributes", + "description": "Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes", "help": "Form elements should have a visible label" }, "all": [], diff --git a/test/integration/rules/label-title-only/label-title-only.html b/test/integration/rules/label-title-only/label-title-only.html index e92fc033c8..c0493b970f 100644 --- a/test/integration/rules/label-title-only/label-title-only.html +++ b/test/integration/rules/label-title-only/label-title-only.html @@ -27,4 +27,15 @@ + + + + + diff --git a/test/integration/rules/label-title-only/label-title-only.json b/test/integration/rules/label-title-only/label-title-only.json index c58c800c0b..fb3ae2b1ce 100644 --- a/test/integration/rules/label-title-only/label-title-only.json +++ b/test/integration/rules/label-title-only/label-title-only.json @@ -10,6 +10,9 @@ ["#pass5"], ["#pass6"], ["#pass7"], - ["#pass8"] + ["#pass8"], + ["#pass9"], + ["#pass10"], + ["#pass11"] ] } diff --git a/test/integration/rules/label/label.html b/test/integration/rules/label/label.html index d87ea614c2..995011e25c 100644 --- a/test/integration/rules/label/label.html +++ b/test/integration/rules/label/label.html @@ -60,4 +60,7 @@ + + + diff --git a/test/integration/rules/label/label.json b/test/integration/rules/label/label.json index a98d0976f6..6df2763965 100644 --- a/test/integration/rules/label/label.json +++ b/test/integration/rules/label/label.json @@ -26,6 +26,7 @@ ["#pass15"], ["#pass16"], ["#pass17"], - ["#pass-gh1176"] + ["#pass-gh1176"], + ["#pass18"] ] } From 828e526fd06ee596df73f4825e750aad459ca75e Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Tue, 12 Oct 2021 10:52:24 +0200 Subject: [PATCH 29/88] fix: Separate Level AAA rules from A and best-practices (#3191) * fix: Separate Level AAA rules from A and best-practices * Don't log use of wcag21aaa as a tag * address comments --- build/configure.js | 8 +++ doc/API.md | 2 + doc/rule-descriptions.md | 74 ++++++++++++--------- lib/core/base/audit.js | 11 +-- lib/rules/identical-links-same-purpose.json | 2 +- lib/rules/meta-refresh.json | 1 - test/core/base/audit.js | 50 ++++++++++++++ 7 files changed, 109 insertions(+), 39 deletions(-) diff --git a/build/configure.js b/build/configure.js index 10a583126c..97939e0455 100644 --- a/build/configure.js +++ b/build/configure.js @@ -62,6 +62,12 @@ function buildRules(grunt, options, commons, callback) { 'Rules that do not necessarily conform to WCAG success criterion but are industry accepted practices that improve the user experience.', rules: [] }, + wcag2aaa: { + title: 'WCAG 2.0 and 2.1 level AAA rules', + intro: + 'Rules that check for conformance to WCAG AAA success criteria that can be fully automated.', + rules: [] + }, experimental: { title: 'Experimental Rules', intro: @@ -335,6 +341,8 @@ function buildRules(grunt, options, commons, callback) { rules = descriptions.deprecated.rules; } else if (rule.tags.includes('experimental')) { rules = descriptions.experimental.rules; + } else if (rule.tags.find(tag => tag.includes('aaa'))) { + rules = descriptions.wcag2aaa.rules; } else if (rule.tags.includes('best-practice')) { rules = descriptions.bestPractice.rules; } else if (rule.tags.find(tag => tag.startsWith('wcag2a'))) { diff --git a/doc/API.md b/doc/API.md index 960d6cebd9..98ee922793 100644 --- a/doc/API.md +++ b/doc/API.md @@ -80,8 +80,10 @@ The `experimental`, `ACT` and `section508` tags are only added to some rules. Ea | ---------------- | ---------------------------------------------------- | | `wcag2a` | WCAG 2.0 Level A | | `wcag2aa` | WCAG 2.0 Level AA | +| `wcag2aaa` | WCAG 2.0 Level AAA | | `wcag21a` | WCAG 2.1 Level A | | `wcag21aa` | WCAG 2.1 Level AA | +| `wcag21aaa` | WCAG 2.1 Level AAA | | `best-practice` | Common accessibility best practices | | `wcag***` | WCAG success criterion e.g. wcag111 maps to SC 1.1.1 | | `ACT` | W3C approved Accessibility Conformance Testing rules | diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 089fe89db5..11cd46558a 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -5,6 +5,7 @@ - [WCAG 2.0 Level A & AA Rules](#wcag-20-level-a--aa-rules) - [WCAG 2.1 Level A & AA Rules](#wcag-21-level-a--aa-rules) - [Best Practices Rules](#best-practices-rules) +- [WCAG 2.0 and 2.1 level AAA rules](#wcag-20-and-21-level-aaa-rules) - [Experimental Rules](#experimental-rules) - [Deprecated Rules](#deprecated-rules) @@ -54,7 +55,7 @@ | [list](https://dequeuniversity.com/rules/axe/4.3/list?application=RuleDescription) | Ensures that lists are structured correctly | Serious | cat.structure, wcag2a, wcag131 | failure | | | [listitem](https://dequeuniversity.com/rules/axe/4.3/listitem?application=RuleDescription) | Ensures <li> elements are used semantically | Serious | cat.structure, wcag2a, wcag131 | failure | | | [marquee](https://dequeuniversity.com/rules/axe/4.3/marquee?application=RuleDescription) | Ensures <marquee> elements are not used | Serious | cat.parsing, wcag2a, wcag222 | failure | | -| [meta-refresh](https://dequeuniversity.com/rules/axe/4.3/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used | Critical | cat.time-and-media, wcag2a, wcag2aaa, wcag221, wcag224, wcag325 | failure | | +| [meta-refresh](https://dequeuniversity.com/rules/axe/4.3/meta-refresh?application=RuleDescription) | Ensures <meta http-equiv="refresh"> is not used | Critical | cat.time-and-media, wcag2a, wcag221, wcag224, wcag325 | failure | | | [nested-interactive](https://dequeuniversity.com/rules/axe/4.3/nested-interactive?application=RuleDescription) | Nested interactive controls are not announced by screen readers | Serious | cat.keyboard, wcag2a, wcag412 | failure, needs review | [307n5z](https://act-rules.github.io/rules/307n5z) | | [object-alt](https://dequeuniversity.com/rules/axe/4.3/object-alt?application=RuleDescription) | Ensures <object> elements have alternate text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | failure, needs review | [8fc3b6](https://act-rules.github.io/rules/8fc3b6) | | [role-img-alt](https://dequeuniversity.com/rules/axe/4.3/role-img-alt?application=RuleDescription) | Ensures [role='img'] elements have alternate text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [23a2a8](https://act-rules.github.io/rules/23a2a8) | @@ -79,38 +80,45 @@ Rules that do not necessarily conform to WCAG success criterion but are industry accepted practices that improve the user experience. -| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | -| :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :---------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------- | -| [accesskeys](https://dequeuniversity.com/rules/axe/4.3/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | -| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.3/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | -| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.3/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-text](https://dequeuniversity.com/rules/axe/4.3/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | -| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.3/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | -| [empty-heading](https://dequeuniversity.com/rules/axe/4.3/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | -| [frame-tested](https://dequeuniversity.com/rules/axe/4.3/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | -| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.3/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, best-practice | failure | | -| [heading-order](https://dequeuniversity.com/rules/axe/4.3/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | -| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.3/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249, best-practice | needs review | [b20e66](https://act-rules.github.io/rules/b20e66), [fd3a94](https://act-rules.github.io/rules/fd3a94) | -| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.3/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | -| [label-title-only](https://dequeuniversity.com/rules/axe/4.3/label-title-only?application=RuleDescription) | Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | -| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.3/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | -| [landmark-unique](https://dequeuniversity.com/rules/axe/4.3/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | -| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.3/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | -| [meta-viewport](https://dequeuniversity.com/rules/axe/4.3/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, best-practice, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | -| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.3/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | -| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.3/presentation-role-conflict?application=RuleDescription) | Flags elements whose role is none or presentation and which cause the role conflict resolution to trigger. | Minor | cat.aria, best-practice | failure | | -| [region](https://dequeuniversity.com/rules/axe/4.3/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | -| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.3/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | -| [skip-link](https://dequeuniversity.com/rules/axe/4.3/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | -| [tabindex](https://dequeuniversity.com/rules/axe/4.3/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | -| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.3/table-duplicate-name?application=RuleDescription) | Ensure that tables do not have the same summary and caption | Minor | cat.tables, best-practice | failure | | +| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | +| :----------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | :----------------- | :---------------------------------------------- | :------------------------- | :------------------------------------------------- | +| [accesskeys](https://dequeuniversity.com/rules/axe/4.3/accesskeys?application=RuleDescription) | Ensures every accesskey attribute value is unique | Serious | cat.keyboard, best-practice | failure | | +| [aria-allowed-role](https://dequeuniversity.com/rules/axe/4.3/aria-allowed-role?application=RuleDescription) | Ensures role attribute has an appropriate value for the element | Minor | cat.aria, best-practice | failure, needs review | | +| [aria-dialog-name](https://dequeuniversity.com/rules/axe/4.3/aria-dialog-name?application=RuleDescription) | Ensures every ARIA dialog and alertdialog node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-text](https://dequeuniversity.com/rules/axe/4.3/aria-text?application=RuleDescription) | Ensures "role=text" is used on elements with no focusable descendants | Serious | cat.aria, best-practice | failure, needs review | | +| [aria-treeitem-name](https://dequeuniversity.com/rules/axe/4.3/aria-treeitem-name?application=RuleDescription) | Ensures every ARIA treeitem node has an accessible name | Serious | cat.aria, best-practice | failure, needs review | | +| [empty-heading](https://dequeuniversity.com/rules/axe/4.3/empty-heading?application=RuleDescription) | Ensures headings have discernible text | Minor | cat.name-role-value, best-practice | failure, needs review | | +| [frame-tested](https://dequeuniversity.com/rules/axe/4.3/frame-tested?application=RuleDescription) | Ensures <iframe> and <frame> elements contain the axe-core script | Critical | cat.structure, review-item, best-practice | failure, needs review | | +| [frame-title-unique](https://dequeuniversity.com/rules/axe/4.3/frame-title-unique?application=RuleDescription) | Ensures <iframe> and <frame> elements contain a unique title attribute | Serious | cat.text-alternatives, best-practice | failure | | +| [heading-order](https://dequeuniversity.com/rules/axe/4.3/heading-order?application=RuleDescription) | Ensures the order of headings is semantically correct | Moderate | cat.semantics, best-practice | failure, needs review | | +| [image-redundant-alt](https://dequeuniversity.com/rules/axe/4.3/image-redundant-alt?application=RuleDescription) | Ensure image alternative is not repeated as text | Minor | cat.text-alternatives, best-practice | failure | | +| [label-title-only](https://dequeuniversity.com/rules/axe/4.3/label-title-only?application=RuleDescription) | Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes | Serious | cat.forms, best-practice | failure | | +| [landmark-banner-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-banner-is-top-level?application=RuleDescription) | Ensures the banner landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-complementary-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-complementary-is-top-level?application=RuleDescription) | Ensures the complementary landmark or aside is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-contentinfo-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-contentinfo-is-top-level?application=RuleDescription) | Ensures the contentinfo landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-main-is-top-level](https://dequeuniversity.com/rules/axe/4.3/landmark-main-is-top-level?application=RuleDescription) | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-banner](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-banner?application=RuleDescription) | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-contentinfo](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-contentinfo?application=RuleDescription) | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-no-duplicate-main](https://dequeuniversity.com/rules/axe/4.3/landmark-no-duplicate-main?application=RuleDescription) | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-one-main](https://dequeuniversity.com/rules/axe/4.3/landmark-one-main?application=RuleDescription) | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | failure | | +| [landmark-unique](https://dequeuniversity.com/rules/axe/4.3/landmark-unique?application=RuleDescription) | Landmarks should have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | failure | | +| [meta-viewport-large](https://dequeuniversity.com/rules/axe/4.3/meta-viewport-large?application=RuleDescription) | Ensures <meta name="viewport"> can scale a significant amount | Minor | cat.sensory-and-visual-cues, best-practice | failure | | +| [meta-viewport](https://dequeuniversity.com/rules/axe/4.3/meta-viewport?application=RuleDescription) | Ensures <meta name="viewport"> does not disable text scaling and zooming | Critical | cat.sensory-and-visual-cues, best-practice, ACT | failure | [b4f0c3](https://act-rules.github.io/rules/b4f0c3) | +| [page-has-heading-one](https://dequeuniversity.com/rules/axe/4.3/page-has-heading-one?application=RuleDescription) | Ensure that the page, or at least one of its frames contains a level-one heading | Moderate | cat.semantics, best-practice | failure | | +| [presentation-role-conflict](https://dequeuniversity.com/rules/axe/4.3/presentation-role-conflict?application=RuleDescription) | Flags elements whose role is none or presentation and which cause the role conflict resolution to trigger. | Minor | cat.aria, best-practice | failure | | +| [region](https://dequeuniversity.com/rules/axe/4.3/region?application=RuleDescription) | Ensures all page content is contained by landmarks | Moderate | cat.keyboard, best-practice | failure | | +| [scope-attr-valid](https://dequeuniversity.com/rules/axe/4.3/scope-attr-valid?application=RuleDescription) | Ensures the scope attribute is used correctly on tables | Moderate, Critical | cat.tables, best-practice | failure | | +| [skip-link](https://dequeuniversity.com/rules/axe/4.3/skip-link?application=RuleDescription) | Ensure all skip links have a focusable target | Moderate | cat.keyboard, best-practice | failure, needs review | | +| [tabindex](https://dequeuniversity.com/rules/axe/4.3/tabindex?application=RuleDescription) | Ensures tabindex attribute values are not greater than 0 | Serious | cat.keyboard, best-practice | failure | | +| [table-duplicate-name](https://dequeuniversity.com/rules/axe/4.3/table-duplicate-name?application=RuleDescription) | Ensure that tables do not have the same summary and caption | Minor | cat.tables, best-practice | failure | | + +## WCAG 2.0 and 2.1 level AAA rules + +Rules that check for conformance to WCAG AAA success criteria that can be fully automated. + +| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | +| :--------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- | :----- | :------------------------------- | :---------------- | :----------------------------------------------------------------------------------------------------- | +| [identical-links-same-purpose](https://dequeuniversity.com/rules/axe/4.3/identical-links-same-purpose?application=RuleDescription) | Ensure that links with the same accessible name serve a similar purpose | Minor | cat.semantics, wcag2aaa, wcag249 | needs review | [b20e66](https://act-rules.github.io/rules/b20e66), [fd3a94](https://act-rules.github.io/rules/fd3a94) | ## Experimental Rules diff --git a/lib/core/base/audit.js b/lib/core/base/audit.js index bf47c49701..14d01cbaa2 100644 --- a/lib/core/base/audit.js +++ b/lib/core/base/audit.js @@ -11,7 +11,6 @@ import { performanceTimer } from '../utils'; import doT from '@deque/dot'; -import log from '../log'; import constants from '../constants'; const dotRegex = /\{\{.+?\}\}/g; @@ -592,9 +591,13 @@ class Audit { // Validate 'tags' (e.g. anything not 'rule') } else if (['tag', 'tags', undefined].includes(only.type)) { only.type = 'tag'; - const unmatchedTags = only.values.filter(tag => !tags.includes(tag)); - if (unmatchedTags.length !== 0) { - log('Could not find tags `' + unmatchedTags.join('`, `') + '`'); + + const unmatchedTags = only.values.filter(tag => ( + !tags.includes(tag) && + !/wcag2[1-3]a{1,3}/.test(tag) + )); + if (unmatchedTags.length !== 0) { + axe.log('Could not find tags `' + unmatchedTags.join('`, `') + '`'); } } else { throw new Error(`Unknown runOnly type '${only.type}'`); diff --git a/lib/rules/identical-links-same-purpose.json b/lib/rules/identical-links-same-purpose.json index ea6e4fdb48..4786ffebe0 100644 --- a/lib/rules/identical-links-same-purpose.json +++ b/lib/rules/identical-links-same-purpose.json @@ -3,7 +3,7 @@ "selector": "a[href], area[href], [role=\"link\"]", "excludeHidden": false, "matches": "identical-links-same-purpose-matches", - "tags": ["cat.semantics", "wcag2aaa", "wcag249", "best-practice"], + "tags": ["cat.semantics", "wcag2aaa", "wcag249"], "actIds": ["b20e66", "fd3a94"], "metadata": { "description": "Ensure that links with the same accessible name serve a similar purpose", diff --git a/lib/rules/meta-refresh.json b/lib/rules/meta-refresh.json index 10317c86d8..de24867624 100644 --- a/lib/rules/meta-refresh.json +++ b/lib/rules/meta-refresh.json @@ -5,7 +5,6 @@ "tags": [ "cat.time-and-media", "wcag2a", - "wcag2aaa", "wcag221", "wcag224", "wcag325" diff --git a/test/core/base/audit.js b/test/core/base/audit.js index c8fad7340d..170de0cf08 100644 --- a/test/core/base/audit.js +++ b/test/core/base/audit.js @@ -1286,6 +1286,14 @@ describe('Audit', function() { }); describe('Audit#normalizeOptions', function() { + var axeLog; + beforeEach(function () { + axeLog = axe.log; + }); + afterEach(function () { + axe.log = axeLog; + }); + it('returns the options object when it is valid', function() { var opt = { runOnly: { @@ -1440,5 +1448,47 @@ describe('Audit', function() { }); }); }); + + it('logs an issue when a tag is unknown', function () { + var message = ''; + axe.log = function (m) { + message = m; + }; + a.normalizeOptions({ + runOnly: { + type: 'tags', + values: ['unknwon-tag'] + } + }); + assert.include(message, 'Could not find tags'); + }); + + it('logs no issues for unknown WCAG level tags', function () { + var message = ''; + axe.log = function (m) { + message = m; + }; + a.normalizeOptions({ + runOnly: { + type: 'tags', + values: ['wcag23aaa'] + } + }); + assert.isEmpty(message); + }); + + it('logs an issue when a tag is unknown, together with a wcag level tag', function () { + var message = ''; + axe.log = function (m) { + message = m; + }; + a.normalizeOptions({ + runOnly: { + type: 'tags', + values: ['wcag23aaa', 'unknwon-tag'] + } + }); + assert.include(message, 'Could not find tags'); + }); }); }); From 8f84d228910a2d01668e787f2fcc70e55ffd49b1 Mon Sep 17 00:00:00 2001 From: Dylan Barrell Date: Wed, 13 Oct 2021 10:24:33 -0400 Subject: [PATCH 30/88] docs: Update rule-proposal to add link to tag assignment (#3184) * Update rule-proposal.md * Update doc/rule-proposal.md Co-authored-by: Stephen Mathieson Co-authored-by: Stephen Mathieson --- doc/rule-proposal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/rule-proposal.md b/doc/rule-proposal.md index f07af40766..f49395c327 100644 --- a/doc/rule-proposal.md +++ b/doc/rule-proposal.md @@ -28,7 +28,7 @@ Example: "Elements must only use allowed ARIA attributes" #### Tags -Indicate which tags the rule should use. +Indicate which tags the rule should use. More information available in the [how we assign tags documentation](https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#axe-core-tags). Example: wcag2a, wcag211, cat.keyboard From fbc581d77e457fe092ecc2b95015e667292f1a08 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 13 Oct 2021 13:36:02 -0600 Subject: [PATCH 31/88] fix(color-contrast): correctly apply page background color (#3207) * fixes * finalize * sort * test * fix tests * Update lib/commons/color/get-background-stack.js Co-authored-by: Wilco Fiers * fixes * fix(color-contrast): correctly apply page background color Co-authored-by: Wilco Fiers --- lib/commons/color/get-background-color.js | 111 ++++++++++--- lib/commons/color/get-background-stack.js | 42 ++--- test/commons/color/get-background-color.js | 184 ++++++++++++++------- 3 files changed, 236 insertions(+), 101 deletions(-) diff --git a/lib/commons/color/get-background-color.js b/lib/commons/color/get-background-color.js index 230fa9d568..ff2a28bc87 100644 --- a/lib/commons/color/get-background-color.js +++ b/lib/commons/color/get-background-color.js @@ -8,23 +8,6 @@ import flattenShadowColors from './flatten-shadow-colors'; import getTextShadowColors from './get-text-shadow-colors'; import visuallyContains from '../dom/visually-contains'; -/** - * Determine if element is partially overlapped, triggering a Can't Tell result - * @private - * @param {Element} elm - * @param {Element} bgElm - * @param {Object} bgColor - * @return {Boolean} - */ -function elmPartiallyObscured(elm, bgElm, bgColor) { - var obscured = - elm !== bgElm && !visuallyContains(elm, bgElm) && bgColor.alpha !== 0; - if (obscured) { - incompleteData.set('bgColor', 'elmPartiallyObscured'); - } - return obscured; -} - /** * Returns background color for element * Uses getBackgroundStack() to get all elements rendered underneath the current element, @@ -32,12 +15,16 @@ function elmPartiallyObscured(elm, bgElm, bgColor) { * * @method getBackgroundColor * @memberof axe.commons.color - * @param {Element} elm Element to determine background color - * @param {Array} [bgElms=[]] elements to inspect - * @param {Number} shadowOutlineEmMax Thickness of `text-shadow` at which it becomes a background color + * @param {Element} elm Element to determine background color + * @param {Array} [bgElms=[]] elements to inspect + * @param {Number} shadowOutlineEmMax Thickness of `text-shadow` at which it becomes a background color * @returns {Color} */ -function getBackgroundColor(elm, bgElms = [], shadowOutlineEmMax = 0.1) { +export default function getBackgroundColor( + elm, + bgElms = [], + shadowOutlineEmMax = 0.1 +) { let bgColors = getTextShadowColors(elm, { minRatio: shadowOutlineEmMax }); if (bgColors.length) { bgColors = [bgColors.reduce(flattenShadowColors)]; @@ -79,15 +66,89 @@ function getBackgroundColor(elm, bgElms = [], shadowOutlineEmMax = 0.1) { return null; } - // Mix the colors together, on top of a default white. Colors must be mixed - // in bottom up order (background to foreground order) to produce the correct + const pageBgs = getPageBackgroundColors( + elm, + elmStack.includes(document.body) + ); + bgColors.unshift(...pageBgs); + + // Mix the colors together. Colors must be mixed in bottom up + // order (background to foreground order) to produce the correct // result. // @see https://github.com/dequelabs/axe-core/issues/2924 - bgColors.unshift(new Color(255, 255, 255, 1)); var colors = bgColors.reduce((bgColor, fgColor) => { return flattenColors(fgColor, bgColor); }); return colors; } -export default getBackgroundColor; +/** + * Determine if element is partially overlapped, triggering a Can't Tell result + * @private + * @param {Element} elm + * @param {Element} bgElm + * @param {Object} bgColor + * @return {Boolean} + */ +function elmPartiallyObscured(elm, bgElm, bgColor) { + var obscured = + elm !== bgElm && !visuallyContains(elm, bgElm) && bgColor.alpha !== 0; + if (obscured) { + incompleteData.set('bgColor', 'elmPartiallyObscured'); + } + return obscured; +} + +/** + * Get the page background color. + * @private + * @param {Element} elm + * @param {Boolean} stackContainsBody + * @return {Colors[]} + */ +function getPageBackgroundColors(elm, stackContainsBody) { + const pageColors = []; + + // Body can sometimes appear out of order in the stack: + // 1) Body is not the first element due to negative z-index elements + // 2) Elements are positioned outside of body's rect coordinates + // (see https://github.com/dequelabs/axe-core/issues/1456) + // In those instances we need to determine if we should use the + // body background or the html background color + if (!stackContainsBody) { + // if the html element defines a bgColor and body defines a + // bgColor but body's height is not the full viewport, then the + // html bgColor fills the full viewport and body bgColor only + // fills to its size. however, if the html element does not + // define a bgColor, then the body bgColor fills the full + // viewport. so if the body wasn't added to the elmStack, we + // need to know which bgColor to get (html or body) + const html = document.documentElement; + const body = document.body; + const htmlStyle = window.getComputedStyle(html); + const bodyStyle = window.getComputedStyle(body); + const htmlBgColor = getOwnBackgroundColor(htmlStyle); + const bodyBgColor = getOwnBackgroundColor(bodyStyle); + const bodyBgColorApplies = + bodyBgColor.alpha !== 0 && visuallyContains(elm, body); + + if ( + (bodyBgColor.alpha !== 0 && htmlBgColor.alpha === 0) || + (bodyBgColorApplies && bodyBgColor.alpha !== 1) + ) { + pageColors.unshift(bodyBgColor); + } + + if ( + htmlBgColor.alpha !== 0 && + (!bodyBgColorApplies || (bodyBgColorApplies && bodyBgColor.alpha !== 1)) + ) { + pageColors.unshift(htmlBgColor); + } + } + + // default page background is white + pageColors.unshift(new Color(255, 255, 255, 1)); + + return pageColors; +} diff --git a/lib/commons/color/get-background-stack.js b/lib/commons/color/get-background-stack.js index cfe0721976..d06d071564 100644 --- a/lib/commons/color/get-background-stack.js +++ b/lib/commons/color/get-background-stack.js @@ -69,32 +69,36 @@ function sortPageBackground(elmStack) { const bodyIndex = elmStack.indexOf(document.body); const bgNodes = elmStack; - // Body can sometimes appear out of order in the stack: - // 1) Body is not the first element due to negative z-index elements - // 2) Elements are positioned outside of body's rect coordinates - // (see https://github.com/dequelabs/axe-core/issues/1456) - // In those instances we want to reinsert body back into the element stack - // when not using the root document element as the html canvas for bgcolor - // prettier-ignore - const sortBodyElement = - bodyIndex > 1 || // negative z-index elements - bodyIndex === -1; // element does not intersect with body - + // body can sometimes appear out of order in the stack when it + // is not the first element due to negative z-index elements. + // however, we only want to change order if the html element + // does not define a background color (ya, it's a strange edge + // case. it turns out that if html defines a background it treats + // body as a normal element, but if it doesn't then body is treated + // as the "html" element) + const htmlBgColor = getOwnBackgroundColor( + window.getComputedStyle(document.documentElement) + ); if ( - sortBodyElement && - !elementHasImage(document.documentElement) && - getOwnBackgroundColor(window.getComputedStyle(document.documentElement)) - .alpha === 0 + bodyIndex > 1 && + htmlBgColor.alpha === 0 && + !elementHasImage(document.documentElement) ) { // Only remove document.body if it was originally contained within the element stack if (bodyIndex > 1) { bgNodes.splice(bodyIndex, 1); + + // Put the body background as the lowest element + bgNodes.push(document.body); } - // Remove document element since body will be used for bgcolor - bgNodes.splice(elmStack.indexOf(document.documentElement), 1); - // Put the body background as the lowest element - bgNodes.push(document.body); + const htmlIndex = bgNodes.indexOf(document.documentElement); + if (htmlIndex > 0) { + bgNodes.splice(htmlIndex, 1); + + // Put the html background as the lowest element + bgNodes.push(document.documentElement); + } } return bgNodes; } diff --git a/test/commons/color/get-background-color.js b/test/commons/color/get-background-color.js index f22ac33fd1..6770dac8b5 100644 --- a/test/commons/color/get-background-color.js +++ b/test/commons/color/get-background-color.js @@ -4,9 +4,18 @@ describe('color.getBackgroundColor', function() { var fixture = document.getElementById('fixture'); var shadowSupported = axe.testUtils.shadowSupport.v1; + var origBodyBg; + var origHtmlBg; + + before(function() { + origBodyBg = document.body.style.background; + origHtmlBg = document.documentElement.style.background; + }); afterEach(function() { - document.getElementById('fixture').innerHTML = ''; + document.body.style.background = origBodyBg; + document.documentElement.style.background = origHtmlBg; + axe.commons.color.incompleteData.clear(); axe._tree = undefined; }); @@ -635,7 +644,6 @@ describe('color.getBackgroundColor', function() { 'style="z-index:-1; position:absolute; width:100%; height:2em; background: #000">' + '
Some text
'; - var orig = document.body.style.background; document.body.style.background = '#FFF'; axe.testUtils.flatTreeSetup(fixture); var actual = axe.commons.color.getBackgroundColor( @@ -649,65 +657,23 @@ describe('color.getBackgroundColor', function() { assert.closeTo(actual.green, expected.green, 0.5); assert.closeTo(actual.blue, expected.blue, 0.5); assert.closeTo(actual.alpha, expected.alpha, 0.1); - - document.body.style.background = orig; - }); - - it('returns the body background', function() { - fixture.innerHTML = '
elm
'; - var orig = document.body.style.background; - document.body.style.background = '#F00'; - - axe.testUtils.flatTreeSetup(fixture); - var actual = axe.commons.color.getBackgroundColor( - document.getElementById('target'), - [] - ); - var expected = new axe.commons.color.Color(255, 0, 0, 1); - document.body.style.background = orig; - - assert.closeTo(actual.red, expected.red, 0.5); - assert.closeTo(actual.green, expected.green, 0.5); - assert.closeTo(actual.blue, expected.blue, 0.5); - assert.closeTo(actual.alpha, expected.alpha, 0.1); }); - it('returns the body background even when the body is MUCH larger than the screen', function() { - fixture.innerHTML = '
elm
'; - var orig = document.body.style.background; - document.body.style.background = '#F00'; - - axe.testUtils.flatTreeSetup(fixture); - var actual = axe.commons.color.getBackgroundColor( - document.getElementById('target'), - [] - ); - var expected = new axe.commons.color.Color(255, 0, 0, 1); - document.body.style.background = orig; - - assert.closeTo(actual.red, expected.red, 0.5); - assert.closeTo(actual.green, expected.green, 0.5); - assert.closeTo(actual.blue, expected.blue, 0.5); - assert.closeTo(actual.alpha, expected.alpha, 0.1); - }); + it('should return null for negative z-index element when html and body have a background', function() { + fixture.innerHTML = + '
' + + '
'; - it('returns the html background', function() { - fixture.innerHTML = '
'; - var orig = document.documentElement.style.background; document.documentElement.style.background = '#0F0'; - + document.body.style.background = '#FFF'; axe.testUtils.flatTreeSetup(fixture); var actual = axe.commons.color.getBackgroundColor( document.getElementById('target'), [] ); - var expected = new axe.commons.color.Color(0, 255, 0, 1); - document.documentElement.style.background = orig; - assert.closeTo(actual.red, expected.red, 0.5); - assert.closeTo(actual.green, expected.green, 0.5); - assert.closeTo(actual.blue, expected.blue, 0.5); - assert.closeTo(actual.alpha, expected.alpha, 0.1); + assert.isNull(actual); }); it('should return background color for inline elements that do not fit the viewport', function() { @@ -747,7 +713,7 @@ describe('color.getBackgroundColor', function() { // size body element so that target element is positioned outside of background var originalHeight = document.body.style.height; - var originalBg = document.body.style.background; + var originalMargin = document.body.style.margin; document.body.style.height = '1px'; document.body.style.background = '#000'; document.body.style.margin = 0; @@ -762,7 +728,7 @@ describe('color.getBackgroundColor', function() { assert.closeTo(actual.alpha, 1, 0); document.body.style.height = originalHeight; - document.body.style.background = originalBg; + document.body.style.margin = originalMargin; }); it('should return the html canvas bgColor when element content does not overlap with body', function() { @@ -771,8 +737,6 @@ describe('color.getBackgroundColor', function() { // size body element so that target element is positioned outside of background var originalHeight = document.body.style.height; - var originalBg = document.body.style.background; - var originalRootBg = document.documentElement.style.background; document.body.style.height = '1px'; document.body.style.background = '#0f0'; document.documentElement.style.background = '#f00'; @@ -787,8 +751,6 @@ describe('color.getBackgroundColor', function() { assert.closeTo(actual.alpha, 1, 0); document.body.style.height = originalHeight; - document.body.style.background = originalBg; - document.documentElement.style.background = originalRootBg; }); (shadowSupported ? it : xit)('finds colors in shadow boundaries', function() { @@ -1029,4 +991,112 @@ describe('color.getBackgroundColor', function() { assert.closeTo(actual.blue, expected.blue, 0.5); assert.closeTo(actual.alpha, expected.alpha, 0.1); }); + + describe('body and document', function() { + it('returns the body background', function() { + fixture.innerHTML = '
elm
'; + document.body.style.background = '#F00'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(255, 0, 0, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + + it('returns the body background even when the body is MUCH larger than the screen', function() { + fixture.innerHTML = '
elm
'; + document.body.style.background = '#F00'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(255, 0, 0, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + + it('returns the html background', function() { + fixture.innerHTML = '
'; + document.documentElement.style.background = '#0F0'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(0, 255, 0, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + + it('returns the html background when body does not cover the element', function() { + fixture.innerHTML = + '
'; + document.documentElement.style.background = '#0F0'; + document.body.style.background = '#00F'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(0, 255, 0, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + + it('returns the body background when body does cover the element', function() { + fixture.innerHTML = '
'; + document.documentElement.style.background = '#0F0'; + document.body.style.background = '#00F'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(0, 0, 255, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + + it('returns both the html and body background if the body has alpha', function() { + fixture.innerHTML = '
'; + document.documentElement.style.background = '#0F0'; + document.body.style.background = 'rgba(0, 0, 255, 0.5)'; + + axe.testUtils.flatTreeSetup(fixture); + var actual = axe.commons.color.getBackgroundColor( + document.getElementById('target'), + [] + ); + var expected = new axe.commons.color.Color(0, 128, 128, 1); + + assert.closeTo(actual.red, expected.red, 0.5); + assert.closeTo(actual.green, expected.green, 0.5); + assert.closeTo(actual.blue, expected.blue, 0.5); + assert.closeTo(actual.alpha, expected.alpha, 0.1); + }); + }); }); From 0677565941486cf339e7267760d4e533d4a29a05 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Thu, 14 Oct 2021 09:22:02 +0200 Subject: [PATCH 32/88] fix: greater consistency of help / description text (#3204) * fix: greater consistency of help / description text * Apply suggestions from code review Co-authored-by: Steven Lambert <2433219+straker@users.noreply.github.com> * Update lib/rules/p-as-heading.json Co-authored-by: Glenda Sims Co-authored-by: Steven Lambert <2433219+straker@users.noreply.github.com> Co-authored-by: Glenda Sims --- lib/rules/aria-roledescription.json | 2 +- lib/rules/aria-toggle-field-name.json | 2 +- lib/rules/css-orientation-lock.json | 2 +- lib/rules/focus-order-semantics.json | 4 ++-- lib/rules/hidden-content.json | 2 +- lib/rules/identical-links-same-purpose.json | 2 +- lib/rules/link-in-text-block.json | 4 ++-- lib/rules/nested-interactive.json | 4 ++-- lib/rules/no-autoplay-audio.json | 2 +- lib/rules/p-as-heading.json | 4 ++-- lib/rules/role-img-alt.json | 2 +- lib/rules/scrollable-region-focusable.json | 4 ++-- lib/rules/svg-img-alt.json | 4 ++-- lib/rules/table-duplicate-name.json | 4 ++-- lib/rules/td-has-header.json | 4 ++-- lib/rules/td-headers-attr.json | 4 ++-- lib/rules/th-has-data-cells.json | 4 ++-- 17 files changed, 27 insertions(+), 27 deletions(-) diff --git a/lib/rules/aria-roledescription.json b/lib/rules/aria-roledescription.json index 594d638e7e..64a43b4346 100644 --- a/lib/rules/aria-roledescription.json +++ b/lib/rules/aria-roledescription.json @@ -4,7 +4,7 @@ "tags": ["cat.aria", "wcag2a", "wcag412"], "metadata": { "description": "Ensure aria-roledescription is only used on elements with an implicit or explicit role", - "help": "Use aria-roledescription on elements with a semantic role" + "help": "aria-roledescription must be on elements with a semantic role" }, "all": [], "any": ["aria-roledescription"], diff --git a/lib/rules/aria-toggle-field-name.json b/lib/rules/aria-toggle-field-name.json index 1f99c95a5d..966ce517a2 100644 --- a/lib/rules/aria-toggle-field-name.json +++ b/lib/rules/aria-toggle-field-name.json @@ -5,7 +5,7 @@ "tags": ["cat.aria", "wcag2a", "wcag412", "ACT"], "metadata": { "description": "Ensures every ARIA toggle field has an accessible name", - "help": "ARIA toggle fields have an accessible name" + "help": "ARIA toggle fields must have an accessible name" }, "all": [], "any": [ diff --git a/lib/rules/css-orientation-lock.json b/lib/rules/css-orientation-lock.json index 19b80121ce..c37fda6cde 100644 --- a/lib/rules/css-orientation-lock.json +++ b/lib/rules/css-orientation-lock.json @@ -5,7 +5,7 @@ "actIds": ["b33eff"], "metadata": { "description": "Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations", - "help": "CSS Media queries are not used to lock display orientation" + "help": "CSS Media queries must not lock display orientation" }, "all": ["css-orientation-lock"], "any": [], diff --git a/lib/rules/focus-order-semantics.json b/lib/rules/focus-order-semantics.json index 5f9dbfb45d..02cd707e45 100644 --- a/lib/rules/focus-order-semantics.json +++ b/lib/rules/focus-order-semantics.json @@ -4,8 +4,8 @@ "matches": "inserted-into-focus-order-matches", "tags": ["cat.keyboard", "best-practice", "experimental"], "metadata": { - "description": "Ensures elements in the focus order have an appropriate role", - "help": "Elements in the focus order need a role appropriate for interactive content" + "description": "Ensures elements in the focus order have a role appropriate for interactive content", + "help": "Elements in the focus order should have an appropriate role" }, "all": [], "any": ["has-widget-role", "valid-scrollable-semantics"], diff --git a/lib/rules/hidden-content.json b/lib/rules/hidden-content.json index 02b264d03e..b4728a2234 100644 --- a/lib/rules/hidden-content.json +++ b/lib/rules/hidden-content.json @@ -5,7 +5,7 @@ "tags": ["cat.structure", "experimental", "review-item", "best-practice"], "metadata": { "description": "Informs users about hidden content.", - "help": "Hidden content on the page cannot be analyzed" + "help": "Hidden content on the page should be analyzed" }, "all": [], "any": ["hidden-content"], diff --git a/lib/rules/identical-links-same-purpose.json b/lib/rules/identical-links-same-purpose.json index 4786ffebe0..6590de7650 100644 --- a/lib/rules/identical-links-same-purpose.json +++ b/lib/rules/identical-links-same-purpose.json @@ -7,7 +7,7 @@ "actIds": ["b20e66", "fd3a94"], "metadata": { "description": "Ensure that links with the same accessible name serve a similar purpose", - "help": "Links with the same name have a similar purpose" + "help": "Links with the same name must have a similar purpose" }, "all": ["identical-links-same-purpose"], "any": [], diff --git a/lib/rules/link-in-text-block.json b/lib/rules/link-in-text-block.json index 3cbc4210c2..b4b6e37535 100644 --- a/lib/rules/link-in-text-block.json +++ b/lib/rules/link-in-text-block.json @@ -5,8 +5,8 @@ "excludeHidden": false, "tags": ["cat.color", "experimental", "wcag2a", "wcag141"], "metadata": { - "description": "Links can be distinguished without relying on color", - "help": "Links must be distinguished from surrounding text in a way that does not rely on color" + "description": "Ensure links are distinguished from surrounding text in a way that does not rely on color", + "help": "Links must be distinguishable without relying on color" }, "all": ["link-in-text-block"], "any": [], diff --git a/lib/rules/nested-interactive.json b/lib/rules/nested-interactive.json index ad6b5b0770..5293a7794f 100644 --- a/lib/rules/nested-interactive.json +++ b/lib/rules/nested-interactive.json @@ -4,8 +4,8 @@ "tags": ["cat.keyboard", "wcag2a", "wcag412"], "actIds": ["307n5z"], "metadata": { - "description": "Nested interactive controls are not announced by screen readers", - "help": "Ensure interactive controls are not nested" + "description": "Ensure controls are not nested as they are not announced by screen readers", + "help": "Interactive controls must not be nested" }, "all": [], "any": ["no-focusable-content"], diff --git a/lib/rules/no-autoplay-audio.json b/lib/rules/no-autoplay-audio.json index 9a7cb5cd5b..2a1d64dc5d 100644 --- a/lib/rules/no-autoplay-audio.json +++ b/lib/rules/no-autoplay-audio.json @@ -7,7 +7,7 @@ "actIds": ["80f0bf"], "metadata": { "description": "Ensures