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

Enable best practices #612

Merged
merged 3 commits into from
Nov 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions doc/rule-descriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@
| empty-heading | Ensures headings have discernible text | cat.name-role-value, best-practice | true |
| frame-title-unique | Ensures <iframe> and <frame> elements contain a unique title attribute | cat.text-alternatives, best-practice | true |
| frame-title | Ensures <iframe> and <frame> elements contain a non-empty title attribute | cat.text-alternatives, wcag2a, wcag241, section508, section508.22.i | true |
| heading-order | Ensures the order of headings is semantically correct | cat.semantics, best-practice | false |
| hidden-content | Informs users about hidden content. | experimental, review-item | false |
| href-no-hash | Ensures that href values are valid link references to promote only using anchors as links | cat.semantics, best-practice | false |
| heading-order | Ensures the order of headings is semantically correct | cat.semantics, best-practice | true |
| hidden-content | Informs users about hidden content. | experimental, review-item | true |
| html-has-lang | Ensures every HTML document has a lang attribute | cat.language, wcag2a, wcag311 | true |
| html-lang-valid | Ensures the lang attribute of the <html> element has a valid value | cat.language, wcag2a, wcag311 | true |
| image-alt | Ensures <img> elements have alternate text or a role of none or presentation | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true |
| image-redundant-alt | Ensure button and link text is not repeated as image alternative | cat.text-alternatives, best-practice | true |
| input-image-alt | Ensures <input type="image"> elements have alternate text | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true |
| label-title-only | Ensures that every form element is not solely labeled using the title or aria-describedby attributes | cat.forms, best-practice | false |
| label-title-only | Ensures that every form element is not solely labeled using the title or aria-describedby attributes | cat.forms, best-practice | true |
| label | Ensures every form element has a label | cat.forms, wcag2a, wcag332, wcag131, section508, section508.22.n | true |
| layout-table | Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute | cat.semantics, wcag2a, wcag131 | true |
| link-in-text-block | Links can be distinguished without relying on color | cat.color, experimental, wcag2a, wcag141 | true |
Expand All @@ -45,10 +44,10 @@
| object-alt | Ensures <object> elements have alternate text | cat.text-alternatives, wcag2a, wcag111, section508, section508.22.a | true |
| p-as-heading | Ensure p elements are not used to style headings | cat.semantics, wcag2a, wcag131, experimental | true |
| radiogroup | Ensures related <input type="radio"> elements have a group and that the group designation is consistent | cat.forms, best-practice | true |
| region | Ensures all content is contained within a landmark region | cat.keyboard, best-practice | false |
| region | Ensures all content is contained within a landmark region | cat.keyboard, best-practice | true |
| scope-attr-valid | Ensures the scope attribute is used correctly on tables | cat.tables, best-practice | true |
| server-side-image-map | Ensures that server-side image maps are not used | cat.text-alternatives, wcag2a, wcag211, section508, section508.22.f | true |
| skip-link | Ensures the first link on the page is a skip link | cat.keyboard, best-practice | false |
| skip-link | Ensure all skip links have a focusable target | cat.keyboard, best-practice | true |
| tabindex | Ensures tabindex attribute values are not greater than 0 | cat.keyboard, best-practice | true |
| table-duplicate-name | Ensure that tables do not have the same summary and caption | cat.tables, best-practice | true |
| table-fake-caption | Ensure that tables with a caption use the <caption> element. | cat.tables, experimental, wcag2a, wcag131, section508, section508.22.g | true |
Expand Down
7 changes: 0 additions & 7 deletions lib/checks/navigation/href-no-hash.js

This file was deleted.

11 changes: 0 additions & 11 deletions lib/checks/navigation/href-no-hash.json

This file was deleted.

1 change: 0 additions & 1 deletion lib/checks/navigation/skip-link-after.js

This file was deleted.

