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(bypass): find headings in iframes #2310

Merged
merged 14 commits into from
Jul 1, 2020
1 change: 1 addition & 0 deletions lib/checks/navigation/header-present.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"id": "header-present",
"evaluate": "has-descendant-evaluate",
"after": "has-descendant-after",
"options": {
"selector": "h1:not([role]), h2:not([role]), h3:not([role]), h4:not([role]), h5:not([role]), h6:not([role]), [role=heading]"
},
Expand Down
11 changes: 10 additions & 1 deletion lib/rules/bypass-matches.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import windowIsTopMatches from './window-is-top-matches';

function bypassMatches(node) {
return !!node.querySelector('a[href]');
// the top level window should have an anchor
if (windowIsTopMatches(node)) {
return !!node.querySelector('a[href]');
Comment on lines +5 to +6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm kind of confused about what you are trying to accomplish here. I don't see how pages having native links is relevant to whether or not they need a mechanism for bypassing repeating content.

Copy link
Contributor Author

@straker straker Jun 19, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original matches function required a page link before testing the entire page. Without one, the iframes (which don't have anchors) would not be tested for headings or landmarks. As to why we require the link in the first place, I have no idea.

}

// all iframes do not need an anchor but should be checked for bypass
// elements (headings, landmarks, etc.)
return true;
}

export default bypassMatches;
10 changes: 10 additions & 0 deletions test/integration/full/bypass/frames/level1-fail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en" id="violation2">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<meta charset="utf8" />
<script src="/axe.js"></script>
</head>
<body>
<p>No h1 here either</p>
</body>
</html>
12 changes: 12 additions & 0 deletions test/integration/full/bypass/frames/level1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en" id="pass2">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<meta charset="utf8" />
<script src="/axe.js"></script>
</head>
<body>
<p>No h1 here either</p>
<iframe id="frame2" src="level2-a.html"></iframe>
<iframe id="frame3" src="level2.html"></iframe>
</body>
</html>
10 changes: 10 additions & 0 deletions test/integration/full/bypass/frames/level2-a.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en" id="pass3">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<meta charset="utf8" />
<script src="/axe.js"></script>
</head>
<body>
<h1>This page has an h1</h1>
</body>
</html>
10 changes: 10 additions & 0 deletions test/integration/full/bypass/frames/level2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en" id="pass4">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<meta charset="utf8" />
<script src="/axe.js"></script>
</head>
<body>
<p>No h1 content in this iframe</p>
</body>
</html>
30 changes: 30 additions & 0 deletions test/integration/full/bypass/header-iframe-fail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en" id="fail1">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<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 h1 content</p>
<iframe id="frame1" src="frames/level1-fail.html"></iframe>
<a href="http://www.deque.com">stuff</a>
<div id="mocha"></div>
<script src="/test/testutils.js"></script>
<script src="header-iframe-fail.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions test/integration/full/bypass/header-iframe-fail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
describe('bypass iframe test fail', function() {
'use strict';
var results;
before(function(done) {
axe.testUtils.awaitNestedLoad(function() {
// Stop messing with my tests Mocha!
var heading = document.querySelector('#mocha h1');
if (heading) {
heading.outerHTML = '<div><b>bypass iframe test fail</b></div>';
}

axe.run({ runOnly: { type: 'rule', values: ['bypass'] } }, 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 #frame1', function() {
assert.deepEqual(results.violations[0].nodes[0].target, ['#fail1']);
});
});

describe('passes', function() {
it('should find none', function() {
assert.lengthOf(results.passes, 0);
});
});
});
30 changes: 30 additions & 0 deletions test/integration/full/bypass/header-iframe-pass.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en" id="pass1">
<head>
straker marked this conversation as resolved.
Show resolved Hide resolved
<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 h1 content</p>
<iframe id="frame1" src="frames/level1.html"></iframe>
<a href="http://www.deque.com">stuff</a>
<div id="mocha"></div>
<script src="/test/testutils.js"></script>
<script src="header-iframe-pass.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
39 changes: 39 additions & 0 deletions test/integration/full/bypass/header-iframe-pass.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
describe('bypass iframe test pass', function() {
'use strict';
var results;
before(function(done) {
this.timeout = 50000;
axe.testUtils.awaitNestedLoad(function() {
// Stop messing with my tests Mocha!
var heading = document.querySelector('#mocha h1');
if (heading) {
heading.outerHTML = '<div><b>bypass pass test fail</b></div>';
}

axe.run({ runOnly: { type: 'rule', values: ['bypass'] } }, function(
err,
r
) {
assert.isNull(err);
results = r;
done();
});
});
});

describe('violations', function() {
it('should find none', function() {
assert.lengthOf(results.violations, 0);
});
});

describe('passes', function() {
it('should find 1', function() {
assert.lengthOf(results.passes[0].nodes, 1);
});

it('should find #pass1', function() {
assert.deepEqual(results.passes[0].nodes[0].target, ['#pass1']);
});
});
});