Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: ensure secondary requirements render properly #29

Merged
merged 2 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
"dependencies": {
"@types/debug": "^4.1.7",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^26.0.24",
"@types/jest": "^29.5.1",
"@types/js-yaml": "^4.0.2",
"@types/jsonld": "^1.5.6",
"@types/jsonld": "^1.5.8",
"@types/markdown-table": "2.0.0",
"@types/node": "^16.3.1",
"@types/request-promise": "^4.1.48",
Expand All @@ -35,7 +35,7 @@
"fastmatter": "^2.1.1",
"fs-extra": "^10.0.1",
"globby": "^11.0.4",
"jsonld": "^5.2.0",
"jsonld": "^8.1.1",
"make-dir": "^3.1.0",
"markdown-table": "2.0.0",
"moment": "^2.29.1",
Expand All @@ -57,10 +57,10 @@
"@typescript-eslint/parser": "^4.28.3",
"eslint": "^7.30.0",
"husky": "^7.0.1",
"jest": "^27.0.6",
"jest": "^29.5.0",
"lint-staged": "^11.0.1",
"prettier": "^2.3.2",
"ts-jest": "^27.0.3"
"ts-jest": "^29.1.0"
},
"jest": {
"rootDir": "./src/",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ describe("accessibility-requirements", () => {
inapplicable: "further testing needed",
};
const secondaryRequirement: AccessibilityRequirement = {
secondary: true,
...requirement,
secondary: "This rule is **less strict** than this criterion.",
};

describe("getRequirementUris", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ export function mapsAllRequirements(
const criterion = findCriterionByKey(key)?.scId;
if (!criterion) return;
allowedCriteria.push(criterion);
if (!requirement.secondary && !failedRequirements.includes(criterion)) {
if (
"secondary" in requirement === false &&
!failedRequirements.includes(criterion)
) {
missingCriteria.push(criterion);
}
}
Expand Down Expand Up @@ -45,7 +48,7 @@ export function getRequirementUris(
ruleAccessibilityRequirements
)) {
const criterion = findCriterionByKey(key);
if (criterion && !requirement.secondary) {
if (criterion && "secondary" in requirement === false) {
requirementUris.push(criterion.scId);
}
}
Expand Down
17 changes: 17 additions & 0 deletions src/rule-transform/__tests__/get-rule-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ describe("getRuleContent", () => {
failed: not satisfied
passed: further testing needed
inapplicable: further testing needed
wcag20:1.1.1: # Non-text Content (A)
secondary: |
This rule is **less strict** than this criterion.
using-aria:fourth:
title: Fourth rule of ARIA use
secondary: This rule is **more strict** than this requirement.
input_aspects:
- DOM Tree
acknowledgments:
Expand Down Expand Up @@ -109,6 +115,17 @@ describe("getRuleContent", () => {
</details></li>
</ul>

### Secondary Requirements

This rule is related to the following accessibility requirements, but was
not designed to test this requirements directly. These
[secondary requirements](https://w3c.github.io/wcag-act/act-rules-format.html#secondary-requirements)
can either be stricter than the rule requires, or may be satisfied in ways
not tested by the rule:

- [1.1.1 Non-text Content (Level A)](https://www.w3.org/TR/WCAG21/#non-text-content): This rule is **less strict** than this criterion.
- [Fourth rule of ARIA use](https://www.w3.org/TR/using-aria/#fourth): This rule is **more strict** than this requirement.

## Input Aspects

The following aspects are required in using this rule.
Expand Down
252 changes: 166 additions & 86 deletions src/rule-transform/rule-content/__tests__/get-requirements-map.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { RuleFrontMatter, AccessibilityRequirement } from "../../../types";
import { getRequirementsMap, headingText } from "../get-requirements-map";
import {
getRequirementsMap,
headingText,
secondaryReqText,
} from "../get-requirements-map";

describe("getRequirementsMap", () => {
const defaultMatter: RuleFrontMatter = {
Expand All @@ -25,112 +29,188 @@ describe("getRequirementsMap", () => {
expect(reqMap).toContain("not required for conformance");
});

it("lists each requirement", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": scRequirement,
"wcag20:4.1.2": scRequirement,
describe("conformance requirements", () => {
it("lists each requirement", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": scRequirement,
"wcag20:4.1.2": scRequirement,
},
},
},
});
expect(reqMap).toContain("1.1.1 Non-text Content (Level A)");
expect(reqMap).toContain("4.1.2 Name, Role, Value (Level A)");
});
expect(reqMap).toContain("1.1.1 Non-text Content (Level A)");
expect(reqMap).toContain("4.1.2 Name, Role, Value (Level A)");
});

it("includes an outcome mapping", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": scRequirement,
it("includes an outcome mapping", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": scRequirement,
},
},
},
});
expect(reqMap).toContain(
"Any <code>failed</code> outcomes: success criterion is not satisfied"
);
expect(reqMap).toContain(
"All <code>passed</code> outcomes: success criterion is satisfied"
);
expect(reqMap).toContain(
"An <code>inapplicable</code> outcome: success criterion needs further testing"
);
});
expect(reqMap).toContain(
"Any <code>failed</code> outcomes: success criterion is not satisfied"
);
expect(reqMap).toContain(
"All <code>passed</code> outcomes: success criterion is satisfied"
);
expect(reqMap).toContain(
"An <code>inapplicable</code> outcome: success criterion needs further testing"
);
});

it("can map to WCAG techniques", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag-technique:G170": {
forConformance: false,
...scRequirement,
it("can map to WCAG techniques", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag-technique:G170": {
forConformance: false,
...scRequirement,
},
},
},
},
});
expect(reqMap).toContain(
"Providing a control near the beginning of the Web page"
);
expect(reqMap).toContain("Not required for conformance");
expect(reqMap).toContain("technique is not satisfied");
});
expect(reqMap).toContain(
"Providing a control near the beginning of the Web page"
);
expect(reqMap).toContain("Not required for conformance");
expect(reqMap).toContain("technique is not satisfied");
});

