Skip to content

Commit

Permalink
fix(has-lang): fail check when xml:lang is used in HTML docum… (#2053)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeeyyy authored and straker committed Mar 6, 2020
1 parent bf4c9bf commit e07aaea
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 6 deletions.
15 changes: 10 additions & 5 deletions lib/checks/language/has-lang.js
@@ -1,5 +1,10 @@
return !!(
node.getAttribute('lang') ||
node.getAttribute('xml:lang') ||
''
).trim();
const { isXHTML } = axe.utils;

const langValue = (node.getAttribute(`lang`) || '').trim();
const xmlLangValue = (node.getAttribute(`xml:lang`) || '').trim();

if (!langValue && !isXHTML(document)) {
return false;
}

return !!(langValue || xmlLangValue);
8 changes: 7 additions & 1 deletion test/checks/language/has-lang.js
Expand Up @@ -15,9 +15,15 @@ describe('has-lang', function() {
assert.isTrue(checks['has-lang'].evaluate(node));
});

it('should return true if xml:lang attribute is present', function() {
it('should return false if only `xml:lang` attribute is present', function() {
fixture.innerHTML = '<div xml:lang="cats"></div>';

assert.isFalse(checks['has-lang'].evaluate(fixture.firstChild));
});

it('should return true if both `lang` and `xml:lang` attribute is present', function() {
fixture.innerHTML = '<div lang="cats" xml:lang="cats"></div>';

assert.isTrue(checks['has-lang'].evaluate(fixture.firstChild));
});

Expand Down
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html id="fail1" xml:lang="fr">
<head>
<title>html-has-lang 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>
<!--
Note:
This rule does not include `iframe` uses matches "window-is-top.js"
-->
<div id="mocha"></div>
<script src="/test/testutils.js"></script>
<script src="html-has-lang-fail-xml-lang.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>
37 changes: 37 additions & 0 deletions test/integration/full/html-has-lang/html-has-lang-fail-xml-lang.js
@@ -0,0 +1,37 @@
/**
* Note:
* This rule does not include `iframe` uses matches "window-is-top.js"
*/
describe('html-has-lang fail test', function() {
'use strict';

var results;
before(function(done) {
axe.testUtils.awaitNestedLoad(function() {
axe.run(
{ runOnly: { type: 'rule', values: ['html-has-lang'] } },
function(err, r) {
assert.isNull(err);
results = r;
done();
}
);
});
});

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

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

describe('passes', function() {
it('should find 0 passes', function() {
assert.lengthOf(results.passes, 0);
});
});
});
36 changes: 36 additions & 0 deletions test/integration/full/html-has-lang/html-has-lang-pass-xhtml.js
@@ -0,0 +1,36 @@
/**
* Note:
* This rule does not include `iframe` uses matches "window-is-top.js"
*/
describe('html-has-lang pass test', function() {
'use strict';
var results;
before(function(done) {
axe.testUtils.awaitNestedLoad(function() {
axe.run(
{ runOnly: { type: 'rule', values: ['html-has-lang'] } },
function(err, r) {
assert.isNull(err);
results = r;
done();
}
);
});
});

describe('violations', function() {
it('should find 0 violations', 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']);
});
});
});
33 changes: 33 additions & 0 deletions test/integration/full/html-has-lang/html-has-lang-pass-xhtml.xhtml
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="klingon" xml:lang="klingon" id="pass1" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>html-has-lang 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>
<!--
Note:
This rule excludes `iframe`, uses matches "window-is-top.js"
-->
<div id="mocha"></div>
<script src="/test/testutils.js"></script>
<script src="html-has-lang-pass-xhtml.js"></script>
<script src="/test/integration/adapter.js"></script>
</body>
</html>

0 comments on commit e07aaea

Please sign in to comment.