-
Notifications
You must be signed in to change notification settings - Fork 780
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(landmark-no-more-than-one-banner): add rule ensuring no more tha…
…n one banner
- Loading branch information
1 parent
aa074fe
commit 6617800
Showing
12 changed files
with
308 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,29 @@ | ||
const banners = axe.utils.querySelectorAll(virtualNode, 'header, [role=banner]'); | ||
const sectioning = ['main', 'section', 'aside', 'nav', 'article']; | ||
var count = 0; | ||
|
||
function isBanner(node){ | ||
var parent = axe.commons.dom.getComposedParent(node); | ||
while (parent){ | ||
if (sectioning.includes(parent.tagName.toLowerCase())){ | ||
return false; | ||
} | ||
parent = axe.commons.dom.getComposedParent(parent); | ||
} | ||
return true; | ||
} | ||
|
||
for (var i=0; i<banners.length; i++){ | ||
var node = banners[i].actualNode; | ||
var role = node.getAttribute('role'); | ||
if (!!role){ | ||
role = role.toLowerCase(); | ||
} | ||
if (role==='banner' || isBanner(node)){ | ||
count++; | ||
} | ||
if (count>1){ | ||
return false; | ||
} | ||
} | ||
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": "has-no-more-than-one-banner", | ||
"evaluate": "has-no-more-than-one-banner.js", | ||
"metadata": { | ||
"impact": "moderate", | ||
"messages": { | ||
"pass": "Document has no more than one banner landmark", | ||
"fail": "Document has more than one banner 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-no-more-than-one-banner", | ||
"selector": "html", | ||
"tags": [ | ||
"best-practice" | ||
], | ||
"metadata": { | ||
"description": "A banner landmark identifies site-oriented content at the beginning of each page within a website", | ||
"help": "Page must not contain more than one banner landmark" | ||
}, | ||
"all": [], | ||
"any": [ | ||
"has-no-more-than-one-banner" | ||
], | ||
"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,50 @@ | ||
describe('has-no-more-than-one-banner', function () { | ||
'use strict'; | ||
|
||
var fixture = document.getElementById('fixture'); | ||
var checkContext = new axe.testUtils.MockCheckContext(); | ||
var checkSetup = axe.testUtils.checkSetup; | ||
var shadowCheckSetup = axe.testUtils.shadowCheckSetup; | ||
var shadowSupported = axe.testUtils.shadowSupport.v1; | ||
|
||
afterEach(function () { | ||
fixture.innerHTML = ''; | ||
checkContext.reset(); | ||
}); | ||
|
||
it('should return false if there is more than one element with role banner', function () { | ||
var params = checkSetup('<div id="target"><div role="banner"></div><div role="banner"></div></div>'); | ||
assert.isFalse(checks['has-no-more-than-one-banner'].evaluate.apply(checkContext, params)); | ||
|
||
}); | ||
|
||
it('should return false if there is more than one header serving as a banner', function () { | ||
var params = checkSetup('<div id="target"><header></header><header></header></div>'); | ||
assert.isFalse(checks['has-no-more-than-one-banner'].evaluate.apply(checkContext, params)); | ||
}); | ||
|
||
it('should return true if there are multiple headers contained in sectioning elements', function(){ | ||
var params = checkSetup('<div role="main" id="target"><header></header><header></header></div>'); | ||
assert.isTrue(checks['has-no-more-than-one-main'].evaluate.apply(checkContext, params)); | ||
}); | ||
|
||
it('should return true if there is only one element with role banner', function(){ | ||
var params = checkSetup('<div role="banner" id="target"></div>'); | ||
assert.isTrue(checks['has-no-more-than-one-banner'].evaluate.apply(checkContext, params)); | ||
}); | ||
|
||
it('should return true if there is only one header serving as a banner', function(){ | ||
var params = checkSetup('<header id="target"></header>'); | ||
assert.isTrue(checks['has-no-more-than-one-banner'].evaluate.apply(checkContext, params)); | ||
}); | ||
|
||
(shadowSupported ? it : xit) | ||
('should return false if there is a second banner inside the shadow dom', function () { | ||
var params = shadowCheckSetup( | ||
'<div role="banner" id="target"></div>', | ||
'<div role="banner"></div>' | ||
); | ||
assert.isFalse(checks['has-no-more-than-one-banner'].evaluate.apply(checkContext, params)); | ||
}); | ||
|
||
}); |
16 changes: 16 additions & 0 deletions
16
test/integration/full/landmark-no-more-than-one-banner/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,16 @@ | ||
<!doctype html> | ||
<html lang="en" id="fail2"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<header> | ||
Header 1 | ||
</header> | ||
<header> | ||
Header 2 | ||
</header> | ||
<iframe id="frame2" src="level2.html"></iframe> | ||
</body> | ||
</html> |
17 changes: 17 additions & 0 deletions
17
test/integration/full/landmark-no-more-than-one-banner/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,17 @@ | ||
<!doctype html> | ||
<html lang="en" id="pass2"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<main> | ||
<header> | ||
Header 1 contained in main landmark | ||
</header> | ||
<header> | ||
Header 2 contained in main landmark | ||
</header> | ||
</main> | ||
</body> | ||
</html> |
17 changes: 17 additions & 0 deletions
17
test/integration/full/landmark-no-more-than-one-banner/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,17 @@ | ||
<!doctype html> | ||
<html lang="en" id="fail3"> | ||
<head> | ||
<meta charset="utf8"> | ||
<script src="/axe.js"></script> | ||
</head> | ||
<body> | ||
<main> | ||
<div role="banner"> | ||
Div 1 with role banner in main landmark | ||
</div> | ||
<div role="banner"> | ||
Div 2 with role banner in main landmark | ||
</div> | ||
</main> | ||
</body> | ||
</html> |
29 changes: 29 additions & 0 deletions
29
...egration/full/landmark-no-more-than-one-banner/landmark-no-more-than-one-banner-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="fail1"> | ||
<head> | ||
<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"> | ||
Div 1 with role of "banner" | ||
</div> | ||
<div role="banner"> | ||
Div 2 with role of "banner" | ||
</div> | ||
<iframe id="frame1" src="frames/level1-fail.html"></iframe> | ||
<div id="mocha"></div> | ||
<script src="landmark-no-more-than-one-banner-fail.js"></script> | ||
<script src="/test/integration/adapter.js"></script> | ||
</body> | ||
</html> |
51 changes: 51 additions & 0 deletions
51
...ntegration/full/landmark-no-more-than-one-banner/landmark-no-more-than-one-banner-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,51 @@ | ||
describe('landmark-no-more-than-one-banner test failure', function () { | ||
'use strict'; | ||
var results; | ||
before(function (done) { | ||
function start() { | ||
axe.run({ runOnly: { type: 'rule', values: ['landmark-no-more-than-one-banner'] } }, 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 3', function () { | ||
assert.lengthOf(results.violations[0].nodes, 3); | ||
}); | ||
|
||
it('should find #fail1', function () { | ||
assert.deepEqual(results.violations[0].nodes[0].target, ['#fail1']); | ||
}); | ||
|
||
it('should find #frame1, #fail2', function () { | ||
assert.deepEqual(results.violations[0].nodes[1].target, ['#frame1', '#fail2']); | ||
}); | ||
|
||
it('should find #frame1, #frame2, #fail3', function () { | ||
assert.deepEqual(results.violations[0].nodes[2].target, ['#frame1', '#frame2', '#fail3']); | ||
}); | ||
|
||
}); | ||
|
||
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); | ||
}); | ||
}); |
24 changes: 24 additions & 0 deletions
24
...egration/full/landmark-no-more-than-one-banner/landmark-no-more-than-one-banner-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,24 @@ | ||
<!doctype html> | ||
<html lang="en" id="pass1"> | ||
<head> | ||
<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> | ||
<p>No banner landmarks</p> | ||
<iframe id="frame1" src="frames/level1.html"></iframe> | ||
<div id="mocha"></div> | ||
<script src="landmark-no-more-than-one-banner-pass.js"></script> | ||
<script src="/test/integration/adapter.js"></script> | ||
</body> | ||
</html> |
47 changes: 47 additions & 0 deletions
47
...ntegration/full/landmark-no-more-than-one-banner/landmark-no-more-than-one-banner-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,47 @@ | ||
describe('landmark-no-more-than-one-banner test pass', function () { | ||
'use strict'; | ||
var results; | ||
before(function (done) { | ||
function start() { | ||
axe.run({ runOnly: { type: 'rule', values: ['landmark-no-more-than-one-banner'] } }, 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 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 #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 0 inapplicable', function () { | ||
assert.lengthOf(results.inapplicable, 0); | ||
}); | ||
|
||
it('should find 0 incomplete', function () { | ||
assert.lengthOf(results.incomplete, 0); | ||
}); | ||
|
||
}); |