From 59e1844120abc74d5fea15dda86159862a9708c9 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Wed, 23 Aug 2017 12:48:17 -0500 Subject: [PATCH 01/15] feat(landmark-one-main): add rule ensuring one main landmark in document --- lib/checks/keyboard/has-at-least-one-main.js | 3 + .../keyboard/has-at-least-one-main.json | 12 +++ .../keyboard/has-no-more-than-one-main.js | 2 + .../keyboard/has-no-more-than-one-main.json | 11 +++ lib/rules/landmark-one-main.json | 17 ++++ test/checks/keyboard/has-at-least-one-main.js | 88 +++++++++++++++++++ .../keyboard/has-no-more-than-one-main.js | 51 +++++++++++ .../frames/level1-fail.html | 10 +++ .../frames/level1.html | 12 +++ .../frames/level2-a.html | 12 +++ .../frames/level2.html | 10 +++ .../landmark-at-least-one-main-fail.html | 24 +++++ .../landmark-at-least-one-main-fail.js | 35 ++++++++ .../landmark-at-least-one-main-pass.html | 25 ++++++ .../landmark-at-least-one-main-pass.js | 51 +++++++++++ 15 files changed, 363 insertions(+) create mode 100644 lib/checks/keyboard/has-at-least-one-main.js create mode 100644 lib/checks/keyboard/has-at-least-one-main.json create mode 100644 lib/checks/keyboard/has-no-more-than-one-main.js create mode 100644 lib/checks/keyboard/has-no-more-than-one-main.json create mode 100644 lib/rules/landmark-one-main.json create mode 100644 test/checks/keyboard/has-at-least-one-main.js create mode 100644 test/checks/keyboard/has-no-more-than-one-main.js create mode 100644 test/integration/full/landmark-at-least-one-main/frames/level1-fail.html create mode 100644 test/integration/full/landmark-at-least-one-main/frames/level1.html create mode 100644 test/integration/full/landmark-at-least-one-main/frames/level2-a.html create mode 100644 test/integration/full/landmark-at-least-one-main/frames/level2.html create mode 100644 test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html create mode 100644 test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js create mode 100644 test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html create mode 100644 test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js new file mode 100644 index 0000000000..de1f128ef4 --- /dev/null +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -0,0 +1,3 @@ +var main = document.querySelector('main,[role=main]'); +this.data(!!main); +return !!main; \ No newline at end of file diff --git a/lib/checks/keyboard/has-at-least-one-main.json b/lib/checks/keyboard/has-at-least-one-main.json new file mode 100644 index 0000000000..6cd6a4cd62 --- /dev/null +++ b/lib/checks/keyboard/has-at-least-one-main.json @@ -0,0 +1,12 @@ +{ + "id": "has-at-least-one-main", + "evaluate": "has-at-least-one-main.js", + "after": "has-at-least-one-main-after.js", + "metadata": { + "impact": "moderate", + "messages": { + "pass": "Document has at least one main landmark", + "fail": "Document has no main landmarks" + } + } +} \ No newline at end of file diff --git a/lib/checks/keyboard/has-no-more-than-one-main.js b/lib/checks/keyboard/has-no-more-than-one-main.js new file mode 100644 index 0000000000..b694e42b27 --- /dev/null +++ b/lib/checks/keyboard/has-no-more-than-one-main.js @@ -0,0 +1,2 @@ +var mains = document.querySelectorAll('main,[role=main]'); +return mains.length<=1; \ No newline at end of file diff --git a/lib/checks/keyboard/has-no-more-than-one-main.json b/lib/checks/keyboard/has-no-more-than-one-main.json new file mode 100644 index 0000000000..c4d9fb3707 --- /dev/null +++ b/lib/checks/keyboard/has-no-more-than-one-main.json @@ -0,0 +1,11 @@ +{ + "id": "has-no-more-than-one-main", + "evaluate": "has-no-more-than-one-main.js", + "metadata": { + "impact": "moderate", + "messages": { + "pass": "Document has no more than one main landmark", + "fail": "Document has more than one main landmark" + } + } +} \ No newline at end of file diff --git a/lib/rules/landmark-one-main.json b/lib/rules/landmark-one-main.json new file mode 100644 index 0000000000..4cec9b9334 --- /dev/null +++ b/lib/rules/landmark-one-main.json @@ -0,0 +1,17 @@ +{ + "id": "landmark-at-least-one-main", + "selector": "html", + "tags": [ + "best-practice" + ], + "metadata": { + "description": "Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one.", + "help": "Page must contain one main landmark." + }, + "all": [], + "any": [ + "has-at-least-one-main", + "has-no-more-than-one-main" + ], + "none": [] +} \ No newline at end of file diff --git a/test/checks/keyboard/has-at-least-one-main.js b/test/checks/keyboard/has-at-least-one-main.js new file mode 100644 index 0000000000..6e1f877a74 --- /dev/null +++ b/test/checks/keyboard/has-at-least-one-main.js @@ -0,0 +1,88 @@ +describe('has-at-least-one-main', function () { + 'use strict'; + + var fixture = document.getElementById('fixture'); + var checkContext = { + _data: null, + data: function (d) { + this._data = d; + }, + }; + + afterEach(function () { + fixture.innerHTML = ''; + checkContext._data = null; + }); + + + it('should return false if main does not exist', function () { + var node = document.querySelector('html'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isFalse(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + }); + + it('should return false if no div has role property', function() { + var node = document.querySelector('html'); + var notMain = document.createElement('div'); + node.appendChild(notMain); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isFalse(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + node.removeChild(notMain); + }); + + it('should return false if div has empty role', function() { + var node = document.querySelector('html'); + var notMain = document.createElement('div'); + notMain.setAttribute('role',''); + node.appendChild(notMain); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isFalse(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + node.removeChild(notMain); + }); + + it('should return false if div has role not equal to main', function() { + var node = document.querySelector('html'); + var notMain = document.createElement('div'); + notMain.setAttribute('role','bananas'); + node.appendChild(notMain); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isFalse(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + node.removeChild(notMain); + }); + + it('should return true if main landmark exists', function(){ + var node = document.querySelector('html'); + var mainLandmark = document.createElement('main'); + node.appendChild(mainLandmark); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isTrue(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + node.removeChild(mainLandmark); + }); + + it('should return true if one div has role equal to main', function() { + var node = document.querySelector('html'); + var mainLandmark = document.createElement('div'); + mainLandmark.setAttribute('role','main'); + node.appendChild(mainLandmark); + var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + assert.isTrue(mainIsFound); + assert.equal(checkContext._data, mainIsFound); + node.removeChild(mainLandmark); + }); + + it('should return true if any document has a main landmark', function() { + var results = [{data: false, result: false}, {data: true, result: true}]; + assert.isTrue(checks['has-at-least-one-main'].after(results)[0].result && checks['has-at-least-one-main'].after(results)[1].result); + }); + + it('should return false if no document has a main landmark', function() { + var results = [{data: false, result: false}, {data: false, result: false}]; + assert.isFalse(checks['has-at-least-one-main'].after(results)[0].result && checks['has-at-least-one-main'].after(results)[1].result); + }); + +}); \ No newline at end of file diff --git a/test/checks/keyboard/has-no-more-than-one-main.js b/test/checks/keyboard/has-no-more-than-one-main.js new file mode 100644 index 0000000000..935c425c12 --- /dev/null +++ b/test/checks/keyboard/has-no-more-than-one-main.js @@ -0,0 +1,51 @@ +describe('has-no-more-than-one-main', function () { + 'use strict'; + + var fixture = document.getElementById('fixture'); + + afterEach(function () { + fixture.innerHTML = ''; + }); + + it('should return false if there is more than one element with role main', function () { + var mainDiv = document.createElement('div'); + mainDiv.setAttribute('role','main'); + var anotherMain = document.createElement('div'); + anotherMain.setAttribute('role','main'); + var node = document.querySelector('html'); + node.appendChild(mainDiv); + node.appendChild(anotherMain); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); + node.removeChild(mainDiv); + node.removeChild(anotherMain); + }); + + it('should return false if there is more than one main element', function () { + var mainLandmark = document.createElement('main'); + var anotherMain = document.createElement('main'); + var node = document.querySelector('html'); + node.appendChild(mainLandmark); + node.appendChild(anotherMain); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); + node.removeChild(mainLandmark); + node.removeChild(anotherMain); + }); + + it('should return true if there is only one element with role main', function(){ + var mainDiv = document.createElement('div'); + mainDiv.setAttribute('role','main'); + var node = document.querySelector('html'); + node.appendChild(mainDiv); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); + node.removeChild(mainDiv); + }); + + it('should return true if there is only one main element', function(){ + var mainLandmark = document.createElement('main'); + var node = document.querySelector('html'); + node.appendChild(mainLandmark); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); + node.removeChild(mainLandmark); + }); + +}); \ No newline at end of file diff --git a/test/integration/full/landmark-at-least-one-main/frames/level1-fail.html b/test/integration/full/landmark-at-least-one-main/frames/level1-fail.html new file mode 100644 index 0000000000..e398796507 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/frames/level1-fail.html @@ -0,0 +1,10 @@ + + + + + + + +

No main content here either

+ + diff --git a/test/integration/full/landmark-at-least-one-main/frames/level1.html b/test/integration/full/landmark-at-least-one-main/frames/level1.html new file mode 100644 index 0000000000..3856ff3b03 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/frames/level1.html @@ -0,0 +1,12 @@ + + + + + + + +

No main content here either

+ + + + diff --git a/test/integration/full/landmark-at-least-one-main/frames/level2-a.html b/test/integration/full/landmark-at-least-one-main/frames/level2-a.html new file mode 100644 index 0000000000..7c3745a65a --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/frames/level2-a.html @@ -0,0 +1,12 @@ + + + + + + + +
+

Main landmark created with main tag

+
+ + diff --git a/test/integration/full/landmark-at-least-one-main/frames/level2.html b/test/integration/full/landmark-at-least-one-main/frames/level2.html new file mode 100644 index 0000000000..64d8a0c398 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/frames/level2.html @@ -0,0 +1,10 @@ + + + + + + + +

No main content in this iframe

+ + diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html new file mode 100644 index 0000000000..e97781fc75 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html @@ -0,0 +1,24 @@ + + + + + + + + + + + +

No main content here

+ +
+ + + + diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js new file mode 100644 index 0000000000..907c96a456 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js @@ -0,0 +1,35 @@ +describe('landmark-at-least-one-main test failure', function () { + 'use strict'; + var results; + + before(function (done) { + axe.run({ runOnly: { type: 'rule', values: ['landmark-at-least-one-main'] } }, function (err, r) { + assert.isNull(err); + results = r; + done(); + }); + }); + + describe('violations', function () { + it('should find 1', function () { + assert.lengthOf(results.violations[0].nodes, 1); + }); + it('should find first level iframe', function () { + assert.deepEqual(results.violations[0].nodes[0].target, ['#fail1']); + }); + }); + + describe('passes', function () { + it('should find 0', function () { + assert.lengthOf(results.passes, 0); + }); + }); + + it('should find 0 inapplicable', function () { + assert.lengthOf(results.inapplicable, 0); + }); + + it('should find 0 incomplete', function () { + assert.lengthOf(results.incomplete, 0); + }); +}); diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html new file mode 100644 index 0000000000..897b3cc820 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html @@ -0,0 +1,25 @@ + + + + landmark-at-least-one-main test pass + + + + + + + + +

No main content

+ +
+ + + + diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js new file mode 100644 index 0000000000..8e468fc035 --- /dev/null +++ b/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js @@ -0,0 +1,51 @@ +describe('landmark-at-least-one-main test pass', function () { + 'use strict'; + var results; + before(function (done) { + window.addEventListener('load', function () { + axe.run({ runOnly: { type: 'rule', values: ['landmark-at-least-one-main'] } }, function (err, r) { + assert.isNull(err); + results = r; + done(); + }); + }); + }); + + describe('violations', function () { + it('should find 0', function () { + document.innerHTML = results; + assert.lengthOf(results.violations, 0); + }); + }); + + describe('passes', function () { + it('should find 4', function () { + assert.lengthOf(results.passes[0].nodes, 4); + }); + + it('should find #pass1', function () { + assert.deepEqual(results.passes[0].nodes[0].target, ['#pass1']); + }); + + it('should find #frame1, #pass2', function () { + assert.deepEqual(results.passes[0].nodes[1].target, ['#frame1', '#pass2']); + }); + + it('should find #frame1, #frame2, #pass3', function () { + assert.deepEqual(results.passes[0].nodes[2].target, ['#frame1', '#frame2', '#pass3']); + }); + + it('should find #frame1, #frame3, #pass4', function () { + assert.deepEqual(results.passes[0].nodes[3].target, ['#frame1', '#frame3', '#pass4']); + }); + }); + + it('should find 0 inapplicable', function () { + assert.lengthOf(results.inapplicable, 0); + }); + + it('should find 0 incomplete', function () { + assert.lengthOf(results.incomplete, 0); + }); + +}); From 4737cbdbc0294131dfa725336759256ac0b5f17d Mon Sep 17 00:00:00 2001 From: ssanaul Date: Wed, 30 Aug 2017 13:30:07 -0500 Subject: [PATCH 02/15] fix: rename integration tests --- .../frames/level1-fail.html | 0 .../frames/level1.html | 0 .../frames/level2-a.html | 0 .../frames/level2.html | 0 .../landmark-one-main-fail.html} | 0 .../landmark-one-main-fail.js} | 0 .../landmark-one-main-pass.js} | 0 .../landmark-one-pass.html} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename test/integration/full/{landmark-at-least-one-main => landmark-one-main}/frames/level1-fail.html (100%) rename test/integration/full/{landmark-at-least-one-main => landmark-one-main}/frames/level1.html (100%) rename test/integration/full/{landmark-at-least-one-main => landmark-one-main}/frames/level2-a.html (100%) rename test/integration/full/{landmark-at-least-one-main => landmark-one-main}/frames/level2.html (100%) rename test/integration/full/{landmark-at-least-one-main/landmark-at-least-one-main-fail.html => landmark-one-main/landmark-one-main-fail.html} (100%) rename test/integration/full/{landmark-at-least-one-main/landmark-at-least-one-main-fail.js => landmark-one-main/landmark-one-main-fail.js} (100%) rename test/integration/full/{landmark-at-least-one-main/landmark-at-least-one-main-pass.js => landmark-one-main/landmark-one-main-pass.js} (100%) rename test/integration/full/{landmark-at-least-one-main/landmark-at-least-one-main-pass.html => landmark-one-main/landmark-one-pass.html} (100%) diff --git a/test/integration/full/landmark-at-least-one-main/frames/level1-fail.html b/test/integration/full/landmark-one-main/frames/level1-fail.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/frames/level1-fail.html rename to test/integration/full/landmark-one-main/frames/level1-fail.html diff --git a/test/integration/full/landmark-at-least-one-main/frames/level1.html b/test/integration/full/landmark-one-main/frames/level1.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/frames/level1.html rename to test/integration/full/landmark-one-main/frames/level1.html diff --git a/test/integration/full/landmark-at-least-one-main/frames/level2-a.html b/test/integration/full/landmark-one-main/frames/level2-a.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/frames/level2-a.html rename to test/integration/full/landmark-one-main/frames/level2-a.html diff --git a/test/integration/full/landmark-at-least-one-main/frames/level2.html b/test/integration/full/landmark-one-main/frames/level2.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/frames/level2.html rename to test/integration/full/landmark-one-main/frames/level2.html diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html b/test/integration/full/landmark-one-main/landmark-one-main-fail.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.html rename to test/integration/full/landmark-one-main/landmark-one-main-fail.html diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js b/test/integration/full/landmark-one-main/landmark-one-main-fail.js similarity index 100% rename from test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-fail.js rename to test/integration/full/landmark-one-main/landmark-one-main-fail.js diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js b/test/integration/full/landmark-one-main/landmark-one-main-pass.js similarity index 100% rename from test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.js rename to test/integration/full/landmark-one-main/landmark-one-main-pass.js diff --git a/test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html b/test/integration/full/landmark-one-main/landmark-one-pass.html similarity index 100% rename from test/integration/full/landmark-at-least-one-main/landmark-at-least-one-main-pass.html rename to test/integration/full/landmark-one-main/landmark-one-pass.html From ac0c51764cc0f9789527bed37fa5862d61585e24 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Wed, 30 Aug 2017 13:31:33 -0500 Subject: [PATCH 03/15] fix: move checks from 'any' to 'all' --- doc/rule-descriptions.md | 1 + lib/rules/landmark-one-main.json | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 044af174d7..6fd84d53c3 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -33,6 +33,7 @@ | input-image-alt | Ensures <input type="image"> elements have alternate text | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true | | label-title-only | Ensures that every form element is not solely labeled using the title or aria-describedby attributes | cat.forms, best-practice | false | | label | Ensures every form element has a label | cat.forms, wcag2a, wcag332, wcag131, section508, section508.22.n | true | +| landmark-at-least-one-main | Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one. | best-practice | true | | layout-table | Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute | cat.semantics, wcag2a, wcag131 | true | | link-in-text-block | Links can be distinguished without relying on color | cat.color, experimental, wcag2a, wcag141 | true | | link-name | Ensures links have discernible text | cat.name-role-value, wcag2a, wcag111, wcag412, wcag244, section508, section508.22.a | true | diff --git a/lib/rules/landmark-one-main.json b/lib/rules/landmark-one-main.json index 4cec9b9334..186bd4cd23 100644 --- a/lib/rules/landmark-one-main.json +++ b/lib/rules/landmark-one-main.json @@ -8,10 +8,10 @@ "description": "Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one.", "help": "Page must contain one main landmark." }, - "all": [], - "any": [ + "all": [ "has-at-least-one-main", "has-no-more-than-one-main" - ], + ], + "any": [], "none": [] } \ No newline at end of file From 456415c7d13c7cb5049991266d4d1c289da4301d Mon Sep 17 00:00:00 2001 From: ssanaul Date: Tue, 26 Sep 2017 11:40:02 -0500 Subject: [PATCH 04/15] fix: add missing 'after' check --- lib/checks/keyboard/has-at-least-one-main-after.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/checks/keyboard/has-at-least-one-main-after.js diff --git a/lib/checks/keyboard/has-at-least-one-main-after.js b/lib/checks/keyboard/has-at-least-one-main-after.js new file mode 100644 index 0000000000..ef72a101db --- /dev/null +++ b/lib/checks/keyboard/has-at-least-one-main-after.js @@ -0,0 +1,8 @@ +var hasMain = false; +for (var i = 0; i < results.length && !hasMain; i++) { + hasMain = results[i].data; +} +for (var i = 0; i < results.length; i++) { + results[i].result = hasMain; +} +return results; \ No newline at end of file From c0f2efb12b15e77e83cfa7ab3eff18714b1580e5 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Tue, 26 Sep 2017 12:57:36 -0500 Subject: [PATCH 05/15] fix: update to pass virtualnode in to check --- lib/checks/keyboard/has-at-least-one-main.js | 6 +- test/checks/keyboard/has-at-least-one-main.js | 58 +++++-------------- 2 files changed, 17 insertions(+), 47 deletions(-) diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js index de1f128ef4..3609926b7c 100644 --- a/lib/checks/keyboard/has-at-least-one-main.js +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -1,3 +1,3 @@ -var main = document.querySelector('main,[role=main]'); -this.data(!!main); -return !!main; \ No newline at end of file +const main = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); +this.data(!!main[0]); +return !!main[0]; \ No newline at end of file diff --git a/test/checks/keyboard/has-at-least-one-main.js b/test/checks/keyboard/has-at-least-one-main.js index 6e1f877a74..6df5b93111 100644 --- a/test/checks/keyboard/has-at-least-one-main.js +++ b/test/checks/keyboard/has-at-least-one-main.js @@ -2,77 +2,47 @@ describe('has-at-least-one-main', function () { 'use strict'; var fixture = document.getElementById('fixture'); - var checkContext = { - _data: null, - data: function (d) { - this._data = d; - }, - }; + var checkContext = new axe.testUtils.MockCheckContext(); + var checkSetup = axe.testUtils.checkSetup; afterEach(function () { fixture.innerHTML = ''; - checkContext._data = null; - }); - - - it('should return false if main does not exist', function () { - var node = document.querySelector('html'); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); - assert.isFalse(mainIsFound); - assert.equal(checkContext._data, mainIsFound); + checkContext.reset(); }); it('should return false if no div has role property', function() { - var node = document.querySelector('html'); - var notMain = document.createElement('div'); - node.appendChild(notMain); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + var params = checkSetup('
No role
'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.apply(checkContext, params); assert.isFalse(mainIsFound); - assert.equal(checkContext._data, mainIsFound); - node.removeChild(notMain); + assert.deepEqual(checkContext._data, mainIsFound); }); it('should return false if div has empty role', function() { - var node = document.querySelector('html'); - var notMain = document.createElement('div'); - notMain.setAttribute('role',''); - node.appendChild(notMain); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + var params = checkSetup('
Empty role
'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.apply(checkContext, params); assert.isFalse(mainIsFound); assert.equal(checkContext._data, mainIsFound); - node.removeChild(notMain); }); it('should return false if div has role not equal to main', function() { - var node = document.querySelector('html'); - var notMain = document.createElement('div'); - notMain.setAttribute('role','bananas'); - node.appendChild(notMain); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + var params = checkSetup('
Wrong role
'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.apply(checkContext, params); assert.isFalse(mainIsFound); assert.equal(checkContext._data, mainIsFound); - node.removeChild(notMain); }); it('should return true if main landmark exists', function(){ - var node = document.querySelector('html'); - var mainLandmark = document.createElement('main'); - node.appendChild(mainLandmark); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + var params = checkSetup('
main landmark
'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.apply(checkContext, params); assert.isTrue(mainIsFound); assert.equal(checkContext._data, mainIsFound); - node.removeChild(mainLandmark); }); it('should return true if one div has role equal to main', function() { - var node = document.querySelector('html'); - var mainLandmark = document.createElement('div'); - mainLandmark.setAttribute('role','main'); - node.appendChild(mainLandmark); - var mainIsFound = checks['has-at-least-one-main'].evaluate.call(checkContext, node); + var params = checkSetup('
Div with role main
'); + var mainIsFound = checks['has-at-least-one-main'].evaluate.apply(checkContext, params); assert.isTrue(mainIsFound); assert.equal(checkContext._data, mainIsFound); - node.removeChild(mainLandmark); }); it('should return true if any document has a main landmark', function() { From ff6417b86d86d18eca988bb01de82ce619c182ea Mon Sep 17 00:00:00 2001 From: ssanaul Date: Tue, 10 Oct 2017 15:54:21 -0500 Subject: [PATCH 06/15] fix: change incorrect rule name in integration tests --- lib/checks/keyboard/has-at-least-one-main.js | 5 +++-- lib/checks/keyboard/has-no-more-than-one-main.js | 5 +++-- .../full/landmark-one-main/landmark-one-main-fail.html | 2 +- .../full/landmark-one-main/landmark-one-main-fail.js | 6 +++--- .../full/landmark-one-main/landmark-one-main-pass.js | 6 +++--- .../full/landmark-one-main/landmark-one-pass.html | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js index 3609926b7c..c156b925ce 100644 --- a/lib/checks/keyboard/has-at-least-one-main.js +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -1,3 +1,4 @@ -const main = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); +/* const main = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); this.data(!!main[0]); -return !!main[0]; \ No newline at end of file +return !!main[0]; */ +return true; \ No newline at end of file diff --git a/lib/checks/keyboard/has-no-more-than-one-main.js b/lib/checks/keyboard/has-no-more-than-one-main.js index b694e42b27..c1f51db4df 100644 --- a/lib/checks/keyboard/has-no-more-than-one-main.js +++ b/lib/checks/keyboard/has-no-more-than-one-main.js @@ -1,2 +1,3 @@ -var mains = document.querySelectorAll('main,[role=main]'); -return mains.length<=1; \ No newline at end of file +//const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); +//return mains.length<=1; +return true; \ No newline at end of file diff --git a/test/integration/full/landmark-one-main/landmark-one-main-fail.html b/test/integration/full/landmark-one-main/landmark-one-main-fail.html index e97781fc75..3474eff7b6 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-fail.html +++ b/test/integration/full/landmark-one-main/landmark-one-main-fail.html @@ -18,7 +18,7 @@

No main content here

- + diff --git a/test/integration/full/landmark-one-main/landmark-one-main-fail.js b/test/integration/full/landmark-one-main/landmark-one-main-fail.js index 907c96a456..491b38614a 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-fail.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-fail.js @@ -1,9 +1,9 @@ -describe('landmark-at-least-one-main test failure', function () { +describe('landmark-one-main test failure', function () { 'use strict'; var results; before(function (done) { - axe.run({ runOnly: { type: 'rule', values: ['landmark-at-least-one-main'] } }, function (err, r) { + axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { assert.isNull(err); results = r; done(); @@ -12,7 +12,7 @@ describe('landmark-at-least-one-main test failure', function () { describe('violations', function () { it('should find 1', function () { - assert.lengthOf(results.violations[0].nodes, 1); + assert.lengthOf(results.violations, 1); }); it('should find first level iframe', function () { assert.deepEqual(results.violations[0].nodes[0].target, ['#fail1']); diff --git a/test/integration/full/landmark-one-main/landmark-one-main-pass.js b/test/integration/full/landmark-one-main/landmark-one-main-pass.js index 8e468fc035..a5c0da1353 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-pass.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-pass.js @@ -1,9 +1,9 @@ -describe('landmark-at-least-one-main test pass', function () { +describe('landmark-one-main test pass', function () { 'use strict'; var results; before(function (done) { window.addEventListener('load', function () { - axe.run({ runOnly: { type: 'rule', values: ['landmark-at-least-one-main'] } }, function (err, r) { + axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { assert.isNull(err); results = r; done(); @@ -20,7 +20,7 @@ describe('landmark-at-least-one-main test pass', function () { describe('passes', function () { it('should find 4', function () { - assert.lengthOf(results.passes[0].nodes, 4); + assert.lengthOf(results.passes, 4); }); it('should find #pass1', function () { diff --git a/test/integration/full/landmark-one-main/landmark-one-pass.html b/test/integration/full/landmark-one-main/landmark-one-pass.html index 897b3cc820..5bc8394ae1 100644 --- a/test/integration/full/landmark-one-main/landmark-one-pass.html +++ b/test/integration/full/landmark-one-main/landmark-one-pass.html @@ -19,7 +19,7 @@

No main content

- + From 4319175ce5efa846e55e48a536dedba51b198678 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Tue, 10 Oct 2017 15:56:55 -0500 Subject: [PATCH 07/15] fix: remove line for debugging --- lib/checks/keyboard/has-at-least-one-main.js | 7 +++---- lib/checks/keyboard/has-no-more-than-one-main.js | 5 ++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js index c156b925ce..52542995a0 100644 --- a/lib/checks/keyboard/has-at-least-one-main.js +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -1,4 +1,3 @@ -/* const main = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); -this.data(!!main[0]); -return !!main[0]; */ -return true; \ No newline at end of file +const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); +this.data(!!mains[0]); +return !!mains[0]; \ No newline at end of file diff --git a/lib/checks/keyboard/has-no-more-than-one-main.js b/lib/checks/keyboard/has-no-more-than-one-main.js index c1f51db4df..abd418d9e4 100644 --- a/lib/checks/keyboard/has-no-more-than-one-main.js +++ b/lib/checks/keyboard/has-no-more-than-one-main.js @@ -1,3 +1,2 @@ -//const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); -//return mains.length<=1; -return true; \ No newline at end of file +const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); +return mains.length<=1; \ No newline at end of file From f1d1b2f7cc80cf21ece27dc34b49adb6933705c2 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Tue, 10 Oct 2017 16:38:58 -0500 Subject: [PATCH 08/15] fix: correct faulty check tests --- lib/checks/keyboard/has-at-least-one-main.js | 4 +- .../keyboard/has-no-more-than-one-main.js | 41 ++++++------------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js index 52542995a0..06db7aa2b4 100644 --- a/lib/checks/keyboard/has-at-least-one-main.js +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -1,3 +1,3 @@ const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); -this.data(!!mains[0]); -return !!mains[0]; \ No newline at end of file +this.data(!!mains.length); +return !!mains.length; \ No newline at end of file diff --git a/test/checks/keyboard/has-no-more-than-one-main.js b/test/checks/keyboard/has-no-more-than-one-main.js index 935c425c12..bb629795bb 100644 --- a/test/checks/keyboard/has-no-more-than-one-main.js +++ b/test/checks/keyboard/has-no-more-than-one-main.js @@ -2,50 +2,33 @@ describe('has-no-more-than-one-main', function () { 'use strict'; var fixture = document.getElementById('fixture'); + var checkContext = new axe.testUtils.MockCheckContext(); + var checkSetup = axe.testUtils.checkSetup; afterEach(function () { fixture.innerHTML = ''; + checkContext.reset(); }); it('should return false if there is more than one element with role main', function () { - var mainDiv = document.createElement('div'); - mainDiv.setAttribute('role','main'); - var anotherMain = document.createElement('div'); - anotherMain.setAttribute('role','main'); - var node = document.querySelector('html'); - node.appendChild(mainDiv); - node.appendChild(anotherMain); - assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainDiv); - node.removeChild(anotherMain); + var params = checkSetup('
one
two
'); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); + }); it('should return false if there is more than one main element', function () { - var mainLandmark = document.createElement('main'); - var anotherMain = document.createElement('main'); - var node = document.querySelector('html'); - node.appendChild(mainLandmark); - node.appendChild(anotherMain); - assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainLandmark); - node.removeChild(anotherMain); + var params = checkSetup('
one
two
'); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); it('should return true if there is only one element with role main', function(){ - var mainDiv = document.createElement('div'); - mainDiv.setAttribute('role','main'); - var node = document.querySelector('html'); - node.appendChild(mainDiv); - assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainDiv); + var params = checkSetup('
just one
'); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); it('should return true if there is only one main element', function(){ - var mainLandmark = document.createElement('main'); - var node = document.querySelector('html'); - node.appendChild(mainLandmark); - assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainLandmark); + var params = checkSetup('
just one
'); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); }); \ No newline at end of file From 93e8f117fde5a11cb934338e13df2b327c4c58b9 Mon Sep 17 00:00:00 2001 From: Marcy Sutton Date: Tue, 10 Oct 2017 15:39:41 -0700 Subject: [PATCH 09/15] test: add shadowCheckSetup util --- test/testutils.js | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/test/testutils.js b/test/testutils.js index 708dc90e41..a4c80433e0 100644 --- a/test/testutils.js +++ b/test/testutils.js @@ -94,4 +94,54 @@ testUtils.checkSetup = function (content, options, target) { return [node.actualNode, options, node]; }; + +/** + * Create check arguments with Shadow DOM + * + * @param Node|String Stuff to go into the fixture (html or node) + * @param Node|String Stuff to go into the shadow boundary (html or node) + * @param Object Options argument for the check (optional, default: {}) + * @param String Target for the check, CSS selector (default: '#target') + * @return Array + */ +testUtils.shadowCheckSetup = function (content, shadowContent, options, target) { + 'use strict'; + // Normalize the params + if (typeof options !== 'object') { + target = options; + options = {}; + } + // Normalize target, allow it to be the inserted node or '#target' + target = target || (content instanceof Node ? content : '#target'); + testUtils.fixtureSetup(content); + + // wrap contents in a DIV to make it easy to attach a shadow + // ensure we attach it to the target, and not the outer fixture + var fixture = document.querySelector(target); + if (typeof shadowContent === 'string') { + fixture.innerHTML = '
'; + } else if (content instanceof Node) { + var shadowHost = document.createElement('div'); + shadowHost.setAttribute('id', 'shadowHost'); + fixture.appendChild(shadowHost); + } + + // attach a shadowRoot with the content provided + var shadowRoot = fixture.querySelector('#shadowHost').attachShadow({ mode: 'open' }); + shadowRoot.innerHTML = shadowContent; + + // query the composed tree AFTER shadowDOM has been attached + axe._tree = axe.utils.getFlattenedTree(fixture); + var node; + if (typeof target === 'string') { + node = axe.utils.querySelectorAll(axe._tree[0], target)[0]; + } else if (target instanceof Node) { + node = axe.utils.getNodeFromTree(axe._tree[0], target); + } else { + node = target; + } + return [node.actualNode, options, node]; +}; + + axe.testUtils = testUtils; \ No newline at end of file From 0319db855c2e39a5efc043123bae471f99f2882e Mon Sep 17 00:00:00 2001 From: Marcy Sutton Date: Tue, 10 Oct 2017 15:41:04 -0700 Subject: [PATCH 10/15] test: fix main tests for shadowdom --- .../keyboard/has-no-more-than-one-main.js | 56 +++++++++---------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/test/checks/keyboard/has-no-more-than-one-main.js b/test/checks/keyboard/has-no-more-than-one-main.js index 935c425c12..6003246965 100644 --- a/test/checks/keyboard/has-no-more-than-one-main.js +++ b/test/checks/keyboard/has-no-more-than-one-main.js @@ -2,50 +2,44 @@ describe('has-no-more-than-one-main', function () { 'use strict'; var fixture = document.getElementById('fixture'); + var checkSetup = axe.testUtils.checkSetup; + var shadowCheckSetup = axe.testUtils.shadowCheckSetup; + var shadowSupported = axe.testUtils.shadowSupport.v1; + + var checkContext = new axe.testUtils.MockCheckContext(); afterEach(function () { fixture.innerHTML = ''; + checkContext._data = null; }); it('should return false if there is more than one element with role main', function () { - var mainDiv = document.createElement('div'); - mainDiv.setAttribute('role','main'); - var anotherMain = document.createElement('div'); - anotherMain.setAttribute('role','main'); - var node = document.querySelector('html'); - node.appendChild(mainDiv); - node.appendChild(anotherMain); - assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainDiv); - node.removeChild(anotherMain); + var params = checkSetup('
'); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); it('should return false if there is more than one main element', function () { - var mainLandmark = document.createElement('main'); - var anotherMain = document.createElement('main'); - var node = document.querySelector('html'); - node.appendChild(mainLandmark); - node.appendChild(anotherMain); - assert.isFalse(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainLandmark); - node.removeChild(anotherMain); + var params = checkSetup('
'); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); - it('should return true if there is only one element with role main', function(){ - var mainDiv = document.createElement('div'); - mainDiv.setAttribute('role','main'); - var node = document.querySelector('html'); - node.appendChild(mainDiv); - assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainDiv); + it('should return true if there is only one element with role main', function() { + var params = checkSetup('
'); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate.apply(checkSetup, params)); }); - it('should return true if there is only one main element', function(){ - var mainLandmark = document.createElement('main'); - var node = document.querySelector('html'); - node.appendChild(mainLandmark); - assert.isTrue(checks['has-no-more-than-one-main'].evaluate(node)); - node.removeChild(mainLandmark); + it('should return true if there is only one main element', function() { + var params = checkSetup('
'); + assert.isTrue(checks['has-no-more-than-one-main'].evaluate.apply(checkSetup, params)); + }); + + (shadowSupported ? it : xit) + ('should return false if there is a second main element inside the shadow dom', function () { + var params = shadowCheckSetup( + '
', + '
' + ); + assert.isFalse(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); }); }); \ No newline at end of file From 59e6d166e77b8c33355e3745e7a5b1e57c0abeea Mon Sep 17 00:00:00 2001 From: ssanaul Date: Wed, 18 Oct 2017 16:03:09 -0500 Subject: [PATCH 11/15] fix: resolve timeout issues --- doc/rule-descriptions.md | 2 +- lib/checks/keyboard/has-at-least-one-main.js | 4 ++-- lib/rules/landmark-one-main.json | 2 +- test/checks/keyboard/has-no-more-than-one-main.js | 1 - .../full/landmark-one-main/landmark-one-main-fail.js | 1 - ...mark-one-pass.html => landmark-one-main-pass.html} | 1 - .../full/landmark-one-main/landmark-one-main-pass.js | 11 ++++------- 7 files changed, 8 insertions(+), 14 deletions(-) rename test/integration/full/landmark-one-main/{landmark-one-pass.html => landmark-one-main-pass.html} (92%) diff --git a/doc/rule-descriptions.md b/doc/rule-descriptions.md index 6fd84d53c3..5d74059269 100644 --- a/doc/rule-descriptions.md +++ b/doc/rule-descriptions.md @@ -33,7 +33,7 @@ | input-image-alt | Ensures <input type="image"> elements have alternate text | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true | | label-title-only | Ensures that every form element is not solely labeled using the title or aria-describedby attributes | cat.forms, best-practice | false | | label | Ensures every form element has a label | cat.forms, wcag2a, wcag332, wcag131, section508, section508.22.n | true | -| landmark-at-least-one-main | Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one. | best-practice | true | +| landmark-one-main | Ensures a navigation point to the primary content of the page. If the page contains iframes, each iframe should contain either no main landmarks or just one. | best-practice | true | | layout-table | Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute | cat.semantics, wcag2a, wcag131 | true | | link-in-text-block | Links can be distinguished without relying on color | cat.color, experimental, wcag2a, wcag141 | true | | link-name | Ensures links have discernible text | cat.name-role-value, wcag2a, wcag111, wcag412, wcag244, section508, section508.22.a | true | diff --git a/lib/checks/keyboard/has-at-least-one-main.js b/lib/checks/keyboard/has-at-least-one-main.js index 06db7aa2b4..52542995a0 100644 --- a/lib/checks/keyboard/has-at-least-one-main.js +++ b/lib/checks/keyboard/has-at-least-one-main.js @@ -1,3 +1,3 @@ const mains = axe.utils.querySelectorAll(virtualNode, 'main,[role=main]'); -this.data(!!mains.length); -return !!mains.length; \ No newline at end of file +this.data(!!mains[0]); +return !!mains[0]; \ No newline at end of file diff --git a/lib/rules/landmark-one-main.json b/lib/rules/landmark-one-main.json index 186bd4cd23..7cb68a8117 100644 --- a/lib/rules/landmark-one-main.json +++ b/lib/rules/landmark-one-main.json @@ -1,5 +1,5 @@ { - "id": "landmark-at-least-one-main", + "id": "landmark-one-main", "selector": "html", "tags": [ "best-practice" diff --git a/test/checks/keyboard/has-no-more-than-one-main.js b/test/checks/keyboard/has-no-more-than-one-main.js index d2b012576d..d3618d4b9e 100644 --- a/test/checks/keyboard/has-no-more-than-one-main.js +++ b/test/checks/keyboard/has-no-more-than-one-main.js @@ -2,7 +2,6 @@ describe('has-no-more-than-one-main', function () { 'use strict'; var fixture = document.getElementById('fixture'); - var checkContext = new axe.testUtils.MockCheckContext(); var checkSetup = axe.testUtils.checkSetup; var shadowCheckSetup = axe.testUtils.shadowCheckSetup; diff --git a/test/integration/full/landmark-one-main/landmark-one-main-fail.js b/test/integration/full/landmark-one-main/landmark-one-main-fail.js index 491b38614a..3f265b5dca 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-fail.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-fail.js @@ -1,7 +1,6 @@ describe('landmark-one-main test failure', function () { 'use strict'; var results; - before(function (done) { axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { assert.isNull(err); diff --git a/test/integration/full/landmark-one-main/landmark-one-pass.html b/test/integration/full/landmark-one-main/landmark-one-main-pass.html similarity index 92% rename from test/integration/full/landmark-one-main/landmark-one-pass.html rename to test/integration/full/landmark-one-main/landmark-one-main-pass.html index 5bc8394ae1..f21d44f322 100644 --- a/test/integration/full/landmark-one-main/landmark-one-pass.html +++ b/test/integration/full/landmark-one-main/landmark-one-main-pass.html @@ -1,7 +1,6 @@ - landmark-at-least-one-main test pass diff --git a/test/integration/full/landmark-one-main/landmark-one-main-pass.js b/test/integration/full/landmark-one-main/landmark-one-main-pass.js index a5c0da1353..112837108a 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-pass.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-pass.js @@ -2,18 +2,15 @@ describe('landmark-one-main test pass', function () { 'use strict'; var results; before(function (done) { - window.addEventListener('load', function () { - axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { - assert.isNull(err); - results = r; - done(); - }); + axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { + assert.isNull(err); + results = r; + done(); }); }); describe('violations', function () { it('should find 0', function () { - document.innerHTML = results; assert.lengthOf(results.violations, 0); }); }); From 26ee38bc2c4d8f0b604238b2d56c8af1958ece6c Mon Sep 17 00:00:00 2001 From: ssanaul Date: Fri, 20 Oct 2017 11:46:13 -0500 Subject: [PATCH 12/15] fix: add event listener --- .../landmark-one-main/landmark-one-main-pass.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/integration/full/landmark-one-main/landmark-one-main-pass.js b/test/integration/full/landmark-one-main/landmark-one-main-pass.js index 112837108a..6b040e0143 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-pass.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-pass.js @@ -2,11 +2,18 @@ describe('landmark-one-main test pass', function () { 'use strict'; var results; before(function (done) { - axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { - assert.isNull(err); - results = r; - done(); - }); + function start() { + axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { + assert.isNull(err); + results = r; + done(); + }); + } + if (document.readyState !== 'complete') { + window.addEventListener('load', start); + } else { + start(); + } }); describe('violations', function () { From 47c7e661606ed37768cc3b9e6b85f893aeca8082 Mon Sep 17 00:00:00 2001 From: ssanaul Date: Fri, 20 Oct 2017 11:49:25 -0500 Subject: [PATCH 13/15] fix: change where to check for passes --- .../full/landmark-one-main/landmark-one-main-pass.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/full/landmark-one-main/landmark-one-main-pass.js b/test/integration/full/landmark-one-main/landmark-one-main-pass.js index 6b040e0143..a038bf2105 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-pass.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-pass.js @@ -24,7 +24,7 @@ describe('landmark-one-main test pass', function () { describe('passes', function () { it('should find 4', function () { - assert.lengthOf(results.passes, 4); + assert.lengthOf(results.passes[0].nodes, 4); }); it('should find #pass1', function () { From a3beee1162bfe3d944181eb6479ceb1625d0d931 Mon Sep 17 00:00:00 2001 From: Sulaiman Sanaullah Date: Thu, 16 Nov 2017 14:43:25 -0600 Subject: [PATCH 14/15] style: comment code for comprehension --- lib/checks/keyboard/has-at-least-one-main-after.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/checks/keyboard/has-at-least-one-main-after.js b/lib/checks/keyboard/has-at-least-one-main-after.js index ef72a101db..32027fe1ad 100644 --- a/lib/checks/keyboard/has-at-least-one-main-after.js +++ b/lib/checks/keyboard/has-at-least-one-main-after.js @@ -1,8 +1,16 @@ var hasMain = false; + +//iterate through results from each document +//stops if any document contains a main landmark for (var i = 0; i < results.length && !hasMain; i++) { hasMain = results[i].data; } + +//if any document contains a main landmark, set all documents to pass the check +//otherwise, fail all documents +//since this is a page level rule, all documents either pass or fail the requirement for (var i = 0; i < results.length; i++) { results[i].result = hasMain; } -return results; \ No newline at end of file + +return results; From 6359af12f3d6b94275fd478b1a34da13aa30dc0d Mon Sep 17 00:00:00 2001 From: Sulaiman Sanaullah Date: Fri, 17 Nov 2017 14:41:44 -0600 Subject: [PATCH 15/15] test: add test for second violation node --- .../landmark-one-main-fail.js | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/test/integration/full/landmark-one-main/landmark-one-main-fail.js b/test/integration/full/landmark-one-main/landmark-one-main-fail.js index 3f265b5dca..b44a999ddf 100644 --- a/test/integration/full/landmark-one-main/landmark-one-main-fail.js +++ b/test/integration/full/landmark-one-main/landmark-one-main-fail.js @@ -2,20 +2,32 @@ describe('landmark-one-main test failure', function () { 'use strict'; var results; before(function (done) { - axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { - assert.isNull(err); - results = r; - done(); - }); + function start() { + axe.run({ runOnly: { type: 'rule', values: ['landmark-one-main'] } }, function (err, r) { + assert.isNull(err); + results = r; + done(); + }); + } + if (document.readyState !== 'complete') { + window.addEventListener('load', start); + } else { + start(); + } }); describe('violations', function () { it('should find 1', function () { - assert.lengthOf(results.violations, 1); + assert.lengthOf(results.violations[0].nodes, 2); }); - it('should find first level iframe', function () { + + it('should find #frame1', function () { assert.deepEqual(results.violations[0].nodes[0].target, ['#fail1']); }); + + it('should find #frame1, #violation2', function () { + assert.deepEqual(results.violations[0].nodes[1].target, ['#frame1', '#violation2']); + }); }); describe('passes', function () {