Commit eb01542a authored by David Sveningsson's avatar David Sveningsson

fix(rules): handle `aria-label` on links for WCAG H30

refs #67
parent 6d5d9630
......@@ -3,7 +3,8 @@ import HtmlValidate from "../../../../src/htmlvalidate";
const markup: { [key: string]: string } = {};
markup["incorrect"] = `<a><img src="cat.gif"></a>`;
markup["correct"] = `<a>lorem ipsum</a>
<a><img src="cat.gif" alt="cat page"></a>`;
<a><img src="cat.gif" alt="cat page"></a>
<a aria-label="lorem ipsum"></a>`;
describe("docs/rules/wcag/h30.md", () => {
it("inline validation: incorrect", () => {
......
......@@ -16,6 +16,12 @@ links and determine whenever to follow the link or not. Assistive technology may
also present a list of links in which case the description is the only thing the
user will be presented with.
The rule recognizes the following patterns:
- Text (non-whitespace) inside the link
- Images with `alt` text (non-whitespace)
- `aria-label` either on the link or at least one descendant.
[1]: https://www.w3.org/WAI/WCAG21/Techniques/html/H30
## Rule details
......@@ -31,4 +37,5 @@ Examples of **correct** code for this rule:
<validate name="correct" rules="wcag/h30">
<a>lorem ipsum</a>
<a><img src="cat.gif" alt="cat page"></a>
<a aria-label="lorem ipsum"></a>
</validate>
export { classifyNodeText } from "./text";
export { hasAltText } from "./has-alt-text";
export { hasAriaLabel } from "./has-aria-label";
......@@ -22,6 +22,20 @@ describe("wcag/h30", () => {
expect(report).toBeValid();
});
it("should not report when link has aria-label", () => {
const report = htmlvalidate.validateString(
'<a aria-label="lorem ipsum"></a>'
);
expect(report).toBeValid();
});
it("should not report when descendant has aria-label", () => {
const report = htmlvalidate.validateString(
'<a><span aria-label="lorem ipsum"></span></a>'
);
expect(report).toBeValid();
});
it("should report error when link is missing text", () => {
const report = htmlvalidate.validateString("<a></a>");
expect(report).toBeInvalid();
......
import { DOMReadyEvent } from "../../event";
import { Rule, RuleDocumentation, ruleDocumentationUrl } from "../../rule";
import { hasAltText } from "../helper";
import { hasAltText, hasAriaLabel } from "../helper";
import { classifyNodeText, TextClassification } from "../helper/text";
class H30 extends Rule {
......@@ -33,6 +33,12 @@ class H30 extends Rule {
continue;
}
/* check if aria-label is present on either the <a> element or a descendant */
const labels = link.querySelectorAll("[aria-label]");
if (hasAriaLabel(link) || labels.some(cur => hasAriaLabel(cur))) {
continue;
}
this.report(
link,
"Anchor link must have a text describing its purpose"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment