-
Notifications
You must be signed in to change notification settings - Fork 788
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add rule, landmark-main-is-top-level (#462)
* init * feat: add new rule, landmark-no-more-than-one-main * test(landmark-at-least-one-main): updated integration tests for check * feat(landmark-main-is-top-level): add rule ensuring each main landmark in a document is not within another landmark element * refactor(landmark-main-is-top-level): change help messages * feat(landmark-main-is-top-level): change a function used in check and update aria index file so application type is structure * refactor(main-is-top-level): change pass/fail messages * refactor(landmark-main-is-top-level): change description/help messages * feat(main-is-top-level): update check for shadow dom features * fix(main-is-top-level): update check to ignore form as a landmark * fix: edit incorrect usage of getComposedParent * test: add unit test to check if main landmark in shadow dom is top level * style: remove spaces in attributes * fix: update test so that checkSetup passes in correct argument * test: add test to ensure correct number of violations nodes * fix: revert 'application' type to landmark * style: remove spaces in attributes * fix: allow main landmark to be in form
- Loading branch information
Showing
13 changed files
with
336 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
var landmarks = axe.commons.aria.getRolesByType('landmark'); | ||
var parent = axe.commons.dom.getComposedParent(node); | ||
while (parent){ | ||
var role = parent.getAttribute('role'); | ||
if (!role && (parent.tagName.toLowerCase() !== 'form')){ | ||
role = axe.commons.aria.implicitRole(parent); | ||
} | ||
if (role && landmarks.includes(role)){ | ||
return false; | ||
} | ||
parent = axe.commons.dom.getComposedParent(parent); | ||
} | ||
return true; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"id": "main-is-top-level", | ||
"evaluate": "main-is-top-level.js", | ||
"metadata": { | ||
"impact": "moderate", | ||
"messages": { | ||
"pass": "The main landmark is at the top level.", | ||
"fail": "The main landmark is contained in another landmark." | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"id": "landmark-main-is-top-level", | ||
"selector": "main,[role=main]", | ||
"tags": [ | ||
"best-practice" | ||
], | ||
"metadata": { | ||
"description": "The main landmark should not be contained in another landmark", | ||
"help": "Main landmark is not at top level" | ||
}, | ||
"all": [], | ||
"any": [ | ||
"main-is-top-level" | ||
], | ||
"none": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
describe('main-is-top-level', function () { | ||
'use strict'; | ||
|
||
var fixture = document.getElementById('fixture'); | ||
|
||
var shadowSupported = axe.testUtils.shadowSupport.v1; | ||
var checkSetup = axe.testUtils.checkSetup; | ||
|
||
afterEach(function () { | ||
fixture.innerHTML = ''; | ||
}); | ||
|
||
it('should return false if main landmark is in another landmark', function () { | ||
var mainLandmark = document.createElement('main'); | ||
var bannerDiv = document.createElement('div'); | ||
bannerDiv.setAttribute('role','banner'); | ||
bannerDiv.appendChild(mainLandmark); | ||
fixture.appendChild(bannerDiv); | ||
assert.isFalse(checks['main-is-top-level'].evaluate(mainLandmark)); | ||
}); | ||
|
||
it('should return false if div with role set to main is in another landmark', function () { | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.setAttribute('role','main'); | ||
var navDiv = document.createElement('div'); | ||
navDiv.setAttribute('role','navigation'); | ||
navDiv.appendChild(mainDiv); | ||
fixture.appendChild(navDiv); | ||
assert.isFalse(checks['main-is-top-level'].evaluate(mainDiv)); | ||
}); | ||
|
||
it('should return true if main landmark is not in another landmark', function () { | ||
var mainLandmark = document.createElement('main'); | ||
var bannerDiv = document.createElement('div'); | ||
bannerDiv.setAttribute('role','banner'); | ||
fixture.appendChild(bannerDiv); | ||
fixture.appendChild(mainLandmark); | ||
assert.isTrue(checks['main-is-top-level'].evaluate(mainLandmark)); | ||
}); | ||
|
||
it('should return true if div with role set to main is not in another landmark', function () { | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.setAttribute('role','main'); | ||
var navDiv = document.createElement('div'); | ||
navDiv.setAttribute('role','navigation'); | ||
fixture.appendChild(navDiv); | ||
fixture.appendChild(mainDiv); | ||
assert.isTrue(checks['main-is-top-level'].evaluate(mainDiv)); | ||
}); | ||
|
||
it('should return true if main is in form landmark', function () { | ||
var mainDiv = document.createElement('div'); | ||
mainDiv.setAttribute('role','main'); | ||
var formDiv = document.createElement('div'); | ||
formDiv.setAttribute('role','form'); | ||
fixture.appendChild(formDiv); | ||
fixture.appendChild(mainDiv); | ||
assert.isTrue(checks['main-is-top-level'].evaluate(mainDiv)); | ||
}); | ||
|
||
|
||
(shadowSupported ? it : xit)('should test if main in shadow DOM is top level', function () { | ||
var div = document.createElement('div'); | ||
var shadow = div.attachShadow({ mode: 'open' }); | ||
shadow.innerHTML = '<main>Main content</main>'; | ||
var checkArgs = checkSetup(shadow.querySelector('main')); | ||
assert.isTrue(checks['main-is-top-level'].evaluate.apply(null, checkArgs)); | ||
}); | ||
|
||
}); |
17 changes: 17 additions & 0 deletions
17
test/integration/full/landmark-main-is-top-level/frames/level1-fail.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!doctype html> | ||
<html id="violation2"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<p>This iframe should fail, too</p> | ||
<div role="complementary"> | ||
<div role="main"> | ||
<p>This main landmark is in a complementary landmark</p> | ||
</div> | ||
</div> | ||
<iframe id="frame2" src="level2.html"></iframe> | ||
<iframe id="frame3" src="level2-a.html"></iframe> | ||
</body> | ||
</html> |
29 changes: 29 additions & 0 deletions
29
test/integration/full/landmark-main-is-top-level/frames/level1.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!doctype html> | ||
<html id="pass2"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<p>This iframe should pass, too</p> | ||
|
||
<div role="banner"> | ||
<p>This div has role banner</p> | ||
</div> | ||
<div role="navigation"> | ||
<p>This div has role navigation</p> | ||
</div> | ||
<div role="main"> | ||
<p>This main content is not within another landmark</p> | ||
</div> | ||
<div role="complementary"> | ||
<p>This div has role complementary</p> | ||
</div> | ||
<div role="search"> | ||
<p>This div has role search</p> | ||
</div> | ||
<div role="form"> | ||
<p>This div has role form<p> | ||
</div> | ||
</body> | ||
</html> |
15 changes: 15 additions & 0 deletions
15
test/integration/full/landmark-main-is-top-level/frames/level2-a.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!doctype html> | ||
<html id="violation4"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<p>This iframe is also a violation</p> | ||
<div role="navigation"> | ||
<main> | ||
<p>This main landmark is in a navigation landmark</p> | ||
</main> | ||
</div> | ||
</body> | ||
</html> |
15 changes: 15 additions & 0 deletions
15
test/integration/full/landmark-main-is-top-level/frames/level2.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<!doctype html> | ||
<html id="violation3"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<p>This iframe is another violation<p> | ||
<div role="search"> | ||
<main> | ||
<p>This main landmark is in a search landmark</p> | ||
</main> | ||
</div> | ||
</body> | ||
</html> |
29 changes: 29 additions & 0 deletions
29
test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<!doctype html> | ||
<html lang="en" id="violation1"> | ||
<head> | ||
<title>landmark-main-is-top-level test</title> | ||
<meta charset="utf8"> | ||
<link rel="stylesheet" type="text/css" href="/node_modules/mocha/mocha.css" /> | ||
<script src="/node_modules/mocha/mocha.js"></script> | ||
<script src="/node_modules/chai/chai.js"></script> | ||
<script src="/axe.js"></script> | ||
<script> | ||
mocha.setup({ | ||
timeout: 10000, | ||
ui: 'bdd' | ||
}); | ||
var assert = chai.assert; | ||
</script> | ||
</head> | ||
<body> | ||
<div role="navigation"> | ||
<div role="main"> | ||
<p>This is going to fail</p> | ||
</div> | ||
</div> | ||
<iframe id="frame1" src="frames/level1-fail.html"></iframe> | ||
<div id="mocha"></div> | ||
<script src="landmark-main-is-top-level-fail.js"></script> | ||
<script src="/test/integration/adapter.js"></script> | ||
</body> | ||
</html> |
42 changes: 42 additions & 0 deletions
42
test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
|
||
describe('landmark-main-is-top-level test fail', function () { | ||
'use strict'; | ||
var results; | ||
before(function (done) { | ||
window.addEventListener('load', function () { | ||
axe.run({ runOnly: { type: 'rule', values: ['landmark-main-is-top-level'] } }, function (err, r) { | ||
assert.isNull(err); | ||
results = r; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('violations', function () { | ||
it('should find 1', function () { | ||
assert.lengthOf(results.violations, 1); | ||
}); | ||
|
||
it('should find 4 nodes', function () { | ||
assert.lengthOf(results.violations[0].nodes, 4); | ||
}); | ||
}); | ||
|
||
describe('passes', function () { | ||
it('should find none', 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); | ||
}); | ||
|
||
}); | ||
|
42 changes: 42 additions & 0 deletions
42
test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<!doctype html> | ||
<html lang="en" id="pass1"> | ||
<head> | ||
<title>landmark-main-is-top-level test</title> | ||
<meta charset="utf8"> | ||
<link rel="stylesheet" type="text/css" href="/node_modules/mocha/mocha.css" /> | ||
<script src="/node_modules/mocha/mocha.js"></script> | ||
<script src="/node_modules/chai/chai.js"></script> | ||
<script src="/axe.js"></script> | ||
<script> | ||
mocha.setup({ | ||
timeout: 10000, | ||
ui: 'bdd' | ||
}); | ||
var assert = chai.assert; | ||
</script> | ||
</head> | ||
<body> | ||
<div role="banner"> | ||
<p>This div has role banner</p> | ||
</div> | ||
<div role="navigation"> | ||
<p>This div has role navigation</p> | ||
</div> | ||
<main> | ||
<p>This main content is not within another landmark</p> | ||
</main> | ||
<div role="complementary"> | ||
<p>This div has role complementary</p> | ||
</div> | ||
<div role="search"> | ||
<p>This div has role search</p> | ||
</div> | ||
<div role="form"> | ||
<p>This div has role form<p> | ||
</div> | ||
<iframe id="frame1" src="frames/level1.html"></iframe> | ||
<div id="mocha"></div> | ||
<script src="landmark-main-is-top-level-pass.js"></script> | ||
<script src="/test/integration/adapter.js"></script> | ||
</body> | ||
</html> |
36 changes: 36 additions & 0 deletions
36
test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
|
||
describe('landmark-main-is-top-level test pass', function () { | ||
'use strict'; | ||
var results; | ||
before(function (done) { | ||
window.addEventListener('load', function () { | ||
axe.run({ runOnly: { type: 'rule', values: ['landmark-main-is-top-level'] } }, function (err, r) { | ||
assert.isNull(err); | ||
results = r; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('violations', function () { | ||
it('should find 0', function () { | ||
assert.lengthOf(results.violations, 0); | ||
}); | ||
}); | ||
|
||
describe('passes', function () { | ||
it('should find 2', function () { | ||
assert.lengthOf(results.passes[0].nodes, 2); | ||
}); | ||
}); | ||
|
||
it('should find 0 inapplicable', function () { | ||
assert.lengthOf(results.inapplicable, 0); | ||
}); | ||
|
||
it('should find 0 incomplete', function () { | ||
assert.lengthOf(results.incomplete, 0); | ||
}); | ||
|
||
}); | ||
|