From e3a5c211fe007736d98a16d69995318c2c651f2d Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:47:24 -0600 Subject: [PATCH 1/7] fix(scrollable-region-focusable): change impact to serious (#3959) * fix(scrollable-region-focusable): change impact to serious * forgot check --- doc/rule-descriptions.md | 2 +- lib/checks/keyboard/focusable-content.json | 2 +- lib/checks/keyboard/focusable-element.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index b5fa1a1b37..88757d9ebe 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -63,7 +63,7 @@ | [no-autoplay-audio](https://dequeuniversity.com/rules/axe/4.6/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, ACT | needs review | [80f0bf](https://act-rules.github.io/rules/80f0bf) | | [object-alt](https://dequeuniversity.com/rules/axe/4.6/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.6/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) | -| [scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.6/scrollable-region-focusable?application=RuleDescription) | Ensure elements that have scrollable content are accessible by keyboard | Moderate | cat.keyboard, wcag2a, wcag211 | failure | [0ssw9k](https://act-rules.github.io/rules/0ssw9k) | +| [scrollable-region-focusable](https://dequeuniversity.com/rules/axe/4.6/scrollable-region-focusable?application=RuleDescription) | Ensure elements that have scrollable content are accessible by keyboard | Serious | cat.keyboard, wcag2a, wcag211 | failure | [0ssw9k](https://act-rules.github.io/rules/0ssw9k) | | [select-name](https://dequeuniversity.com/rules/axe/4.6/select-name?application=RuleDescription) | Ensures select element has an accessible name | Minor, Critical | cat.forms, wcag2a, wcag412, section508, section508.22.n, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | | [server-side-image-map](https://dequeuniversity.com/rules/axe/4.6/server-side-image-map?application=RuleDescription) | Ensures that server-side image maps are not used | Minor | cat.text-alternatives, wcag2a, wcag211, section508, section508.22.f | needs review | | | [svg-img-alt](https://dequeuniversity.com/rules/axe/4.6/svg-img-alt?application=RuleDescription) | Ensures <svg> elements with an img, graphics-document or graphics-symbol role have an accessible text | Serious | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a, ACT | failure, needs review | [7d6734](https://act-rules.github.io/rules/7d6734) | diff --git a/lib/checks/keyboard/focusable-content.json b/lib/checks/keyboard/focusable-content.json index 9a91fff842..11db612fb3 100644 --- a/lib/checks/keyboard/focusable-content.json +++ b/lib/checks/keyboard/focusable-content.json @@ -2,7 +2,7 @@ "id": "focusable-content", "evaluate": "focusable-content-evaluate", "metadata": { - "impact": "moderate", + "impact": "serious", "messages": { "pass": "Element contains focusable elements", "fail": "Element should have focusable content" diff --git a/lib/checks/keyboard/focusable-element.json b/lib/checks/keyboard/focusable-element.json index 9045e78f92..da108b768d 100644 --- a/lib/checks/keyboard/focusable-element.json +++ b/lib/checks/keyboard/focusable-element.json @@ -2,7 +2,7 @@ "id": "focusable-element", "evaluate": "focusable-element-evaluate", "metadata": { - "impact": "moderate", + "impact": "serious", "messages": { "pass": "Element is focusable", "fail": "Element should be focusable" From 2842395f9a8990f670e7025749ff8301b68a15ae Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:47:35 -0600 Subject: [PATCH 2/7] fix(aria-allowed-attrs): allow aria-description and aria-braille* attrs (#3956) * fix(aria-allowed-attrs): allow aria-description and aria-braille* attrs * fix test --- lib/standards/aria-attrs.js | 13 ++ .../standards/get-global-aria-attrs.js | 3 + .../rules/aria-allowed-attr/passes.html | 201 ++++++++++++++++++ 3 files changed, 217 insertions(+) diff --git a/lib/standards/aria-attrs.js b/lib/standards/aria-attrs.js index 85bf547e74..1143ca1fc7 100644 --- a/lib/standards/aria-attrs.js +++ b/lib/standards/aria-attrs.js @@ -12,6 +12,14 @@ const ariaAttrs = { type: 'nmtoken', values: ['inline', 'list', 'both', 'none'] }, + 'aria-braillelabel': { + type: 'string', + global: true + }, + 'aria-brailleroledescription': { + type: 'string', + global: true + }, 'aria-busy': { type: 'boolean', global: true @@ -48,6 +56,11 @@ const ariaAttrs = { allowEmpty: true, global: true }, + 'aria-description': { + type: 'string', + allowEmpty: true, + global: true + }, 'aria-details': { type: 'idref', allowEmpty: true, diff --git a/test/commons/standards/get-global-aria-attrs.js b/test/commons/standards/get-global-aria-attrs.js index a1bbf28408..0141f255a3 100644 --- a/test/commons/standards/get-global-aria-attrs.js +++ b/test/commons/standards/get-global-aria-attrs.js @@ -14,10 +14,13 @@ describe('standards.getGlobalAriaAttrs', function () { var globalAttrs = getGlobalAriaAttrs(); assert.deepEqual(globalAttrs, [ 'aria-atomic', + 'aria-braillelabel', + 'aria-brailleroledescription', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', + 'aria-description', 'aria-details', 'aria-disabled', 'aria-dropeffect', diff --git a/test/integration/rules/aria-allowed-attr/passes.html b/test/integration/rules/aria-allowed-attr/passes.html index fe562556bc..9bee42b07c 100644 --- a/test/integration/rules/aria-allowed-attr/passes.html +++ b/test/integration/rules/aria-allowed-attr/passes.html @@ -7,9 +7,12 @@ id="pass1" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -33,9 +36,12 @@ id="pass2" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -61,9 +67,12 @@ aria-activedescendant="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -89,9 +98,12 @@ aria-posinset="value" aria-setsize="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -115,9 +127,12 @@ id="pass5" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -142,9 +157,12 @@ aria-expanded="value" aria-pressed="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -168,9 +186,12 @@ id="pass7" aria-checked="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -203,9 +224,12 @@ aria-selected="value" aria-required="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -233,9 +257,12 @@ aria-expanded="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -259,9 +286,12 @@ id="pass10" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -285,9 +315,12 @@ id="pass11" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -311,9 +344,12 @@ id="pass12" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -337,9 +373,12 @@ id="pass13" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -364,9 +403,12 @@ id="pass14" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -390,9 +432,12 @@ id="pass15" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -416,9 +461,12 @@ id="pass16" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -442,9 +490,12 @@ id="pass17" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -472,9 +523,12 @@ aria-activedescendant="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -507,9 +561,12 @@ aria-expanded="value" aria-required="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -534,9 +591,12 @@ aria-activedescendant="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -560,9 +620,12 @@ id="pass21" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -586,9 +649,12 @@ id="pass22" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -612,9 +678,12 @@ id="pass23" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -638,9 +707,12 @@ id="pass24" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -668,9 +740,12 @@ aria-expanded="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -698,9 +773,12 @@ aria-setsize="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -724,9 +802,12 @@ id="pass27" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -750,9 +831,12 @@ id="pass28" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -776,9 +860,12 @@ id="pass29" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -802,9 +889,12 @@ id="pass30" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -830,9 +920,12 @@ aria-expanded="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -858,9 +951,12 @@ aria-expanded="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -886,9 +982,12 @@ aria-expanded="value" aria-setsize="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -914,9 +1013,12 @@ aria-posinset="value" aria-setsize="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -942,9 +1044,12 @@ aria-setsize="value" aria-checked="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -968,9 +1073,12 @@ id="pass36" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -994,9 +1102,12 @@ id="pass37" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1023,9 +1134,12 @@ aria-setsize="value" aria-checked="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1052,9 +1166,12 @@ aria-valuemax="value" aria-valuemin="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1081,9 +1198,12 @@ aria-setsize="value" aria-checked="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1109,9 +1229,12 @@ aria-required="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1136,9 +1259,12 @@ id="pass42" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1167,9 +1293,12 @@ aria-activedescendant="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1192,9 +1321,12 @@ role="rowgroup" id="pass44" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1226,9 +1358,12 @@ aria-expanded="value" aria-selected="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1257,8 +1392,11 @@ aria-valuemax="value" aria-valuemin="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1282,9 +1420,12 @@ id="pass47" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1308,9 +1449,12 @@ id="pass48" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1342,9 +1486,12 @@ aria-valuemax="value" aria-valuemin="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1373,9 +1520,12 @@ aria-valuemax="value" aria-valuemin="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1400,9 +1550,12 @@ id="pass51" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1429,9 +1582,12 @@ aria-posinset="value" aria-setsize="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1459,9 +1615,12 @@ aria-multiselectable="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1485,9 +1644,12 @@ id="pass54" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1515,9 +1677,12 @@ aria-readonly="value" aria-required="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1542,9 +1707,12 @@ id="pass56" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1569,9 +1737,12 @@ aria-activedescendant="value" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1596,9 +1767,12 @@ id="pass58" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1626,9 +1800,12 @@ aria-expanded="value" aria-orientation="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1660,9 +1837,12 @@ aria-required="value" aria-rowcount="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1691,9 +1871,12 @@ aria-posinset="value" aria-setsize="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1717,9 +1900,12 @@ id="pass62" aria-checked="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1746,9 +1932,12 @@ aria-rowindex="value" aria-rowspan="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1776,9 +1965,12 @@ aria-readonly="value" aria-required="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1803,9 +1995,12 @@ id="pass65" aria-expanded="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1828,9 +2023,12 @@ role="text" id="pass66" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" @@ -1855,9 +2053,12 @@ aria-colcount="value" aria-rowcount="value" aria-atomic="value" + aria-braillelabel="value" + aria-brailleroledescription="value" aria-busy="value" aria-controls="value" aria-describedby="value" + aria-description="value" aria-details="value" aria-disabled="value" aria-dropeffect="value" From cce75869be032006dc505a2af853886943973319 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 24 Mar 2023 08:47:48 -0600 Subject: [PATCH 3/7] fix(aria-required-children): list elements that are not allowed (#3951) * fix(aria-required-children): list elements that are not allowed * jsdoc * fix tests * remove dups --- .../aria/aria-required-children-evaluate.js | 145 ++++++++++++------ lib/checks/aria/aria-required-children.json | 2 +- locales/_template.json | 2 +- test/checks/aria/required-children.js | 35 ++++- 4 files changed, 129 insertions(+), 55 deletions(-) diff --git a/lib/checks/aria/aria-required-children-evaluate.js b/lib/checks/aria/aria-required-children-evaluate.js index 205ef1c970..940c824b62 100644 --- a/lib/checks/aria/aria-required-children-evaluate.js +++ b/lib/checks/aria/aria-required-children-evaluate.js @@ -12,6 +12,71 @@ import { isVisibleToScreenReaders } from '../../commons/dom'; +/** + * Check that an element owns all required children for its explicit role. + * + * Required roles are taken from the `ariaRoles` standards object from the roles `requiredOwned` property. + * + * @memberof checks + * @param {Boolean} options.reviewEmpty List of ARIA roles that should be flagged as "Needs Review" rather than a violation if the element has no owned children. + * @data {String[]} List of all missing owned roles. + * @returns {Mixed} True if the element owns all required roles. Undefined if `options.reviewEmpty=true` and the element has no owned children. False otherwise. + */ +export default function ariaRequiredChildrenEvaluate( + node, + options, + virtualNode +) { + const reviewEmpty = + options && Array.isArray(options.reviewEmpty) ? options.reviewEmpty : []; + const role = getExplicitRole(virtualNode, { dpub: true }); + const required = requiredOwned(role); + if (required === null) { + return true; + } + + const ownedRoles = getOwnedRoles(virtualNode, required); + const unallowed = ownedRoles.filter(({ role }) => !required.includes(role)); + + if (unallowed.length) { + this.relatedNodes(unallowed.map(({ ownedElement }) => ownedElement)); + this.data({ + messageKey: 'unallowed', + values: unallowed + .map(({ ownedElement, attr }) => + getUnallowedSelector(ownedElement, attr) + ) + .filter((selector, index, array) => array.indexOf(selector) === index) + .join(', ') + }); + return false; + } + + const missing = missingRequiredChildren( + virtualNode, + role, + required, + ownedRoles + ); + if (!missing) { + return true; + } + + this.data(missing); + + // Only review empty nodes when a node is both empty and does not have an aria-owns relationship + if ( + reviewEmpty.includes(role) && + !hasContentVirtual(virtualNode, false, true) && + !ownedRoles.length && + (!virtualNode.hasAttr('aria-owns') || !idrefs(node, 'aria-owns').length) + ) { + return undefined; + } + + return false; +} + /** * Get all owned roles of an element */ @@ -26,10 +91,9 @@ function getOwnedRoles(virtualNode, required) { const role = getRole(ownedElement, { noPresentational: true }); - const hasGlobalAria = getGlobalAriaAttrs().some(attr => - ownedElement.hasAttr(attr) - ); - const hasGlobalAriaOrFocusable = hasGlobalAria || isFocusable(ownedElement); + const globalAriaAttr = getGlobalAriaAttr(ownedElement); + const hasGlobalAriaOrFocusable = + !!globalAriaAttr || isFocusable(ownedElement); // if owned node has no role or is presentational, or if role // allows group or rowgroup, we keep parsing the descendant tree. @@ -43,7 +107,11 @@ function getOwnedRoles(virtualNode, required) { ) { ownedElements.push(...ownedElement.children); } else if (role || hasGlobalAriaOrFocusable) { - ownedRoles.push({ role, ownedElement }); + ownedRoles.push({ + role, + attr: globalAriaAttr || 'tabindex', + ownedElement + }); } } @@ -71,58 +139,35 @@ function missingRequiredChildren(virtualNode, role, required, ownedRoles) { } /** - * Check that an element owns all required children for its explicit role. - * - * Required roles are taken from the `ariaRoles` standards object from the roles `requiredOwned` property. - * - * @memberof checks - * @param {Boolean} options.reviewEmpty List of ARIA roles that should be flagged as "Needs Review" rather than a violation if the element has no owned children. - * @data {String[]} List of all missing owned roles. - * @returns {Mixed} True if the element owns all required roles. Undefined if `options.reviewEmpty=true` and the element has no owned children. False otherwise. + * Get the first global ARIA attribute the element has. + * @param {VirtualNode} vNode + * @return {String|null} */ -function ariaRequiredChildrenEvaluate(node, options, virtualNode) { - const reviewEmpty = - options && Array.isArray(options.reviewEmpty) ? options.reviewEmpty : []; - const role = getExplicitRole(virtualNode, { dpub: true }); - const required = requiredOwned(role); - if (required === null) { - return true; - } +function getGlobalAriaAttr(vNode) { + return getGlobalAriaAttrs().find(attr => vNode.hasAttr(attr)); +} - const ownedRoles = getOwnedRoles(virtualNode, required); - const unallowed = ownedRoles.filter(({ role }) => !required.includes(role)); +/** + * Return a simple selector for an unallowed element. + * @param {VirtualNode} vNode + * @param {String} [attr] - Optional attribute which made the element unallowed + * @return {String} + */ +function getUnallowedSelector(vNode, attr) { + const { nodeName, nodeType } = vNode.props; - if (unallowed.length) { - this.relatedNodes(unallowed.map(({ ownedElement }) => ownedElement)); - this.data({ - messageKey: 'unallowed' - }); - return false; + if (nodeType === 3) { + return `#text`; } - const missing = missingRequiredChildren( - virtualNode, - role, - required, - ownedRoles - ); - if (!missing) { - return true; + const role = getExplicitRole(vNode, { dpub: true }); + if (role) { + return `[role=${role}]`; } - this.data(missing); - - // Only review empty nodes when a node is both empty and does not have an aria-owns relationship - if ( - reviewEmpty.includes(role) && - !hasContentVirtual(virtualNode, false, true) && - !ownedRoles.length && - (!virtualNode.hasAttr('aria-owns') || !idrefs(node, 'aria-owns').length) - ) { - return undefined; + if (attr) { + return nodeName + `[${attr}]`; } - return false; + return nodeName; } - -export default ariaRequiredChildrenEvaluate; diff --git a/lib/checks/aria/aria-required-children.json b/lib/checks/aria/aria-required-children.json index 38618dbc19..db1e2bf630 100644 --- a/lib/checks/aria/aria-required-children.json +++ b/lib/checks/aria/aria-required-children.json @@ -24,7 +24,7 @@ "fail": { "singular": "Required ARIA child role not present: ${data.values}", "plural": "Required ARIA children role not present: ${data.values}", - "unallowed": "Element has children which are not allowed (see related nodes)" + "unallowed": "Element has children which are not allowed: ${data.values}" }, "incomplete": { "singular": "Expecting ARIA child role to be added: ${data.values}", diff --git a/locales/_template.json b/locales/_template.json index 7ac37e6d57..e41a1b4514 100644 --- a/locales/_template.json +++ b/locales/_template.json @@ -477,7 +477,7 @@ "fail": { "singular": "Required ARIA child role not present: ${data.values}", "plural": "Required ARIA children role not present: ${data.values}", - "unallowed": "Element has children which are not allowed (see related nodes)" + "unallowed": "Element has children which are not allowed: ${data.values}" }, "incomplete": { "singular": "Expecting ARIA child role to be added: ${data.values}", diff --git a/test/checks/aria/required-children.js b/test/checks/aria/required-children.js index 34c5c312c4..47191efb09 100644 --- a/test/checks/aria/required-children.js +++ b/test/checks/aria/required-children.js @@ -153,7 +153,10 @@ describe('aria-required-children', () => { axe._tree, '[role="tabpanel"]' )[0]; - assert.deepEqual(checkContext._data, { messageKey: 'unallowed' }); + assert.deepEqual(checkContext._data, { + messageKey: 'unallowed', + values: '[role=tabpanel]' + }); assert.deepEqual(checkContext._relatedNodes, [unallowed]); }); @@ -171,7 +174,10 @@ describe('aria-required-children', () => { axe._tree, '[aria-live="polite"]' )[0]; - assert.deepEqual(checkContext._data, { messageKey: 'unallowed' }); + assert.deepEqual(checkContext._data, { + messageKey: 'unallowed', + values: 'div[aria-live]' + }); assert.deepEqual(checkContext._relatedNodes, [unallowed]); }); @@ -189,10 +195,33 @@ describe('aria-required-children', () => { axe._tree, '[tabindex="0"]' )[0]; - assert.deepEqual(checkContext._data, { messageKey: 'unallowed' }); + assert.deepEqual(checkContext._data, { + messageKey: 'unallowed', + values: 'div[tabindex]' + }); assert.deepEqual(checkContext._relatedNodes, [unallowed]); }); + it('should remove duplicate unallowed selectors', () => { + const params = checkSetup(` +
+
+
List item 1
+
+
+ `); + assert.isFalse( + axe.testUtils + .getCheckEvaluate('aria-required-children') + .apply(checkContext, params) + ); + + assert.deepEqual(checkContext._data, { + messageKey: 'unallowed', + values: '[role=tabpanel]' + }); + }); + it('should pass when list has child with aria-hidden', () => { const params = checkSetup( '
' + From 78264ee663d528bc3fbfc9ea7dbba180259f01af Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Wed, 29 Mar 2023 10:55:02 +0200 Subject: [PATCH 4/7] feat(d.ts): setup/teardown, reporters & metadata definitions (#3966) --- axe.d.ts | 83 +++++++++++++++++++++++++++--- typings/axe-core/axe-core-tests.ts | 76 ++++++++++++++++++++------- 2 files changed, 134 insertions(+), 25 deletions(-) diff --git a/axe.d.ts b/axe.d.ts index e9a447e4ae..c174b24c0f 100644 --- a/axe.d.ts +++ b/axe.d.ts @@ -190,12 +190,13 @@ declare namespace axe { help: string; }; } + interface CheckMessages { + pass: string | { [key: string]: string }; + fail: string | { [key: string]: string }; + incomplete: string | { [key: string]: string }; + } interface CheckLocale { - [key: string]: { - pass: string | { [key: string]: string }; - fail: string | { [key: string]: string }; - incomplete: string | { [key: string]: string }; - }; + [key: string]: CheckMessages; } interface Locale { lang?: string; @@ -237,7 +238,7 @@ declare namespace axe { } interface Spec { branding?: string | Branding; - reporter?: ReporterVersion; + reporter?: ReporterVersion | string | AxeReporter; checks?: Check[]; rules?: Rule[]; standards?: Standards; @@ -263,6 +264,10 @@ declare namespace axe { options?: any; matches?: string; enabled?: boolean; + metadata?: { + impact?: ImpactValue; + messages?: CheckMessages; + }; } interface Rule { id: string; @@ -277,6 +282,7 @@ declare namespace axe { tags?: string[]; matches?: string; reviewOnFail?: boolean; + metadata?: Omit; } interface AxePlugin { id: string; @@ -319,6 +325,40 @@ declare namespace axe { frameSelector: CrossTreeSelector; frameContext: FrameContextObject; } + + interface RawNodeResult { + any: CheckResult[]; + all: CheckResult[]; + none: CheckResult[]; + impact: ImpactValue | null; + result: T; + } + + interface RawResult extends Omit { + inapplicable: []; + passes: RawNodeResult<'passed'>[]; + incomplete: RawNodeResult<'incomplete'>[]; + violations: RawNodeResult<'failed'>[]; + pageLevel: boolean; + result: 'failed' | 'passed' | 'incomplete' | 'inapplicable'; + } + + type AxeReporter = ( + rawResults: RawResult[], + option: RunOptions, + callback: (report: T) => void + ) => void; + + interface VirtualNode { + actualNode?: Node; + shadowId?: string; + children?: VirtualNode[]; + parent?: VirtualNode; + attr(attr: string): string | null; + hasAttr(attr: string): boolean; + props: { [key: string]: unknown }; + } + interface Utils { getFrameContexts: ( context?: ElementContext, @@ -326,7 +366,9 @@ declare namespace axe { ) => FrameContext[]; shadowSelect: (selector: CrossTreeSelector) => Element | null; shadowSelectAll: (selector: CrossTreeSelector) => Element[]; + getStandards(): Required; } + interface EnvironmentData { testEngine: TestEngine; testRunner: TestRunner; @@ -436,6 +478,35 @@ declare namespace axe { */ function frameMessenger(frameMessenger: FrameMessenger): void; + /** + * Setup axe-core so axe.common functions can work properly. + */ + function setup(node?: Element | Document): VirtualNode; + + /** + * Clean up axe-core tree and caches. `axe.run` will call this function at the end of the run so there's no need to call it yourself afterwards. + */ + function teardown(): void; + + /** + * Check if a reporter is registered + */ + function hasReporter(reporterName: string): boolean; + + /** + * Get a reporter based the name it is registered with + */ + function getReporter(reporterName: string): AxeReporter; + + /** + * Register a new reporter, optionally setting it as the default + */ + function addReporter( + reporterName: string, + reporter: AxeReporter, + isDefault?: boolean + ): void; + // axe.frameMessenger type FrameMessenger = { open: (topicHandler: TopicHandler) => Close | void; diff --git a/typings/axe-core/axe-core-tests.ts b/typings/axe-core/axe-core-tests.ts index ba83d9fd5f..309dc9e75a 100644 --- a/typings/axe-core/axe-core-tests.ts +++ b/typings/axe-core/axe-core-tests.ts @@ -223,10 +223,22 @@ var spec: axe.Spec = { id: 'custom-check', evaluate: function () { return true; + }, + metadata: { + impact: 'minor', + messages: { + pass: 'yes', + fail: 'nope', + incomplete: { + maybe: 'maybe', + or: 'maybe not' + } + } } } ], standards: { + ...axe.utils.getStandards(), ariaRoles: { 'custom-role': { type: 'widget', @@ -251,7 +263,13 @@ var spec: axe.Spec = { rules: [ { id: 'custom-rule', - any: ['custom-check'] + any: ['custom-check'], + metadata: { + description: 'custom rule', + help: 'different help', + helpUrl: 'https://example.com', + tags: ['custom'] + } } ] }; @@ -270,24 +288,6 @@ rules.forEach(rule => { rule.ruleId.substr(1234); }); -// Plugins -var pluginSrc: axe.AxePlugin = { - id: 'doStuff', - run: (data: any, callback: Function) => { - callback(); - }, - commands: [ - { - id: 'run-doStuff', - callback: (data: any, callback: Function) => { - axe.plugins['doStuff'].run(data, callback); - } - } - ] -}; -axe.registerPlugin(pluginSrc); -axe.cleanup(); - axe.configure({ locale: { checks: { @@ -322,3 +322,41 @@ axe.configure({ } } }); + +// Reporters +let fooReporter = ( + results: axe.RawResult[], + options: axe.RunOptions, + cb: (out: 'foo') => void +) => { + cb('foo'); +}; + +axe.addReporter<'foo'>('foo', fooReporter, true); +axe.configure({ reporter: fooReporter }); +fooReporter = axe.getReporter<'foo'>('foo'); +const hasFoo: boolean = axe.hasReporter('foo'); + +// setup & teardown +axe.setup(); +axe.setup(document); +axe.setup(document.createElement('div')); +axe.teardown(); + +// Plugins +var pluginSrc: axe.AxePlugin = { + id: 'doStuff', + run: (data: any, callback: Function) => { + callback(); + }, + commands: [ + { + id: 'run-doStuff', + callback: (data: any, callback: Function) => { + axe.plugins['doStuff'].run(data, callback); + } + } + ] +}; +axe.registerPlugin(pluginSrc); +axe.cleanup(); From 1664e57b3e06ecd71ad34549eb3f2ad3fb958105 Mon Sep 17 00:00:00 2001 From: Wilco Fiers Date: Wed, 29 Mar 2023 12:43:06 +0200 Subject: [PATCH 5/7] ci: work around puppeteer cache problem --- doc/examples/puppeteer/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/puppeteer/package.json b/doc/examples/puppeteer/package.json index e923712d68..d73d26b257 100644 --- a/doc/examples/puppeteer/package.json +++ b/doc/examples/puppeteer/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "axe-core": "^4.6.2", - "puppeteer": "^19.7.2" + "puppeteer": "19.8.0" } } From 4b6056ec5d8b8b140009f4e725200d3ac8fb3fc3 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 29 Mar 2023 08:22:26 -0600 Subject: [PATCH 6/7] chore: update datalist spec to disallow aria attrs (#3964) --- lib/standards/html-elms.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/standards/html-elms.js b/lib/standards/html-elms.js index 8f67b9d833..7e99be92a9 100644 --- a/lib/standards/html-elms.js +++ b/lib/standards/html-elms.js @@ -182,6 +182,7 @@ const htmlElms = { datalist: { contentTypes: ['phrasing', 'flow'], allowedRoles: false, + noAriaAttrs: true, implicitAttrs: { // Note: even though the value of aria-multiselectable is based // on the attributes, we don't currently need to know the From 4b67a9f3a4496f9bd607c493b0a8138c14326958 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Wed, 29 Mar 2023 08:22:52 -0600 Subject: [PATCH 7/7] chore(audio-caption): add deprecated tag (#3963) --- doc/rule-descriptions.md | 8 ++++---- lib/rules/audio-caption.json | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 88757d9ebe..5206b0c792 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -30,7 +30,6 @@ | [aria-tooltip-name](https://dequeuniversity.com/rules/axe/4.6/aria-tooltip-name?application=RuleDescription) | Ensures every ARIA tooltip node has an accessible name | Serious | cat.aria, wcag2a, wcag412 | failure, needs review | | | [aria-valid-attr-value](https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr-value?application=RuleDescription) | Ensures all ARIA attributes have valid values | Serious, Critical | cat.aria, wcag2a, wcag412 | failure, needs review | [6a7281](https://act-rules.github.io/rules/6a7281) | | [aria-valid-attr](https://dequeuniversity.com/rules/axe/4.6/aria-valid-attr?application=RuleDescription) | Ensures attributes that begin with aria- are valid ARIA attributes | Critical | cat.aria, wcag2a, wcag412 | failure | [5f99a7](https://act-rules.github.io/rules/5f99a7) | -| [audio-caption](https://dequeuniversity.com/rules/axe/4.6/audio-caption?application=RuleDescription) | Ensures <audio> elements have captions | Critical | cat.time-and-media, wcag2a, wcag121, section508, section508.22.a | needs review | [2eb176](https://act-rules.github.io/rules/2eb176), [afb423](https://act-rules.github.io/rules/afb423) | | [blink](https://dequeuniversity.com/rules/axe/4.6/blink?application=RuleDescription) | Ensures <blink> elements are not used | Serious | cat.time-and-media, wcag2a, wcag222, section508, section508.22.j | failure | | | [button-name](https://dequeuniversity.com/rules/axe/4.6/button-name?application=RuleDescription) | Ensures buttons have discernible text | Critical | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1), [m6b1q3](https://act-rules.github.io/rules/m6b1q3) | | [bypass](https://dequeuniversity.com/rules/axe/4.6/bypass?application=RuleDescription) | Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content | Serious | cat.keyboard, wcag2a, wcag241, section508, section508.22.o | needs review | [cf77f2](https://act-rules.github.io/rules/cf77f2), [047fe0](https://act-rules.github.io/rules/047fe0), [b40fd1](https://act-rules.github.io/rules/b40fd1), [3e12e1](https://act-rules.github.io/rules/3e12e1), [ye5d6e](https://act-rules.github.io/rules/ye5d6e) | @@ -150,6 +149,7 @@ Rules we are still testing and developing. They are disabled by default in axe-c Deprecated rules are disabled by default and will be removed in the next major release. -| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | -| :----------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :------ | :------------------------------------ | :------------------------- | :-------- | -| [aria-roledescription](https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=RuleDescription) | Ensure aria-roledescription is only used on elements with an implicit or explicit role | Serious | cat.aria, wcag2a, wcag412, deprecated | failure, needs review | | +| Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | +| :----------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------- | :------- | :--------------------------------------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------- | +| [aria-roledescription](https://dequeuniversity.com/rules/axe/4.6/aria-roledescription?application=RuleDescription) | Ensure aria-roledescription is only used on elements with an implicit or explicit role | Serious | cat.aria, wcag2a, wcag412, deprecated | failure, needs review | | +| [audio-caption](https://dequeuniversity.com/rules/axe/4.6/audio-caption?application=RuleDescription) | Ensures <audio> elements have captions | Critical | cat.time-and-media, wcag2a, wcag121, section508, section508.22.a, deprecated | needs review | [2eb176](https://act-rules.github.io/rules/2eb176), [afb423](https://act-rules.github.io/rules/afb423) | diff --git a/lib/rules/audio-caption.json b/lib/rules/audio-caption.json index 026a5277a7..cbcf650dfe 100644 --- a/lib/rules/audio-caption.json +++ b/lib/rules/audio-caption.json @@ -8,7 +8,8 @@ "wcag2a", "wcag121", "section508", - "section508.22.a" + "section508.22.a", + "deprecated" ], "actIds": ["2eb176", "afb423"], "metadata": {