From a86c27e9f07f59bb1aa37e35329d75b69dc628b9 Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Wed, 12 Jul 2023 17:12:12 -0600 Subject: [PATCH 1/4] feat(aria-prohibited-attr): add rule aria-prohibited-attr --- doc/rule-descriptions.md | 3 +- lib/rules/aria-allowed-attr.json | 6 +- lib/rules/aria-prohibited-attr.json | 14 +++++ locales/_template.json | 8 ++- test/core/public/finish-run.js | 7 ++- .../rules/aria-allowed-attr/failures.html | 55 ++++------------- .../rules/aria-allowed-attr/failures.json | 31 +--------- .../rules/aria-allowed-attr/incomplete.html | 5 +- .../rules/aria-allowed-attr/incomplete.json | 7 +-- .../aria-prohibited-attr.html | 40 ++++++++++++ .../aria-prohibited-attr.json | 37 +++++++++++ .../virtual-rules/aria-prohibited-attr.js | 61 +++++++++++++++++++ 12 files changed, 184 insertions(+), 90 deletions(-) create mode 100644 lib/rules/aria-prohibited-attr.json create mode 100644 test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html create mode 100644 test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.json create mode 100644 test/integration/virtual-rules/aria-prohibited-attr.js diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 43844744ac..63c723f9d8 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -15,7 +15,7 @@ | Rule ID | Description | Impact | Tags | Issue Type | ACT Rules | | :------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [area-alt](https://dequeuniversity.com/rules/axe/4.7/area-alt?application=RuleDescription) | Ensures <area> elements of image maps have alternate text | Critical | cat.text-alternatives, wcag2a, wcag244, wcag412, section508, section508.22.a, TTv5, TT6.a, EN-301-549, EN-9.2.4.4, EN-9.4.1.2, ACT | failure, needs review | [c487ae](https://act-rules.github.io/rules/c487ae) | -| [aria-allowed-attr](https://dequeuniversity.com/rules/axe/4.7/aria-allowed-attr?application=RuleDescription) | Ensures ARIA attributes are allowed for an element's role | Serious, Critical | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure, needs review | [5c01ea](https://act-rules.github.io/rules/5c01ea) | +| [aria-allowed-attr](https://dequeuniversity.com/rules/axe/4.7/aria-allowed-attr?application=RuleDescription) | Ensures an element's role supports its ARIA attributes | Serious, Critical | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure, needs review | [5c01ea](https://act-rules.github.io/rules/5c01ea) | | [aria-command-name](https://dequeuniversity.com/rules/axe/4.7/aria-command-name?application=RuleDescription) | Ensures every ARIA button, link and menuitem has an accessible name | Serious | cat.aria, wcag2a, wcag412, TTv5, TT6.a, EN-301-549, EN-9.4.1.2, ACT | failure, needs review | [97a4e1](https://act-rules.github.io/rules/97a4e1) | | [aria-deprecated-role](https://dequeuniversity.com/rules/axe/4.7/aria-deprecated-role?application=RuleDescription) | Ensures elements do not use deprecated roles | Minor | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure | [674b10](https://act-rules.github.io/rules/674b10) | | [aria-hidden-body](https://dequeuniversity.com/rules/axe/4.7/aria-hidden-body?application=RuleDescription) | Ensures aria-hidden='true' is not present on the document body. | Critical | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure | | @@ -23,6 +23,7 @@ | [aria-input-field-name](https://dequeuniversity.com/rules/axe/4.7/aria-input-field-name?application=RuleDescription) | Ensures every ARIA input field has an accessible name | Moderate, Serious | cat.aria, wcag2a, wcag412, TTv5, TT5.c, EN-301-549, EN-9.4.1.2, ACT | failure, needs review | [e086e5](https://act-rules.github.io/rules/e086e5) | | [aria-meter-name](https://dequeuniversity.com/rules/axe/4.7/aria-meter-name?application=RuleDescription) | Ensures every ARIA meter node has an accessible name | Serious | cat.aria, wcag2a, wcag111, EN-301-549, EN-9.1.1.1 | failure, needs review | | | [aria-progressbar-name](https://dequeuniversity.com/rules/axe/4.7/aria-progressbar-name?application=RuleDescription) | Ensures every ARIA progressbar node has an accessible name | Serious | cat.aria, wcag2a, wcag111, EN-301-549, EN-9.1.1.1 | failure, needs review | | +| [aria-prohibited-attr](https://dequeuniversity.com/rules/axe/4.7/aria-prohibited-attr?application=RuleDescription) | Ensures ARIA attributes are not prohibited for an element's role | Serious | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure, needs review | [5c01ea](https://act-rules.github.io/rules/5c01ea) | | [aria-required-attr](https://dequeuniversity.com/rules/axe/4.7/aria-required-attr?application=RuleDescription) | Ensures elements with ARIA roles have all required ARIA attributes | Critical | cat.aria, wcag2a, wcag412, EN-301-549, EN-9.4.1.2 | failure | [4e8ab6](https://act-rules.github.io/rules/4e8ab6) | | [aria-required-children](https://dequeuniversity.com/rules/axe/4.7/aria-required-children?application=RuleDescription) | Ensures elements with an ARIA role that require child roles contain them | Critical | cat.aria, wcag2a, wcag131, EN-301-549, EN-9.1.3.1 | failure, needs review | [bc4a75](https://act-rules.github.io/rules/bc4a75), [ff89c9](https://act-rules.github.io/rules/ff89c9) | | [aria-required-parent](https://dequeuniversity.com/rules/axe/4.7/aria-required-parent?application=RuleDescription) | Ensures elements with an ARIA role that require parent roles are contained by them | Critical | cat.aria, wcag2a, wcag131, EN-301-549, EN-9.1.3.1 | failure | [ff89c9](https://act-rules.github.io/rules/ff89c9) | diff --git a/lib/rules/aria-allowed-attr.json b/lib/rules/aria-allowed-attr.json index fbf35f78d5..cf72be7256 100644 --- a/lib/rules/aria-allowed-attr.json +++ b/lib/rules/aria-allowed-attr.json @@ -4,10 +4,10 @@ "tags": ["cat.aria", "wcag2a", "wcag412", "EN-301-549", "EN-9.4.1.2"], "actIds": ["5c01ea"], "metadata": { - "description": "Ensures ARIA attributes are allowed for an element's role", - "help": "Elements must only use allowed ARIA attributes" + "description": "Ensures an element's role supports its ARIA attributes", + "help": "Elements must only use supported ARIA attributes" }, "all": ["aria-allowed-attr", "aria-conditional-attr"], "any": [], - "none": ["aria-unsupported-attr", "aria-prohibited-attr"] + "none": ["aria-unsupported-attr"] } diff --git a/lib/rules/aria-prohibited-attr.json b/lib/rules/aria-prohibited-attr.json new file mode 100644 index 0000000000..aa711f91e8 --- /dev/null +++ b/lib/rules/aria-prohibited-attr.json @@ -0,0 +1,14 @@ +{ + "id": "aria-prohibited-attr", + "matches": "aria-allowed-attr-matches", + "tags": ["cat.aria", "wcag2a", "wcag412", "EN-301-549", "EN-9.4.1.2"], + "actIds": ["5c01ea"], + "impact": "serious", + "metadata": { + "description": "Ensures ARIA attributes are not prohibited for an element's role", + "help": "Elements must only use permitted ARIA attributes" + }, + "all": [], + "any": [], + "none": ["aria-prohibited-attr"] +} diff --git a/locales/_template.json b/locales/_template.json index 07e040308b..82f3c825c4 100644 --- a/locales/_template.json +++ b/locales/_template.json @@ -10,8 +10,8 @@ "help": "Active elements must have alternate text" }, "aria-allowed-attr": { - "description": "Ensures ARIA attributes are allowed for an element's role", - "help": "Elements must only use allowed ARIA attributes" + "description": "Ensures an element's role supports its ARIA attributes", + "help": "Elements must only use supported ARIA attributes" }, "aria-allowed-role": { "description": "Ensures role attribute has an appropriate value for the element", @@ -49,6 +49,10 @@ "description": "Ensures every ARIA progressbar node has an accessible name", "help": "ARIA progressbar nodes must have an accessible name" }, + "aria-prohibited-attr": { + "description": "Ensures ARIA attributes are not prohibited for an element's role", + "help": "Elements must only use permitted ARIA attributes" + }, "aria-required-attr": { "description": "Ensures elements with ARIA roles have all required ARIA attributes", "help": "Required ARIA attributes must be provided" diff --git a/test/core/public/finish-run.js b/test/core/public/finish-run.js index 8abe92f935..1e329e279c 100644 --- a/test/core/public/finish-run.js +++ b/test/core/public/finish-run.js @@ -104,7 +104,10 @@ describe('axe.finishRun', function () { it('can report violations results', function (done) { fixture.innerHTML = '
'; axe - .runPartial({ include: [['#fixture']] }, { runOnly: 'aria-allowed-attr' }) + .runPartial( + { include: [['#fixture']] }, + { runOnly: 'aria-prohibited-attr' } + ) .then(function (result) { return axe.finishRun([result]); }) @@ -186,7 +189,7 @@ describe('axe.finishRun', function () { allResults.push(results); return axe.runPartial( { include: [['#fail']] }, - { runOnly: 'aria-allowed-attr' } + { runOnly: 'aria-prohibited-attr' } ); }) .then(function (results) { diff --git a/test/integration/rules/aria-allowed-attr/failures.html b/test/integration/rules/aria-allowed-attr/failures.html index cef9d931ff..f35a55a047 100644 --- a/test/integration/rules/aria-allowed-attr/failures.html +++ b/test/integration/rules/aria-allowed-attr/failures.html @@ -2,57 +2,28 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - - - - + -
-
-
-
- -
-
-
+ +
+
+
- -
-
-
+ +
+
+
- - - + + + diff --git a/test/integration/rules/aria-allowed-attr/failures.json b/test/integration/rules/aria-allowed-attr/failures.json index 895d49aac7..aa2d4b1f25 100644 --- a/test/integration/rules/aria-allowed-attr/failures.json +++ b/test/integration/rules/aria-allowed-attr/failures.json @@ -17,35 +17,6 @@ ["#fail13"], ["#fail14"], ["#fail15"], - ["#fail16"], - ["#fail17"], - ["#fail18"], - ["#fail19"], - ["#fail20"], - ["#fail21"], - ["#fail22"], - ["#fail23"], - ["#fail24"], - ["#fail25"], - ["#fail26"], - ["#fail27"], - ["#fail28"], - ["#fail29"], - ["#fail30"], - ["#fail31"], - ["#fail32"], - ["#fail33"], - ["#fail34"], - ["#fail35"], - ["#fail36"], - ["#fail37"], - ["#fail38"], - ["#fail39"], - ["#fail40"], - ["#fail41"], - ["#fail42"], - ["#fail43"], - ["#fail44"], - ["#fail45"] + ["#fail16"] ] } diff --git a/test/integration/rules/aria-allowed-attr/incomplete.html b/test/integration/rules/aria-allowed-attr/incomplete.html index e187dba1c6..b98bc3380b 100644 --- a/test/integration/rules/aria-allowed-attr/incomplete.html +++ b/test/integration/rules/aria-allowed-attr/incomplete.html @@ -1,4 +1 @@ -
Foo
-
Foo
-Foo -
Foo
+Foo diff --git a/test/integration/rules/aria-allowed-attr/incomplete.json b/test/integration/rules/aria-allowed-attr/incomplete.json index fa37187123..5a2b2b4fc3 100644 --- a/test/integration/rules/aria-allowed-attr/incomplete.json +++ b/test/integration/rules/aria-allowed-attr/incomplete.json @@ -1,10 +1,5 @@ { "description": "aria-allowed-attr incomplete tests", "rule": "aria-allowed-attr", - "incomplete": [ - ["#incomplete0"], - ["#incomplete1"], - ["#incomplete2"], - ["#incomplete3"] - ] + "incomplete": [["#incomplete1"]] } diff --git a/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html new file mode 100644 index 0000000000..3705726d99 --- /dev/null +++ b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html @@ -0,0 +1,40 @@ + +
Foo
+
Foo
+ +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + +
+
+
+
+ +
Foo
+
Foo
+
Foo
diff --git a/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.json b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.json new file mode 100644 index 0000000000..f6f9e7717b --- /dev/null +++ b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.json @@ -0,0 +1,37 @@ +{ + "description": "aria-prohibited-attr tests", + "rule": "aria-prohibited-attr", + "passes": [["#pass1"], ["#pass2"], ["#pass3"], ["#pass4"], ["#pass5"]], + "incomplete": [["#incomplete1"], ["#incomplete2"], ["#incomplete3"]], + "violations": [ + ["#fail1"], + ["#fail2"], + ["#fail3"], + ["#fail4"], + ["#fail5"], + ["#fail6"], + ["#fail7"], + ["#fail8"], + ["#fail9"], + ["#fail10"], + ["#fail11"], + ["#fail12"], + ["#fail13"], + ["#fail14"], + ["#fail15"], + ["#fail16"], + ["#fail17"], + ["#fail18"], + ["#fail19"], + ["#fail20"], + ["#fail21"], + ["#fail22"], + ["#fail23"], + ["#fail24"], + ["#fail25"], + ["#fail26"], + ["#fail27"], + ["#fail28"], + ["#fail29"] + ] +} diff --git a/test/integration/virtual-rules/aria-prohibited-attr.js b/test/integration/virtual-rules/aria-prohibited-attr.js new file mode 100644 index 0000000000..ccacf57b33 --- /dev/null +++ b/test/integration/virtual-rules/aria-prohibited-attr.js @@ -0,0 +1,61 @@ +describe('aria-prohibited-attr virtual-rule', () => { + it('should pass for required attributes', () => { + const results = axe.runVirtualRule('aria-prohibited-attr', { + nodeName: 'div', + attributes: { + role: 'checkbox', + 'aria-checked': true + } + }); + + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); + assert.lengthOf(results.incomplete, 0); + }); + + it('should pass for allowed attributes', () => { + const results = axe.runVirtualRule('aria-prohibited-attr', { + nodeName: 'div', + attributes: { + role: 'radio', + 'aria-required': true, + 'aria-checked': true + } + }); + + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); + assert.lengthOf(results.incomplete, 0); + }); + + it('should pass for invalid attributes', () => { + const results = axe.runVirtualRule('aria-prohibited-attr', { + nodeName: 'div', + attributes: { + role: 'dialog', + 'aria-cats': true + } + }); + + assert.lengthOf(results.passes, 1); + assert.lengthOf(results.violations, 0); + assert.lengthOf(results.incomplete, 0); + }); + + it('should fail for prohibited attributes', () => { + const vNode = new axe.SerialVirtualNode({ + nodeName: 'div', + attributes: { + role: 'code', + 'aria-label': 'foo' + } + }); + vNode.children = []; + + const results = axe.runVirtualRule('aria-prohibited-attr', vNode); + + assert.lengthOf(results.passes, 0); + assert.lengthOf(results.violations, 1); + assert.lengthOf(results.incomplete, 0); + }); +}); From 27f6062d32b8c4647ace484b845bd72a0568b21b Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Wed, 12 Jul 2023 17:27:06 -0600 Subject: [PATCH 2/4] fix act --- test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js b/test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js index 6a2e047d12..10b74e3fa7 100644 --- a/test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js +++ b/test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js @@ -1,5 +1,5 @@ require('./act-runner.js')({ id: '5c01ea', title: 'ARIA state or property is permitted', - axeRules: ['aria-allowed-attr'] + axeRules: ['aria-allowed-attr', 'aria-prohibited-attr'] }); From 4705e2ad78b4bf50d07a03c3a0666e9a0b88d7cb Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Thu, 13 Jul 2023 07:54:03 -0600 Subject: [PATCH 3/4] fixes --- test/integration/rules/aria-allowed-attr/passes.html | 5 +++++ test/integration/rules/aria-allowed-attr/passes.json | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/test/integration/rules/aria-allowed-attr/passes.html b/test/integration/rules/aria-allowed-attr/passes.html index 5449480b8a..76780a4662 100644 --- a/test/integration/rules/aria-allowed-attr/passes.html +++ b/test/integration/rules/aria-allowed-attr/passes.html @@ -2153,3 +2153,8 @@ + +
+
+
+
diff --git a/test/integration/rules/aria-allowed-attr/passes.json b/test/integration/rules/aria-allowed-attr/passes.json index 84f487f8b1..f5a7ce3113 100644 --- a/test/integration/rules/aria-allowed-attr/passes.json +++ b/test/integration/rules/aria-allowed-attr/passes.json @@ -96,6 +96,10 @@ ["#treegrid"], ["#pass91"], ["#pass92"], - ["#pass93"] + ["#pass93"], + ["#pass94"], + ["#pass95"], + ["#pass96"], + ["#pass97"] ] } From 236d27abd591b5e7a4eb0dba948cf1a79462d9c6 Mon Sep 17 00:00:00 2001 From: Steven Lambert <2433219+straker@users.noreply.github.com> Date: Fri, 14 Jul 2023 07:57:00 -0600 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Wilco Fiers --- test/integration/rules/aria-allowed-attr/passes.html | 1 + .../rules/aria-prohibited-attr/aria-prohibited-attr.html | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/rules/aria-allowed-attr/passes.html b/test/integration/rules/aria-allowed-attr/passes.html index 76780a4662..88b342e814 100644 --- a/test/integration/rules/aria-allowed-attr/passes.html +++ b/test/integration/rules/aria-allowed-attr/passes.html @@ -2154,6 +2154,7 @@ +
diff --git a/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html index 3705726d99..ec354260a3 100644 --- a/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html +++ b/test/integration/rules/aria-prohibited-attr/aria-prohibited-attr.html @@ -24,7 +24,8 @@
- +