diff --git a/lib/checks/language/has-lang.js b/lib/checks/language/has-lang.js index aba70aaf4f..28626e11e9 100644 --- a/lib/checks/language/has-lang.js +++ b/lib/checks/language/has-lang.js @@ -3,8 +3,18 @@ const { isXHTML } = axe.utils; const langValue = (node.getAttribute(`lang`) || '').trim(); const xmlLangValue = (node.getAttribute(`xml:lang`) || '').trim(); -if (!langValue && !isXHTML(document)) { +if (!langValue && xmlLangValue && !isXHTML(document)) { + this.data({ + messageKey: 'noXHTML' + }); return false; } -return !!(langValue || xmlLangValue); +if (!(langValue || xmlLangValue)) { + this.data({ + messageKey: 'noLang' + }); + return false; +} + +return true; diff --git a/lib/checks/language/has-lang.json b/lib/checks/language/has-lang.json index 0be958a1e7..151cfc4d5b 100644 --- a/lib/checks/language/has-lang.json +++ b/lib/checks/language/has-lang.json @@ -5,7 +5,10 @@ "impact": "serious", "messages": { "pass": "The element has a lang attribute", - "fail": "The element does not have a lang attribute" + "fail": { + "noXHTML": "The xml:lang attribute is not valid on HTML pages, use the lang attribute.", + "noLang": "The element does not have a lang attribute" + } } } } diff --git a/test/checks/language/has-lang.js b/test/checks/language/has-lang.js index a4e06cf1db..d37ca4a4f6 100644 --- a/test/checks/language/has-lang.js +++ b/test/checks/language/has-lang.js @@ -2,43 +2,47 @@ describe('has-lang', function() { 'use strict'; var fixture = document.getElementById('fixture'); + var checkContext = axe.testUtils.MockCheckContext(); + var checkSetup = axe.testUtils.checkSetup; + var hasLangEvaluate = checks['has-lang'].evaluate; afterEach(function() { fixture.innerHTML = ''; + checkContext.reset(); }); it('should return true if a lang attribute is present', function() { - var node = document.createElement('div'); - node.setAttribute('lang', 'woohoo'); - fixture.appendChild(node); + var params = checkSetup('
'); - assert.isTrue(checks['has-lang'].evaluate(node)); + assert.isTrue(hasLangEvaluate.apply(checkContext, params)); }); it('should return false if only `xml:lang` attribute is present', function() { - fixture.innerHTML = ''; + var params = checkSetup(''); - assert.isFalse(checks['has-lang'].evaluate(fixture.firstChild)); + assert.isFalse(hasLangEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noXHTML'); }); it('should return true if both `lang` and `xml:lang` attribute is present', function() { - fixture.innerHTML = ''; + var params = checkSetup( + '' + ); - assert.isTrue(checks['has-lang'].evaluate(fixture.firstChild)); + assert.isTrue(hasLangEvaluate.apply(checkContext, params)); }); it('should return false if xml:lang and lang attributes are not present', function() { - var node = document.createElement('div'); - fixture.appendChild(node); + var params = checkSetup(''); - assert.isFalse(checks['has-lang'].evaluate(node)); + assert.isFalse(hasLangEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noLang'); }); it('should return false if lang is left empty', function() { - var node = document.createElement('div'); - node.setAttribute('lang', ''); - fixture.appendChild(node); + var params = checkSetup(''); - assert.isFalse(checks['has-lang'].evaluate(node)); + assert.isFalse(hasLangEvaluate.apply(checkContext, params)); + assert.equal(checkContext._data.messageKey, 'noLang'); }); });