6 changes: 5 additions & 1 deletion lib/checks/navigation/skip-link.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
return axe.commons.dom.isFocusable(axe.commons.dom.getElementByReference(node, 'href'));
const target = axe.commons.dom.getElementByReference(node, 'href');
if (target) {
return axe.commons.dom.isVisible(target, true) || undefined;
}
return false;
6 changes: 3 additions & 3 deletions lib/checks/navigation/skip-link.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"id": "skip-link",
"evaluate": "skip-link.js",
"after": "skip-link-after.js",
"metadata": {
"impact": "moderate",
"messages": {
"pass": "Valid skip link found",
"fail": "No valid skip link found"
"pass": "Skip link target exists",
"incomplete": "Skip link target should become visible on activation",
"fail": "No skip link target"
}
}
}
1 change: 0 additions & 1 deletion lib/rules/empty-heading.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"id": "empty-heading",
"selector": "h1, h2, h3, h4, h5, h6, [role=\"heading\"]",
"enabled": true,
"tags": [
"cat.name-role-value",
"best-practice"
Expand Down
1 change: 0 additions & 1 deletion lib/rules/heading-order.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"id": "heading-order",
"selector": "h1,h2,h3,h4,h5,h6,[role=heading]",
"enabled": false,
"tags": [
"cat.semantics",
"best-practice"
Expand Down
3 changes: 1 addition & 2 deletions lib/rules/hidden-content.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@
"any": [
"hidden-content"
],
"none": [],
"enabled": false
"none": []
}
18 changes: 0 additions & 18 deletions lib/rules/href-no-hash.json

This file was deleted.

1 change: 0 additions & 1 deletion lib/rules/label-title-only.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"id": "label-title-only",
"selector": "input, select, textarea",
"matches": "label-matches.js",
"enabled": false,
"tags": [
"cat.forms",
"best-practice"
Expand Down
1 change: 0 additions & 1 deletion lib/rules/region.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"id": "region",
"selector": "html",
"pageLevel": true,
"enabled": false,
"tags": [
"cat.keyboard",
"best-practice"
Expand Down
1 change: 0 additions & 1 deletion lib/rules/scope-attr-valid.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"id": "scope-attr-valid",
"selector": "td[scope], th[scope]",
"enabled": true,
"tags": [
"cat.tables",
"best-practice"
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/skip-link-matches.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const href = node.getAttribute('href');
return (href[0] === '#' && href.length > 1);
7 changes: 3 additions & 4 deletions lib/rules/skip-link.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
{
"id": "skip-link",
"selector": "a[href]",
"pageLevel": true,
"enabled": false,
"matches": "skip-link-matches.js",
"tags": [
"cat.keyboard",
"best-practice"
],
"metadata": {
"description": "Ensures the first link on the page is a skip link",
"help": "The page should have a skip link as its first link"
"description": "Ensure all skip links have a focusable target",
"help": "The skip-link target should exist and be focusable"
},
"all": [],
"any": [
Expand Down
27 changes: 0 additions & 27 deletions test/checks/navigation/href-no-hash.js

This file was deleted.

27 changes: 18 additions & 9 deletions test/checks/navigation/skip-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,29 @@ describe('skip-link', function () {
assert.isFalse(checks['skip-link'].evaluate(node));
});

it('should return false if the href points to a non-focusable element', function () {
fixture.innerHTML = '<a href="#mainheader">Click Here</a><h1 id="mainheader">Introduction</h1>';
it('should return true if the href points to an element with an ID', function () {
fixture.innerHTML = '<a href="#target">Click Here</a><h1 id="target">Introduction</h1>';
var node = fixture.querySelector('a');
assert.isFalse(checks['skip-link'].evaluate(node));
assert.isTrue(checks['skip-link'].evaluate(node));
});

it('should return true if the href points to an element with an name', function () {
fixture.innerHTML = '<a href="#target">Click Here</a><a name="target"></a>';
var node = fixture.querySelector('a');
assert.isTrue(checks['skip-link'].evaluate(node));
});

it('should return first result of an array', function () {
var results = [1, 2, 3];
assert.equal(checks['skip-link'].after(results), 1);
it('should return undefined if the target has display:none', function () {
fixture.innerHTML = '<a href="#target">Click Here</a>' +
'<h1 id="target" style="display:none">Introduction</h1>';
var node = fixture.querySelector('a');
assert.isUndefined(checks['skip-link'].evaluate(node));
});

it('should return true if the href points to a focusable element', function () {
fixture.innerHTML = '<a href="#mainheader">Click Here</a><h1 id="mainheader" tabindex="0">Introduction</h1>';
it('should return undefined if the target has aria-hidden=true', function () {
fixture.innerHTML = '<a href="#target">Click Here</a>' +
'<h1 id="target" aria-hidden="true">Introduction</h1>';
var node = fixture.querySelector('a');
assert.isTrue(checks['skip-link'].evaluate(node));
assert.isUndefined(checks['skip-link'].evaluate(node));
});
});
23 changes: 0 additions & 23 deletions test/integration/full/skip-link/skip-link-fail.html

This file was deleted.

27 changes: 0 additions & 27 deletions test/integration/full/skip-link/skip-link-fail.js

This file was deleted.

24 changes: 0 additions & 24 deletions test/integration/full/skip-link/skip-link-pass.html

This file was deleted.

27 changes: 0 additions & 27 deletions test/integration/full/skip-link/skip-link-pass.js

This file was deleted.

6 changes: 0 additions & 6 deletions test/integration/rules/href-no-hash/href-no-hash.html

This file was deleted.

6 changes: 0 additions & 6 deletions test/integration/rules/href-no-hash/href-no-hash.json

This file was deleted.

14 changes: 14 additions & 0 deletions test/integration/rules/skip-link/skip-link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

<a href="foo#bar" id="ignore1">link</a>
<a href="#" id="ignore2">link</a>

<div id="pass1-tgt"></div>
<a href="#pass1-tgt" id="pass1">Link</a>

<a name="pass2-tgt"></a>
<a href="#pass2-tgt" id="pass2">Link</a>

<div id="canttell1-tgt" style="display:none"></div>
<a href="#canttell1-tgt" id="canttell1">Link</a>

<a href="#fail1-tgt" id="fail1">bad link 1</a>
6 changes: 6 additions & 0 deletions test/integration/rules/skip-link/skip-link.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"rule": "skip-link",
"violations": [["#fail1"]],
"incomplete": [["#canttell1"]],
"passes": [["#pass1"], ["#pass2"]]
}