it("can map to WCAG non-interference requirements", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag-text:cc5": {
title: "WCAG Non-Interference",
forConformance: true,
...scRequirement,
it("can map to WCAG non-interference requirements", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag-text:cc5": {
title: "WCAG Non-Interference",
forConformance: true,
...scRequirement,
},
},
},
},
});
expect(reqMap).toContain("WCAG Non-Interference");
expect(reqMap).toContain("Required for conformance");
expect(reqMap).toContain(
"WCAG 2 conformance requirement is not satisfied"
);
});
expect(reqMap).toContain("WCAG Non-Interference");
expect(reqMap).toContain("Required for conformance");
expect(reqMap).toContain("WCAG 2 conformance requirement is not satisfied");
});

it("can map to WAI-ARIA", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"aria11:state_property_processing": {
title: "ARIA 1.1, 7.6 State and Property Attribute Processing",
forConformance: true,
...scRequirement,
it("can map to WAI-ARIA", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"aria11:state_property_processing": {
title: "ARIA 1.1, 7.6 State and Property Attribute Processing",
forConformance: true,
...scRequirement,
},
},
},
},
});
expect(reqMap).toContain(
"ARIA 1.1, 7.6 State and Property Attribute Processing"
);
expect(reqMap).toContain("Required for conformance");
expect(reqMap).toContain("WAI-ARIA requirement is not satisfied");
});

it('can map to "using ARIA"', () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"using-aria:fourth:1.1.1": {
forConformance: false,
title: "Fourth rule of ARIA use",
...scRequirement,
},
},
},
});
expect(reqMap).toContain("Fourth rule of ARIA use");
expect(reqMap).toContain("Not required for conformance");
expect(reqMap).toContain("WAI-ARIA rule is not satisfied");
});
expect(reqMap).toContain(
"ARIA 1.1, 7.6 State and Property Attribute Processing"
);
expect(reqMap).toContain("Required for conformance");
expect(reqMap).toContain("WAI-ARIA requirement is not satisfied");
});

it('can map to "using ARIA"', () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"using-aria:fourth:1.1.1": {
forConformance: false,
title: "Fourth rule of ARIA use",
...scRequirement,
describe("secondary requirements", () => {
it("includes the secondary requirements heading", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": { secondary: "foo" },
"wcag20:4.1.2": scRequirement,
},
},
});
expect(reqMap).toContain("Secondary Requirements");
});

it("includes the secondary requirements text", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": { secondary: "foo" },
},
},
});
expect(reqMap).toContain(secondaryReqText);
});

it("does not include secondary requirements if there are none", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:4.1.2": scRequirement,
},
},
});
expect(reqMap).not.toContain("Secondary Requirements");
});

it("lists each secondary requirement", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": { secondary: "foo" },
"wcag20:4.1.2": { secondary: "bar" },
},
},
});
expect(reqMap).toContain("foo");
expect(reqMap).toContain("1.1.1 Non-text Content (Level A)");
expect(reqMap).toContain("bar");
expect(reqMap).toContain("4.1.2 Name, Role, Value (Level A)");
});

it("splits secondary requirements and conformance requirements", () => {
const reqMap = getRequirementsMap({
frontmatter: {
...defaultMatter,
accessibility_requirements: {
"wcag20:1.1.1": { secondary: "foo" },
"wcag20:4.1.2": scRequirement,
},
},
},
});
const [conformance, secondary] = reqMap.split("Secondary Requirements");
expect(conformance).not.toContain("1.1.1 Non-text Content (Level A)");
expect(conformance).toContain("4.1.2 Name, Role, Value (Level A)");
expect(secondary).toContain("1.1.1 Non-text Content (Level A)");
expect(secondary).not.toContain("4.1.2 Name, Role, Value (Level A)");
});
expect(reqMap).toContain("Fourth rule of ARIA use");
expect(reqMap).toContain("Not required for conformance");
expect(reqMap).toContain("WAI-ARIA rule is not satisfied");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function getSCsTested(
accRequirements.forEach(([requirementId, req]) => {
const [requirementDoc, scNumber] = requirementId.split(":");
const criterion = criteria[scNumber];
if (!requirementDoc.includes("wcag2") || !criterion || req.secondary) {
if (!requirementDoc.includes("wcag2") || !criterion || "secondary" in req) {
return;
}

Expand Down
Loading