From ab636efa743ba2cbf1194b87aa27be5aba70989b Mon Sep 17 00:00:00 2001 From: Esteban Gehring Date: Fri, 8 Oct 2021 19:48:35 +0200 Subject: [PATCH] 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"] ] }