From 5ec7894394f8348761f5fe48ad0d09b31a27d2b2 Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Wed, 8 Jan 2020 13:06:34 -0700 Subject: [PATCH] feat(landmark-no-duplicate-*): add rule landmark-no-duplicate-main, don't use html as element source for all duplicate rules (#1949) * fix(landmark-no-duplicate-*): dont use html as element source * revert playground * update integration tests * separate landmark-on-main * update * update rule-desc --- doc/rule-descriptions.md | 3 +- .../keyboard/page-no-duplicate-after.js | 2 + .../keyboard/page-no-duplicate-banner.json | 1 + .../page-no-duplicate-contentinfo.json | 1 + .../keyboard/page-no-duplicate-main.json | 1 + lib/checks/keyboard/page-no-duplicate.js | 16 +++++- lib/rules/landmark-no-duplicate-banner.json | 2 +- .../landmark-no-duplicate-contentinfo.json | 2 +- lib/rules/landmark-no-duplicate-main.json | 12 ++++ lib/rules/landmark-one-main.json | 4 +- test/checks/keyboard/page-no-duplicate.js | 24 ++++---- .../frames/level1-fail.html | 4 +- .../frames/level1.html | 4 +- .../frames/level2.html | 4 +- .../landmark-no-duplicate-banner-fail.html | 4 +- .../landmark-no-duplicate-banner-pass.js | 10 +--- .../frames/level1-fail.html | 4 +- .../frames/level1.html | 4 +- .../frames/level2.html | 4 +- ...andmark-no-duplicate-contentinfo-fail.html | 4 +- ...andmark-no-duplicate-contentinfo-pass.html | 2 +- .../landmark-no-duplicate-contentinfo-pass.js | 10 +--- .../frames/level1-fail.html | 16 ++++++ .../frames/level1.html | 12 ++++ .../frames/level2.html | 15 +++++ .../landmark-no-duplicate-main-fail.html | 34 ++++++++++++ .../landmark-no-duplicate-main-fail.js | 55 +++++++++++++++++++ .../landmark-no-duplicate-main-pass.html | 29 ++++++++++ .../landmark-no-duplicate-main-pass.js | 43 +++++++++++++++ 29 files changed, 277 insertions(+), 49 deletions(-) create mode 100644 lib/checks/keyboard/page-no-duplicate-after.js create mode 100644 lib/rules/landmark-no-duplicate-main.json create mode 100644 test/integration/full/landmark-no-duplicate-main/frames/level1-fail.html create mode 100644 test/integration/full/landmark-no-duplicate-main/frames/level1.html create mode 100644 test/integration/full/landmark-no-duplicate-main/frames/level2.html create mode 100644 test/integration/full/landmark-no-duplicate-main/landmark-no-duplicate-main-fail.html create mode 100644 test/integration/full/landmark-no-duplicate-main/landmark-no-duplicate-main-fail.js create mode 100644 test/integration/full/landmark-no-duplicate-main/landmark-no-duplicate-main-pass.html create mode 100644 test/integration/full/landmark-no-duplicate-main/landmark-no-duplicate-main-pass.js diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 3a3851476f..5c534a0bbe 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -55,7 +55,8 @@ | landmark-main-is-top-level | Ensures the main landmark is at top level | Moderate | cat.semantics, best-practice | true | true | false | | landmark-no-duplicate-banner | Ensures the document has at most one banner landmark | Moderate | cat.semantics, best-practice | true | true | false | | landmark-no-duplicate-contentinfo | Ensures the document has at most one contentinfo landmark | Moderate | cat.semantics, best-practice | true | true | false | -| landmark-one-main | Ensures the document has only one main landmark and each iframe in the page has at most one main landmark | Moderate | cat.semantics, best-practice | true | true | false | +| landmark-no-duplicate-main | Ensures the document has at most one main landmark | Moderate | cat.semantics, best-practice | true | true | false | +| landmark-one-main | Ensures the document has a main landmark | Moderate | cat.semantics, best-practice | true | true | false | | landmark-unique | Landmarks must have a unique role or role/label/title (i.e. accessible name) combination | Moderate | cat.semantics, best-practice | true | true | false | | layout-table | Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute | Serious | cat.semantics, wcag2a, wcag131, deprecated | false | true | false | | link-in-text-block | Links can be distinguished without relying on color | Serious | cat.color, experimental, wcag2a, wcag141 | true | true | true | diff --git a/lib/checks/keyboard/page-no-duplicate-after.js b/lib/checks/keyboard/page-no-duplicate-after.js new file mode 100644 index 0000000000..38d66b2f12 --- /dev/null +++ b/lib/checks/keyboard/page-no-duplicate-after.js @@ -0,0 +1,2 @@ +// ignore results +return results.filter(checkResult => checkResult.data !== 'ignored'); diff --git a/lib/checks/keyboard/page-no-duplicate-banner.json b/lib/checks/keyboard/page-no-duplicate-banner.json index 8f706b51b9..ee947ff1d8 100644 --- a/lib/checks/keyboard/page-no-duplicate-banner.json +++ b/lib/checks/keyboard/page-no-duplicate-banner.json @@ -1,6 +1,7 @@ { "id": "page-no-duplicate-banner", "evaluate": "page-no-duplicate.js", + "after": "page-no-duplicate-after.js", "options": { "selector": "header:not([role]), [role=banner]", "nativeScopeFilter": "article, aside, main, nav, section" diff --git a/lib/checks/keyboard/page-no-duplicate-contentinfo.json b/lib/checks/keyboard/page-no-duplicate-contentinfo.json index c6e36dbd9a..a18431f03f 100644 --- a/lib/checks/keyboard/page-no-duplicate-contentinfo.json +++ b/lib/checks/keyboard/page-no-duplicate-contentinfo.json @@ -1,6 +1,7 @@ { "id": "page-no-duplicate-contentinfo", "evaluate": "page-no-duplicate.js", + "after": "page-no-duplicate-after.js", "options": { "selector": "footer:not([role]), [role=contentinfo]", "nativeScopeFilter": "article, aside, main, nav, section" diff --git a/lib/checks/keyboard/page-no-duplicate-main.json b/lib/checks/keyboard/page-no-duplicate-main.json index 1cd4fff39e..93198f4862 100644 --- a/lib/checks/keyboard/page-no-duplicate-main.json +++ b/lib/checks/keyboard/page-no-duplicate-main.json @@ -1,6 +1,7 @@ { "id": "page-no-duplicate-main", "evaluate": "page-no-duplicate.js", + "after": "page-no-duplicate-after.js", "options": { "selector": "main:not([role]), [role='main']" }, diff --git a/lib/checks/keyboard/page-no-duplicate.js b/lib/checks/keyboard/page-no-duplicate.js index e484eac06c..7932656249 100644 --- a/lib/checks/keyboard/page-no-duplicate.js +++ b/lib/checks/keyboard/page-no-duplicate.js @@ -4,7 +4,19 @@ if (!options || !options.selector || typeof options.selector !== 'string') { ); } -let elms = axe.utils.querySelectorAll(virtualNode, options.selector); +// only look at the first node and it's related nodes +const key = 'page-no-duplicate;' + options.selector; +if (axe._cache.get(key)) { + this.data('ignored'); + return; +} +axe._cache.set(key, true); + +let elms = axe.utils.querySelectorAllFilter( + axe._tree[0], + options.selector, + elm => elm !== virtualNode +); // Filter elements that, within certain contexts, don't map their role. // e.g. a