axe-core 2.4.1 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +70 -0
- package/CONTRIBUTING.md +1 -1
- package/appveyor.yml +21 -0
- package/axe.d.ts +1 -1
- package/axe.js +489 -222
- package/axe.min.js +6 -6
- package/bower.json +1 -1
- package/build/sri-update.js +10 -0
- package/build/utils/postinstall.js +3 -3
- package/doc/API.md +16 -2
- package/doc/developer-guide.md +25 -0
- package/doc/examples/jasmine/package.json +1 -1
- package/doc/examples/jest+react/package.json +1 -1
- package/doc/examples/mocha/package.json +1 -1
- package/doc/examples/qunit/package.json +1 -1
- package/doc/examples/selenium/package.json +1 -1
- package/doc/projects.md +2 -1
- package/doc/rule-descriptions.md +2 -0
- package/doc/rule-development.md +56 -10
- package/lib/checks/aria/errormessage.js +25 -0
- package/lib/checks/aria/errormessage.json +11 -0
- package/lib/checks/aria/required-children.js +16 -7
- package/lib/checks/aria/valid-attr-value.js +8 -3
- package/lib/checks/color/color-contrast.js +2 -1
- package/lib/checks/color/color-contrast.json +3 -1
- package/lib/checks/keyboard/has-at-least-one-main-after.js +16 -0
- package/lib/checks/keyboard/has-at-least-one-main.js +3 -0
- package/lib/checks/keyboard/has-at-least-one-main.json +12 -0
- package/lib/checks/keyboard/has-no-more-than-one-main.js +2 -0
- package/lib/checks/keyboard/has-no-more-than-one-main.json +11 -0
- package/lib/checks/keyboard/main-is-top-level.js +15 -0
- package/lib/checks/keyboard/main-is-top-level.json +11 -0
- package/lib/checks/lists/dlitem.js +1 -1
- package/lib/checks/navigation/region.js +15 -4
- package/lib/checks/navigation/skip-link.js +2 -1
- package/lib/commons/aria/attributes.js +19 -7
- package/lib/commons/aria/index.js +26 -15
- package/lib/commons/aria/roles.js +39 -15
- package/lib/commons/color/contrast.js +29 -8
- package/lib/commons/color/element-is-distinct.js +17 -2
- package/lib/commons/color/get-background-color.js +111 -11
- package/lib/commons/color/get-foreground-color.js +5 -2
- package/lib/commons/color/incomplete-data.js +14 -2
- package/lib/commons/color/index.js +6 -0
- package/lib/commons/dom/elements-below-floating.js +3 -1
- package/lib/commons/dom/find-up.js +5 -3
- package/lib/commons/dom/get-element-by-reference.js +11 -2
- package/lib/commons/dom/get-element-coordinates.js +17 -16
- package/lib/commons/dom/get-scroll-offset.js +6 -3
- package/lib/commons/dom/get-viewport-size.js +6 -5
- package/lib/commons/dom/idrefs.js +8 -3
- package/lib/commons/dom/index.js +8 -1
- package/lib/commons/dom/is-focusable.js +28 -9
- package/lib/commons/dom/is-html5.js +11 -2
- package/lib/commons/dom/is-in-text-block.js +6 -2
- package/lib/commons/dom/is-node.js +11 -3
- package/lib/commons/dom/is-offscreen.js +10 -2
- package/lib/commons/dom/is-visible.js +9 -3
- package/lib/commons/dom/is-visual-content.js +8 -5
- package/lib/commons/dom/visually-contains.js +3 -0
- package/lib/commons/dom/visually-overlaps.js +3 -0
- package/lib/commons/index.js +8 -0
- package/lib/commons/table/get-all-cells.js +10 -1
- package/lib/commons/table/get-cell-position.js +7 -4
- package/lib/commons/table/get-headers.js +6 -3
- package/lib/commons/table/get-scope.js +8 -5
- package/lib/commons/table/index.js +8 -1
- package/lib/commons/table/is-column-header.js +8 -5
- package/lib/commons/table/is-data-cell.js +6 -3
- package/lib/commons/table/is-data-table.js +6 -3
- package/lib/commons/table/is-header.js +5 -2
- package/lib/commons/table/is-row-header.js +8 -5
- package/lib/commons/table/to-grid.js +5 -2
- package/lib/commons/table/traverse.js +9 -6
- package/lib/commons/text/accessible-text.js +12 -6
- package/lib/commons/text/index.js +9 -2
- package/lib/commons/text/sanitize.js +10 -1
- package/lib/commons/utils/index.js +9 -3
- package/lib/commons/utils/to-array.js +11 -2
- package/lib/commons/utils/token-list.js +10 -3
- package/lib/commons/utils/valid-langs.js +11 -3
- package/lib/core/base/audit.js +1 -1
- package/lib/core/public/load.js +1 -1
- package/lib/core/reporters/helpers/process-aggregate.js +32 -0
- package/lib/core/reporters/no-passes.js +3 -0
- package/lib/core/utils/{aggregateRule.js → aggregateNodeResults.js} +18 -13
- package/lib/core/utils/check-helper.js +1 -1
- package/lib/core/utils/contains.js +4 -1
- package/lib/core/utils/finalize-result.js +1 -1
- package/lib/core/utils/find-by.js +4 -1
- package/lib/core/utils/get-selector.js +9 -4
- package/lib/core/utils/index.js +8 -1
- package/lib/core/utils/is-hidden.js +4 -1
- package/lib/core/utils/is-xhtml.js +16 -0
- package/lib/core/utils/pollyfills.js +136 -128
- package/lib/core/utils/rule-should-run.js +1 -1
- package/lib/rules/aria-valid-attr-value.json +4 -3
- package/lib/rules/color-contrast-matches.js +1 -1
- package/lib/rules/landmark-main-is-top-level.json +16 -0
- package/lib/rules/landmark-one-main.json +17 -0
- package/lib/rules/th-has-data-cells.json +1 -1
- package/package.json +7 -4
- package/sri-history.json +20 -0
- package/test/checks/aria/allowed-attr.js +13 -1
- package/test/checks/aria/errormessage.js +49 -0
- package/test/checks/aria/required-children.js +34 -4
- package/test/checks/color/color-contrast.js +33 -2
- package/test/checks/index.html +9 -0
- package/test/checks/keyboard/has-at-least-one-main.js +68 -0
- package/test/checks/keyboard/has-no-more-than-one-main.js +34 -0
- package/test/checks/keyboard/main-is-top-level.js +58 -0
- package/test/commons/aria/attributes.js +29 -29
- package/test/commons/aria/roles.js +29 -29
- package/test/commons/color/contrast.js +8 -0
- package/test/commons/color/get-background-color.js +26 -0
- package/test/commons/dom/is-natively-focusable.js +138 -0
- package/test/commons/index.html +3 -0
- package/test/core/base/audit.js +48 -0
- package/test/core/base/check.js +1 -1
- package/test/core/index.html +11 -4
- package/test/core/public/run-rules.js +27 -1
- package/test/core/reporters/helpers/process-aggregate.js +290 -0
- package/test/core/utils/{aggregateRule.js → aggregateNodeResults.js} +10 -14
- package/test/core/utils/finalize-result.js +7 -7
- package/test/core/utils/get-selector.js +14 -0
- package/test/core/utils/is-xhtml.js +21 -0
- package/test/integration/full/async/async.html +29 -0
- package/test/integration/full/async/async.js +102 -0
- package/test/integration/full/definition-list/dlitem-xhtml.js +52 -0
- package/test/integration/full/definition-list/dlitem-xhtml.xhtml +30 -0
- package/test/integration/full/get-selector/get-selector.js +12 -0
- package/test/integration/full/get-selector/get-selector.xhtml +25 -0
- package/test/integration/full/is-xhtml/is-xhtml.js +9 -0
- package/test/integration/full/is-xhtml/is-xhtml.xhtml +24 -0
- package/test/integration/full/landmark-main-is-top-level/frames/level1-fail.html +17 -0
- package/test/integration/full/landmark-main-is-top-level/frames/level1.html +29 -0
- package/test/integration/full/landmark-main-is-top-level/frames/level2-a.html +15 -0
- package/test/integration/full/landmark-main-is-top-level/frames/level2.html +15 -0
- package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.html +29 -0
- package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.js +42 -0
- package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.html +42 -0
- package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.js +36 -0
- package/test/integration/full/landmark-one-main/frames/level1-fail.html +10 -0
- package/test/integration/full/landmark-one-main/frames/level1.html +12 -0
- package/test/integration/full/landmark-one-main/frames/level2-a.html +12 -0
- package/test/integration/full/landmark-one-main/frames/level2.html +10 -0
- package/test/integration/full/landmark-one-main/landmark-one-main-fail.html +24 -0
- package/test/integration/full/landmark-one-main/landmark-one-main-fail.js +46 -0
- package/test/integration/full/landmark-one-main/landmark-one-main-pass.html +24 -0
- package/test/integration/full/landmark-one-main/landmark-one-main-pass.js +55 -0
- package/test/integration/full/region/region-fail.html +3 -0
- package/test/integration/full/region/region-pass.html +10 -0
- package/test/integration/rules/aria-allowed-attr/failures.html +2 -0
- package/test/integration/rules/aria-allowed-attr/failures.json +2 -2
- package/test/integration/rules/aria-allowed-attr/passes.html +9 -3
- package/test/integration/rules/aria-allowed-attr/passes.json +3 -2
- package/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html +5 -0
- package/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json +3 -2
- package/test/integration/rules/color-contrast/color-contrast.html +0 -5
- package/test/integration/rules/color-contrast/color-contrast.json +0 -2
- package/test/integration/rules/index.html +1 -0
- package/test/rule-matches/color-contrast-matches.js +10 -0
- package/test/rule-matches/index.html +1 -0
- package/test/runner.tmpl +1 -0
- package/test/testutils.js +43 -0
- package/typings/axe-core/axe-core-tests.js +10 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
describe('dom.isNativelyFocusable', function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var fixture = document.getElementById('fixture');
|
|
5
|
+
|
|
6
|
+
afterEach(function () {
|
|
7
|
+
document.getElementById('fixture').innerHTML = '';
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
it('should return true for buttons with redundant tabindex', function () {
|
|
12
|
+
fixture.innerHTML = '<button tabindex="0" id="target"></button>';
|
|
13
|
+
var el = document.getElementById('target');
|
|
14
|
+
|
|
15
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
16
|
+
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should return true for buttons with tabindex -1', function () {
|
|
20
|
+
fixture.innerHTML = '<button tabindex="-1" id="target"></button>';
|
|
21
|
+
var el = document.getElementById('target');
|
|
22
|
+
|
|
23
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
24
|
+
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should return true for visible, enabled textareas', function () {
|
|
28
|
+
fixture.innerHTML = '<textarea id="target"></textarea>';
|
|
29
|
+
var el = document.getElementById('target');
|
|
30
|
+
|
|
31
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
32
|
+
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should return true for visible, enabled selects', function () {
|
|
36
|
+
fixture.innerHTML = '<select id="target"></select>';
|
|
37
|
+
var el = document.getElementById('target');
|
|
38
|
+
|
|
39
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
40
|
+
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return true for visible, enabled buttons', function () {
|
|
44
|
+
fixture.innerHTML = '<button id="target"></button>';
|
|
45
|
+
var el = document.getElementById('target');
|
|
46
|
+
|
|
47
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
48
|
+
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return true for visible, enabled, non-hidden inputs', function () {
|
|
52
|
+
fixture.innerHTML = '<input type="text" id="target">';
|
|
53
|
+
var el = document.getElementById('target');
|
|
54
|
+
|
|
55
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
56
|
+
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should return false for disabled elements', function () {
|
|
60
|
+
fixture.innerHTML = '<input type="text" id="target" disabled>';
|
|
61
|
+
var el = document.getElementById('target');
|
|
62
|
+
|
|
63
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
64
|
+
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should return false for hidden inputs', function () {
|
|
68
|
+
fixture.innerHTML = '<input type="hidden" id="target">';
|
|
69
|
+
var el = document.getElementById('target');
|
|
70
|
+
|
|
71
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
72
|
+
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should return false for non-visible elements', function () {
|
|
76
|
+
fixture.innerHTML = '<input type="text" id="target" style="display: none">';
|
|
77
|
+
var el = document.getElementById('target');
|
|
78
|
+
|
|
79
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
80
|
+
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should return true for an anchor with an href', function () {
|
|
84
|
+
fixture.innerHTML = '<a href="something.html" id="target"></a>';
|
|
85
|
+
var el = document.getElementById('target');
|
|
86
|
+
|
|
87
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
88
|
+
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should return false for an anchor with no href', function () {
|
|
92
|
+
fixture.innerHTML = '<a name="anchor" id="target"></a>';
|
|
93
|
+
var el = document.getElementById('target');
|
|
94
|
+
|
|
95
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
96
|
+
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should return false for a div with a tabindex with spaces', function () {
|
|
100
|
+
fixture.innerHTML = '<div id="target" tabindex=" 0 "></div>';
|
|
101
|
+
var el = document.getElementById('target');
|
|
102
|
+
|
|
103
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
104
|
+
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return false for a div with a tabindex', function () {
|
|
108
|
+
fixture.innerHTML = '<div id="target" tabindex="0"></div>';
|
|
109
|
+
var el = document.getElementById('target');
|
|
110
|
+
|
|
111
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
112
|
+
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should return false for a div with a non-numeric tabindex', function () {
|
|
116
|
+
fixture.innerHTML = '<div id="target" tabindex="x"></div>';
|
|
117
|
+
var el = document.getElementById('target');
|
|
118
|
+
|
|
119
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
120
|
+
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should return true for a details element', function () {
|
|
124
|
+
fixture.innerHTML = '<details id="target"><p>Detail</p></details>';
|
|
125
|
+
var el = document.getElementById('target');
|
|
126
|
+
|
|
127
|
+
assert.isTrue(axe.commons.dom.isNativelyFocusable(el));
|
|
128
|
+
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should return false for a div with no tabindex', function () {
|
|
132
|
+
fixture.innerHTML = '<div id="target"></div>';
|
|
133
|
+
var el = document.getElementById('target');
|
|
134
|
+
|
|
135
|
+
assert.isFalse(axe.commons.dom.isNativelyFocusable(el));
|
|
136
|
+
|
|
137
|
+
});
|
|
138
|
+
});
|
package/test/commons/index.html
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
<body>
|
|
30
30
|
<div id="mocha"></div>
|
|
31
31
|
<div id="fixture"></div>
|
|
32
|
+
<script src="/test/testutils.js"></script>
|
|
32
33
|
|
|
33
34
|
<script src="aria/attributes.js"></script>
|
|
34
35
|
|
|
@@ -66,6 +67,8 @@
|
|
|
66
67
|
|
|
67
68
|
<script src="dom/is-in-text-block.js"></script>
|
|
68
69
|
|
|
70
|
+
<script src="dom/is-natively-focusable.js"></script>
|
|
71
|
+
|
|
69
72
|
<script src="dom/is-node.js"></script>
|
|
70
73
|
|
|
71
74
|
<script src="dom/is-offscreen.js"></script>
|
package/test/core/base/audit.js
CHANGED
|
@@ -149,6 +149,54 @@ describe('Audit', function () {
|
|
|
149
149
|
'https://dequeuniversity.com/rules/thing/x.y/target2?application=axeAPI'
|
|
150
150
|
);
|
|
151
151
|
});
|
|
152
|
+
it('understands prerelease type version numbers', function () {
|
|
153
|
+
var tempVersion = axe.version;
|
|
154
|
+
var audit = new Audit();
|
|
155
|
+
audit.addRule({
|
|
156
|
+
id: 'target',
|
|
157
|
+
matches: 'function () {return "hello";}',
|
|
158
|
+
selector: 'bob'
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
axe.version = '3.2.1-alpha.0';
|
|
162
|
+
audit._constructHelpUrls();
|
|
163
|
+
|
|
164
|
+
axe.version = tempVersion;
|
|
165
|
+
assert.equal(audit.data.rules.target.helpUrl,
|
|
166
|
+
'https://dequeuniversity.com/rules/axe/3.2/target?application=axeAPI');
|
|
167
|
+
});
|
|
168
|
+
it('sets x.y as version for invalid versions', function () {
|
|
169
|
+
var tempVersion = axe.version;
|
|
170
|
+
var audit = new Audit();
|
|
171
|
+
audit.addRule({
|
|
172
|
+
id: 'target',
|
|
173
|
+
matches: 'function () {return "hello";}',
|
|
174
|
+
selector: 'bob'
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
axe.version = 'in-3.0-valid';
|
|
178
|
+
audit._constructHelpUrls();
|
|
179
|
+
|
|
180
|
+
axe.version = tempVersion;
|
|
181
|
+
assert.equal(audit.data.rules.target.helpUrl,
|
|
182
|
+
'https://dequeuniversity.com/rules/axe/x.y/target?application=axeAPI');
|
|
183
|
+
});
|
|
184
|
+
it('matches major release versions', function () {
|
|
185
|
+
var tempVersion = axe.version;
|
|
186
|
+
var audit = new Audit();
|
|
187
|
+
audit.addRule({
|
|
188
|
+
id: 'target',
|
|
189
|
+
matches: 'function () {return "hello";}',
|
|
190
|
+
selector: 'bob'
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
axe.version = '1.0.0';
|
|
194
|
+
audit._constructHelpUrls();
|
|
195
|
+
|
|
196
|
+
axe.version = tempVersion;
|
|
197
|
+
assert.equal(audit.data.rules.target.helpUrl,
|
|
198
|
+
'https://dequeuniversity.com/rules/axe/1.0/target?application=axeAPI');
|
|
199
|
+
});
|
|
152
200
|
});
|
|
153
201
|
|
|
154
202
|
describe('Audit#setBranding', function () {
|
package/test/core/base/check.js
CHANGED
package/test/core/index.html
CHANGED
|
@@ -78,9 +78,9 @@
|
|
|
78
78
|
|
|
79
79
|
<script src="/tmp/core/utils/aggregateChecks.js"></script>
|
|
80
80
|
|
|
81
|
-
<script src="/tmp/core/utils/
|
|
81
|
+
<script src="/tmp/core/utils/aggregateNodeResults.js"></script>
|
|
82
82
|
|
|
83
|
-
<script src="/tmp/core/utils/
|
|
83
|
+
<script src="/tmp/core/utils/aggregateResult.js"></script>
|
|
84
84
|
|
|
85
85
|
<script src="/tmp/core/utils/are-styles-set.js"></script>
|
|
86
86
|
|
|
@@ -118,6 +118,8 @@
|
|
|
118
118
|
|
|
119
119
|
<script src="/tmp/core/utils/is-hidden.js"></script>
|
|
120
120
|
|
|
121
|
+
<script src="/tmp/core/utils/is-xhtml.js"></script>
|
|
122
|
+
|
|
121
123
|
<script src="/tmp/core/utils/merge-results.js"></script>
|
|
122
124
|
|
|
123
125
|
<script src="/tmp/core/utils/node-sorter.js"></script>
|
|
@@ -149,6 +151,7 @@
|
|
|
149
151
|
<body>
|
|
150
152
|
<div id="mocha"></div>
|
|
151
153
|
<div id="fixture"></div>
|
|
154
|
+
<script src="/test/testutils.js"></script>
|
|
152
155
|
|
|
153
156
|
<script src="base/audit.js"></script>
|
|
154
157
|
|
|
@@ -194,6 +197,8 @@
|
|
|
194
197
|
|
|
195
198
|
<script src="reporters/helpers/incomplete-fallback-msg.js"></script>
|
|
196
199
|
|
|
200
|
+
<script src="reporters/helpers/process-aggregate.js"></script>
|
|
201
|
+
|
|
197
202
|
<script src="reporters/na.js"></script>
|
|
198
203
|
|
|
199
204
|
<script src="reporters/no-passes.js"></script>
|
|
@@ -208,9 +213,9 @@
|
|
|
208
213
|
|
|
209
214
|
<script src="utils/aggregateChecks.js"></script>
|
|
210
215
|
|
|
211
|
-
<script src="utils/
|
|
216
|
+
<script src="utils/aggregateNodeResults.js"></script>
|
|
212
217
|
|
|
213
|
-
<script src="utils/
|
|
218
|
+
<script src="utils/aggregateResult.js"></script>
|
|
214
219
|
|
|
215
220
|
<script src="utils/are-styles-set.js"></script>
|
|
216
221
|
|
|
@@ -248,6 +253,8 @@
|
|
|
248
253
|
|
|
249
254
|
<script src="utils/is-hidden.js"></script>
|
|
250
255
|
|
|
256
|
+
<script src="utils/is-xhtml.js"></script>
|
|
257
|
+
|
|
251
258
|
<script src="utils/merge-results.js"></script>
|
|
252
259
|
|
|
253
260
|
<script src="utils/node-sorter.js"></script>
|
|
@@ -67,7 +67,6 @@ describe('runRules', function () {
|
|
|
67
67
|
}
|
|
68
68
|
}], messages: {}});
|
|
69
69
|
|
|
70
|
-
|
|
71
70
|
var frame = document.createElement('iframe');
|
|
72
71
|
frame.src = '../mock/frames/frame-frame.html';
|
|
73
72
|
|
|
@@ -621,4 +620,31 @@ describe('runRules', function () {
|
|
|
621
620
|
});
|
|
622
621
|
fixture.appendChild(frame);
|
|
623
622
|
});
|
|
623
|
+
|
|
624
|
+
it('should not fail if `include` / `exclude` is overwritten', function (done) {
|
|
625
|
+
function invalid () {
|
|
626
|
+
throw new Error('nope!');
|
|
627
|
+
}
|
|
628
|
+
Array.prototype.include = invalid;
|
|
629
|
+
Array.prototype.exclude = invalid;
|
|
630
|
+
|
|
631
|
+
axe._load({ rules: [{
|
|
632
|
+
id: 'html',
|
|
633
|
+
selector: 'html',
|
|
634
|
+
any: ['html']
|
|
635
|
+
}], checks: [{
|
|
636
|
+
id: 'html',
|
|
637
|
+
evaluate: function () {
|
|
638
|
+
return true;
|
|
639
|
+
}
|
|
640
|
+
}], messages: {}});
|
|
641
|
+
|
|
642
|
+
runRules([document], {}, function (r) {
|
|
643
|
+
assert.lengthOf(r[0].passes, 1);
|
|
644
|
+
|
|
645
|
+
delete Array.prototype.include;
|
|
646
|
+
delete Array.prototype.exclude;
|
|
647
|
+
done();
|
|
648
|
+
}, isNotCalled);
|
|
649
|
+
});
|
|
624
650
|
});
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
|
|
2
|
+
describe('helpers.processAggregate', function () {
|
|
3
|
+
'use strict';
|
|
4
|
+
var results, options;
|
|
5
|
+
|
|
6
|
+
beforeEach(function () {
|
|
7
|
+
results = [{
|
|
8
|
+
id: 'passed-rule',
|
|
9
|
+
passes: [{
|
|
10
|
+
result: 'passed',
|
|
11
|
+
node: {
|
|
12
|
+
element: document.createElement('div'),
|
|
13
|
+
selector: 'header > .thing',
|
|
14
|
+
source: '<div class=\"thing\">Thing</div>',
|
|
15
|
+
xpath: '/header/div[@class="thing"]'
|
|
16
|
+
},
|
|
17
|
+
any: [{
|
|
18
|
+
id: 'passed-rule',
|
|
19
|
+
relatedNodes: [{
|
|
20
|
+
element: document.createElement('div'),
|
|
21
|
+
selector: 'footer > .thing',
|
|
22
|
+
source: '<div class=\"thing\">Thing</div>',
|
|
23
|
+
xpath: '/footer/div[@class="thing"]',
|
|
24
|
+
}]
|
|
25
|
+
}],
|
|
26
|
+
all: [],
|
|
27
|
+
none: []
|
|
28
|
+
}, {
|
|
29
|
+
result: 'passed',
|
|
30
|
+
node: {
|
|
31
|
+
element: document.createElement('div'),
|
|
32
|
+
selector: 'main > .thing',
|
|
33
|
+
source: '<div class=\"thing\">Thing</div>',
|
|
34
|
+
xpath: '/main/div[@class="thing"]'
|
|
35
|
+
},
|
|
36
|
+
any: [{
|
|
37
|
+
id: 'passed-rule',
|
|
38
|
+
relatedNodes: [{
|
|
39
|
+
element: document.createElement('div'),
|
|
40
|
+
selector: 'footer > .thing',
|
|
41
|
+
source: '<div class=\"thing\">Thing</div>',
|
|
42
|
+
xpath: '/footer/div[@class="thing"]',
|
|
43
|
+
}]
|
|
44
|
+
}],
|
|
45
|
+
all: [],
|
|
46
|
+
none: []
|
|
47
|
+
}],
|
|
48
|
+
inapplicable: [],
|
|
49
|
+
incomplete: [],
|
|
50
|
+
violations: []
|
|
51
|
+
}, {
|
|
52
|
+
id: 'failed-rule',
|
|
53
|
+
violations: [{
|
|
54
|
+
result: 'failed',
|
|
55
|
+
node: {
|
|
56
|
+
selector: '#dopel',
|
|
57
|
+
source: '<input id=\"dopel\"/>',
|
|
58
|
+
xpath: '/main/input[@id="dopel"]',
|
|
59
|
+
fromFrame: true
|
|
60
|
+
},
|
|
61
|
+
any: [{
|
|
62
|
+
id: 'failed-rule',
|
|
63
|
+
relatedNodes: [{
|
|
64
|
+
element: document.createElement('input'),
|
|
65
|
+
selector: '#dopel',
|
|
66
|
+
source: '<input id=\"dopel\"/>',
|
|
67
|
+
xpath: '/main/input[@id="dopel"]',
|
|
68
|
+
fromFrame: true
|
|
69
|
+
}]
|
|
70
|
+
}],
|
|
71
|
+
all: [],
|
|
72
|
+
none: []
|
|
73
|
+
}, {
|
|
74
|
+
result: 'failed',
|
|
75
|
+
node: {
|
|
76
|
+
selector: '#dopell',
|
|
77
|
+
source: '<input id=\"dopell\"/>',
|
|
78
|
+
xpath: '/header/input[@id="dopell"]',
|
|
79
|
+
fromFrame: true
|
|
80
|
+
},
|
|
81
|
+
any: [{
|
|
82
|
+
id: 'failed-rule',
|
|
83
|
+
relatedNodes: [{
|
|
84
|
+
element: document.createElement('input'),
|
|
85
|
+
selector: '#dopell',
|
|
86
|
+
source: '<input id=\"dopell\"/>',
|
|
87
|
+
xpath: '/header/input[@id="dopell"]',
|
|
88
|
+
fromFrame: true
|
|
89
|
+
}]
|
|
90
|
+
}],
|
|
91
|
+
all: [],
|
|
92
|
+
none: []
|
|
93
|
+
}],
|
|
94
|
+
inapplicable: [],
|
|
95
|
+
passes: [],
|
|
96
|
+
incomplete: []
|
|
97
|
+
}];
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should add a `timestamp` property to the `resultObject`', function () {
|
|
101
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
102
|
+
assert.isDefined(resultObject.timestamp);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should add a `url` property to the `resultObject`', function () {
|
|
106
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
107
|
+
assert.isDefined(resultObject.url);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should remove the `result` property from each node in each ruleResult', function () {
|
|
111
|
+
assert.isDefined(results.find(function (r) {
|
|
112
|
+
return r.id === 'passed-rule';
|
|
113
|
+
}).passes[0].result);
|
|
114
|
+
|
|
115
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
116
|
+
var ruleResult = resultObject.passes.find(function (r) {
|
|
117
|
+
return r.id === 'passed-rule';
|
|
118
|
+
});
|
|
119
|
+
assert.isUndefined(ruleResult.nodes[0].result);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should remove the `node` property from each node in each ruleResult', function () {
|
|
123
|
+
assert.isDefined(results.find(function (r) {
|
|
124
|
+
return r.id === 'passed-rule';
|
|
125
|
+
}).passes[0].node);
|
|
126
|
+
|
|
127
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
128
|
+
var ruleResult = resultObject.passes.find(function (r) {
|
|
129
|
+
return r.id === 'passed-rule';
|
|
130
|
+
});
|
|
131
|
+
assert.isUndefined(ruleResult.nodes[0].node);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe('`options` argument', function () {
|
|
135
|
+
|
|
136
|
+
describe('`resultTypes` option', function () {
|
|
137
|
+
|
|
138
|
+
it('should reduce the unwanted result types to 1 in the `resultObject`', function () {
|
|
139
|
+
var resultObject = helpers.processAggregate(results, { resultTypes: ['violations'] });
|
|
140
|
+
assert.isDefined(resultObject.passes);
|
|
141
|
+
assert.equal(resultObject.passes[0].nodes.length, 1);
|
|
142
|
+
assert.isDefined(resultObject.violations);
|
|
143
|
+
assert.equal(resultObject.violations[0].nodes.length, 2);
|
|
144
|
+
resultObject = helpers.processAggregate(results, { resultTypes: ['passes'] });
|
|
145
|
+
assert.equal(resultObject.passes[0].nodes.length, 2);
|
|
146
|
+
assert.equal(resultObject.violations[0].nodes.length, 1);
|
|
147
|
+
assert.isDefined(resultObject.incomplete);
|
|
148
|
+
assert.isDefined(resultObject.inapplicable);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('`elementRef` option', function () {
|
|
153
|
+
|
|
154
|
+
describe('when set to true', function () {
|
|
155
|
+
|
|
156
|
+
before(function () {
|
|
157
|
+
options = { elementRef: true };
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('when node\'s, or relatedNode\'s, `fromFrame` equals false', function () {
|
|
161
|
+
it('should add an `element` property to the subResult nodes or relatedNodes', function () {
|
|
162
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
163
|
+
assert.isDefined(resultObject.passes[0].nodes[0].element);
|
|
164
|
+
assert.isDefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].element);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('when node\'s, or relatedNode\'s, `fromFrame` equals true', function () {
|
|
169
|
+
it('should NOT add an `element` property to the subResult nodes or relatedNodes', function () {
|
|
170
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
171
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].element);
|
|
172
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].any[0].relatedNodes[0].element);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe('when set to false', function () {
|
|
178
|
+
|
|
179
|
+
before(function () {
|
|
180
|
+
options = { elementRef: false };
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should NOT add an `element` property to the subResult nodes or relatedNodes', function () {
|
|
184
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
185
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].element);
|
|
186
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].element);
|
|
187
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].element);
|
|
188
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].any[0].relatedNodes[0].element);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('when not set at all', function () {
|
|
193
|
+
|
|
194
|
+
it('should NOT add an `element` property to the subResult nodes or relatedNodes', function () {
|
|
195
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
196
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].element);
|
|
197
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].element);
|
|
198
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].element);
|
|
199
|
+
assert.isUndefined(resultObject.violations[0].nodes[0].any[0].relatedNodes[0].element);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe('`selectors` option', function () {
|
|
205
|
+
|
|
206
|
+
describe('when set to false', function () {
|
|
207
|
+
|
|
208
|
+
before(function () {
|
|
209
|
+
options = { selectors: false };
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe('when node\'s, or relatedNode\'s, `fromFrame` equals true', function () {
|
|
213
|
+
it('should add a `target` property to the subResult nodes or relatedNodes', function () {
|
|
214
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
215
|
+
assert.isDefined(resultObject.violations[0].nodes[0].target);
|
|
216
|
+
assert.isDefined(resultObject.violations[0].nodes[0].any[0].relatedNodes[0].target);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
describe('when node\'s, or relatedNode\'s, `fromFrame` equals false', function () {
|
|
221
|
+
it('should NOT add a `target` property to the subResult nodes or relatedNodes', function () {
|
|
222
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
223
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].target);
|
|
224
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].target);
|
|
225
|
+
});
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
describe('when set to true', function () {
|
|
230
|
+
|
|
231
|
+
before(function () {
|
|
232
|
+
options = { selectors: true };
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
it('should add a `target` property to the subResult nodes or relatedNodes', function () {
|
|
236
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
237
|
+
assert.isDefined(resultObject.passes[0].nodes[0].target);
|
|
238
|
+
assert.isDefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].target);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('when not set at all', function () {
|
|
243
|
+
|
|
244
|
+
it('should add a `target` property to the subResult nodes or relatedNodes', function () {
|
|
245
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
246
|
+
assert.isDefined(resultObject.passes[0].nodes[0].target);
|
|
247
|
+
assert.isDefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].target);
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe('`xpath` option', function () {
|
|
253
|
+
|
|
254
|
+
describe('when set to true', function () {
|
|
255
|
+
|
|
256
|
+
before(function () {
|
|
257
|
+
options = { xpath: true };
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should add an `xpath` property to the subResult nodes or relatedNodes', function () {
|
|
261
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
262
|
+
assert.isDefined(resultObject.passes[0].nodes[0].xpath);
|
|
263
|
+
assert.isDefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].xpath);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
describe('when set to false', function () {
|
|
268
|
+
|
|
269
|
+
before(function () {
|
|
270
|
+
options = { xpath: false };
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should NOT add an `xpath` property to the subResult nodes or relatedNodes', function () {
|
|
274
|
+
var resultObject = helpers.processAggregate(results, options);
|
|
275
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].xpath);
|
|
276
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].xpath);
|
|
277
|
+
});
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
describe('when not set at all', function () {
|
|
281
|
+
|
|
282
|
+
it('should NOT add an `xpath` property to the subResult nodes or relatedNodes', function () {
|
|
283
|
+
var resultObject = helpers.processAggregate(results, {});
|
|
284
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].xpath);
|
|
285
|
+
assert.isUndefined(resultObject.passes[0].nodes[0].any[0].relatedNodes[0].xpath);
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
describe('axe.utils.
|
|
1
|
+
describe('axe.utils.aggregateNodeResults', function() {
|
|
2
2
|
'use strict';
|
|
3
3
|
var FAIL = 'failed';
|
|
4
4
|
var PASS = 'passed';
|
|
@@ -38,20 +38,16 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
it('should be a function', function() {
|
|
41
|
-
assert.isFunction(axe.utils.
|
|
41
|
+
assert.isFunction(axe.utils.aggregateNodeResults);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it('Should be `inapplicable` when no results are given', function () {
|
|
45
|
-
var ruleResult = axe.utils.
|
|
46
|
-
{}, {}
|
|
47
|
-
));
|
|
48
|
-
|
|
45
|
+
var ruleResult = axe.utils.aggregateNodeResults([]);
|
|
49
46
|
assert.equal(ruleResult.result, INAPPLICABLE);
|
|
50
|
-
assert.lengthOf(ruleResult.inapplicable, 2);
|
|
51
47
|
});
|
|
52
48
|
|
|
53
49
|
it('should assign FAIL to ruleResult over PASS', function() {
|
|
54
|
-
var ruleResult = axe.utils.
|
|
50
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults(
|
|
55
51
|
{ all: false },
|
|
56
52
|
{ all: true },
|
|
57
53
|
{ all: true }
|
|
@@ -62,7 +58,7 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
62
58
|
});
|
|
63
59
|
|
|
64
60
|
it('should assign FAIL to ruleResult over CANTTELL', function() {
|
|
65
|
-
var ruleResult = axe.utils.
|
|
61
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults(
|
|
66
62
|
{ all: false },
|
|
67
63
|
{ all: 0 },
|
|
68
64
|
{ all: true }
|
|
@@ -74,7 +70,7 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
74
70
|
});
|
|
75
71
|
|
|
76
72
|
it('should assign PASS to ruleResult if there are only passing checks', function() {
|
|
77
|
-
var ruleResult = axe.utils.
|
|
73
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults(
|
|
78
74
|
{ all: true },
|
|
79
75
|
{ all: true },
|
|
80
76
|
{ all: true }
|
|
@@ -86,7 +82,7 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
86
82
|
});
|
|
87
83
|
|
|
88
84
|
it('should assign FAIL if there are no passing anys checks', function() {
|
|
89
|
-
var ruleResult = axe.utils.
|
|
85
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults(
|
|
90
86
|
{ any: false },
|
|
91
87
|
{ any: false },
|
|
92
88
|
{ any: false }
|
|
@@ -97,7 +93,7 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
97
93
|
});
|
|
98
94
|
|
|
99
95
|
it('should assign CANTTELL over PASS', function() {
|
|
100
|
-
var ruleResult = axe.utils.
|
|
96
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults(
|
|
101
97
|
{ all: true },
|
|
102
98
|
{ all: 0 },
|
|
103
99
|
{ all: 0 }
|
|
@@ -108,14 +104,14 @@ describe('axe.utils.aggregateRule', function() {
|
|
|
108
104
|
});
|
|
109
105
|
|
|
110
106
|
it('should provide impact on incomplete', function () {
|
|
111
|
-
var ruleResult = axe.utils.
|
|
107
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults({
|
|
112
108
|
none: { result: undefined, impact: 'serious' }
|
|
113
109
|
}));
|
|
114
110
|
assert.equal(ruleResult.impact, 'serious');
|
|
115
111
|
});
|
|
116
112
|
|
|
117
113
|
it('should raise the highest "raisedMetadata" on failing checks', function() {
|
|
118
|
-
var ruleResult = axe.utils.
|
|
114
|
+
var ruleResult = axe.utils.aggregateNodeResults( createTestResults({
|
|
119
115
|
none: { result: true, impact: 'moderate' },
|
|
120
116
|
any: { result: true, impact: 'minor' },
|
|
121
117
|
all: [
|