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.
Files changed (166) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/appveyor.yml +21 -0
  4. package/axe.d.ts +1 -1
  5. package/axe.js +489 -222
  6. package/axe.min.js +6 -6
  7. package/bower.json +1 -1
  8. package/build/sri-update.js +10 -0
  9. package/build/utils/postinstall.js +3 -3
  10. package/doc/API.md +16 -2
  11. package/doc/developer-guide.md +25 -0
  12. package/doc/examples/jasmine/package.json +1 -1
  13. package/doc/examples/jest+react/package.json +1 -1
  14. package/doc/examples/mocha/package.json +1 -1
  15. package/doc/examples/qunit/package.json +1 -1
  16. package/doc/examples/selenium/package.json +1 -1
  17. package/doc/projects.md +2 -1
  18. package/doc/rule-descriptions.md +2 -0
  19. package/doc/rule-development.md +56 -10
  20. package/lib/checks/aria/errormessage.js +25 -0
  21. package/lib/checks/aria/errormessage.json +11 -0
  22. package/lib/checks/aria/required-children.js +16 -7
  23. package/lib/checks/aria/valid-attr-value.js +8 -3
  24. package/lib/checks/color/color-contrast.js +2 -1
  25. package/lib/checks/color/color-contrast.json +3 -1
  26. package/lib/checks/keyboard/has-at-least-one-main-after.js +16 -0
  27. package/lib/checks/keyboard/has-at-least-one-main.js +3 -0
  28. package/lib/checks/keyboard/has-at-least-one-main.json +12 -0
  29. package/lib/checks/keyboard/has-no-more-than-one-main.js +2 -0
  30. package/lib/checks/keyboard/has-no-more-than-one-main.json +11 -0
  31. package/lib/checks/keyboard/main-is-top-level.js +15 -0
  32. package/lib/checks/keyboard/main-is-top-level.json +11 -0
  33. package/lib/checks/lists/dlitem.js +1 -1
  34. package/lib/checks/navigation/region.js +15 -4
  35. package/lib/checks/navigation/skip-link.js +2 -1
  36. package/lib/commons/aria/attributes.js +19 -7
  37. package/lib/commons/aria/index.js +26 -15
  38. package/lib/commons/aria/roles.js +39 -15
  39. package/lib/commons/color/contrast.js +29 -8
  40. package/lib/commons/color/element-is-distinct.js +17 -2
  41. package/lib/commons/color/get-background-color.js +111 -11
  42. package/lib/commons/color/get-foreground-color.js +5 -2
  43. package/lib/commons/color/incomplete-data.js +14 -2
  44. package/lib/commons/color/index.js +6 -0
  45. package/lib/commons/dom/elements-below-floating.js +3 -1
  46. package/lib/commons/dom/find-up.js +5 -3
  47. package/lib/commons/dom/get-element-by-reference.js +11 -2
  48. package/lib/commons/dom/get-element-coordinates.js +17 -16
  49. package/lib/commons/dom/get-scroll-offset.js +6 -3
  50. package/lib/commons/dom/get-viewport-size.js +6 -5
  51. package/lib/commons/dom/idrefs.js +8 -3
  52. package/lib/commons/dom/index.js +8 -1
  53. package/lib/commons/dom/is-focusable.js +28 -9
  54. package/lib/commons/dom/is-html5.js +11 -2
  55. package/lib/commons/dom/is-in-text-block.js +6 -2
  56. package/lib/commons/dom/is-node.js +11 -3
  57. package/lib/commons/dom/is-offscreen.js +10 -2
  58. package/lib/commons/dom/is-visible.js +9 -3
  59. package/lib/commons/dom/is-visual-content.js +8 -5
  60. package/lib/commons/dom/visually-contains.js +3 -0
  61. package/lib/commons/dom/visually-overlaps.js +3 -0
  62. package/lib/commons/index.js +8 -0
  63. package/lib/commons/table/get-all-cells.js +10 -1
  64. package/lib/commons/table/get-cell-position.js +7 -4
  65. package/lib/commons/table/get-headers.js +6 -3
  66. package/lib/commons/table/get-scope.js +8 -5
  67. package/lib/commons/table/index.js +8 -1
  68. package/lib/commons/table/is-column-header.js +8 -5
  69. package/lib/commons/table/is-data-cell.js +6 -3
  70. package/lib/commons/table/is-data-table.js +6 -3
  71. package/lib/commons/table/is-header.js +5 -2
  72. package/lib/commons/table/is-row-header.js +8 -5
  73. package/lib/commons/table/to-grid.js +5 -2
  74. package/lib/commons/table/traverse.js +9 -6
  75. package/lib/commons/text/accessible-text.js +12 -6
  76. package/lib/commons/text/index.js +9 -2
  77. package/lib/commons/text/sanitize.js +10 -1
  78. package/lib/commons/utils/index.js +9 -3
  79. package/lib/commons/utils/to-array.js +11 -2
  80. package/lib/commons/utils/token-list.js +10 -3
  81. package/lib/commons/utils/valid-langs.js +11 -3
  82. package/lib/core/base/audit.js +1 -1
  83. package/lib/core/public/load.js +1 -1
  84. package/lib/core/reporters/helpers/process-aggregate.js +32 -0
  85. package/lib/core/reporters/no-passes.js +3 -0
  86. package/lib/core/utils/{aggregateRule.js → aggregateNodeResults.js} +18 -13
  87. package/lib/core/utils/check-helper.js +1 -1
  88. package/lib/core/utils/contains.js +4 -1
  89. package/lib/core/utils/finalize-result.js +1 -1
  90. package/lib/core/utils/find-by.js +4 -1
  91. package/lib/core/utils/get-selector.js +9 -4
  92. package/lib/core/utils/index.js +8 -1
  93. package/lib/core/utils/is-hidden.js +4 -1
  94. package/lib/core/utils/is-xhtml.js +16 -0
  95. package/lib/core/utils/pollyfills.js +136 -128
  96. package/lib/core/utils/rule-should-run.js +1 -1
  97. package/lib/rules/aria-valid-attr-value.json +4 -3
  98. package/lib/rules/color-contrast-matches.js +1 -1
  99. package/lib/rules/landmark-main-is-top-level.json +16 -0
  100. package/lib/rules/landmark-one-main.json +17 -0
  101. package/lib/rules/th-has-data-cells.json +1 -1
  102. package/package.json +7 -4
  103. package/sri-history.json +20 -0
  104. package/test/checks/aria/allowed-attr.js +13 -1
  105. package/test/checks/aria/errormessage.js +49 -0
  106. package/test/checks/aria/required-children.js +34 -4
  107. package/test/checks/color/color-contrast.js +33 -2
  108. package/test/checks/index.html +9 -0
  109. package/test/checks/keyboard/has-at-least-one-main.js +68 -0
  110. package/test/checks/keyboard/has-no-more-than-one-main.js +34 -0
  111. package/test/checks/keyboard/main-is-top-level.js +58 -0
  112. package/test/commons/aria/attributes.js +29 -29
  113. package/test/commons/aria/roles.js +29 -29
  114. package/test/commons/color/contrast.js +8 -0
  115. package/test/commons/color/get-background-color.js +26 -0
  116. package/test/commons/dom/is-natively-focusable.js +138 -0
  117. package/test/commons/index.html +3 -0
  118. package/test/core/base/audit.js +48 -0
  119. package/test/core/base/check.js +1 -1
  120. package/test/core/index.html +11 -4
  121. package/test/core/public/run-rules.js +27 -1
  122. package/test/core/reporters/helpers/process-aggregate.js +290 -0
  123. package/test/core/utils/{aggregateRule.js → aggregateNodeResults.js} +10 -14
  124. package/test/core/utils/finalize-result.js +7 -7
  125. package/test/core/utils/get-selector.js +14 -0
  126. package/test/core/utils/is-xhtml.js +21 -0
  127. package/test/integration/full/async/async.html +29 -0
  128. package/test/integration/full/async/async.js +102 -0
  129. package/test/integration/full/definition-list/dlitem-xhtml.js +52 -0
  130. package/test/integration/full/definition-list/dlitem-xhtml.xhtml +30 -0
  131. package/test/integration/full/get-selector/get-selector.js +12 -0
  132. package/test/integration/full/get-selector/get-selector.xhtml +25 -0
  133. package/test/integration/full/is-xhtml/is-xhtml.js +9 -0
  134. package/test/integration/full/is-xhtml/is-xhtml.xhtml +24 -0
  135. package/test/integration/full/landmark-main-is-top-level/frames/level1-fail.html +17 -0
  136. package/test/integration/full/landmark-main-is-top-level/frames/level1.html +29 -0
  137. package/test/integration/full/landmark-main-is-top-level/frames/level2-a.html +15 -0
  138. package/test/integration/full/landmark-main-is-top-level/frames/level2.html +15 -0
  139. package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.html +29 -0
  140. package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-fail.js +42 -0
  141. package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.html +42 -0
  142. package/test/integration/full/landmark-main-is-top-level/landmark-main-is-top-level-pass.js +36 -0
  143. package/test/integration/full/landmark-one-main/frames/level1-fail.html +10 -0
  144. package/test/integration/full/landmark-one-main/frames/level1.html +12 -0
  145. package/test/integration/full/landmark-one-main/frames/level2-a.html +12 -0
  146. package/test/integration/full/landmark-one-main/frames/level2.html +10 -0
  147. package/test/integration/full/landmark-one-main/landmark-one-main-fail.html +24 -0
  148. package/test/integration/full/landmark-one-main/landmark-one-main-fail.js +46 -0
  149. package/test/integration/full/landmark-one-main/landmark-one-main-pass.html +24 -0
  150. package/test/integration/full/landmark-one-main/landmark-one-main-pass.js +55 -0
  151. package/test/integration/full/region/region-fail.html +3 -0
  152. package/test/integration/full/region/region-pass.html +10 -0
  153. package/test/integration/rules/aria-allowed-attr/failures.html +2 -0
  154. package/test/integration/rules/aria-allowed-attr/failures.json +2 -2
  155. package/test/integration/rules/aria-allowed-attr/passes.html +9 -3
  156. package/test/integration/rules/aria-allowed-attr/passes.json +3 -2
  157. package/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.html +5 -0
  158. package/test/integration/rules/aria-valid-attr-value/aria-valid-attr-value.json +3 -2
  159. package/test/integration/rules/color-contrast/color-contrast.html +0 -5
  160. package/test/integration/rules/color-contrast/color-contrast.json +0 -2
  161. package/test/integration/rules/index.html +1 -0
  162. package/test/rule-matches/color-contrast-matches.js +10 -0
  163. package/test/rule-matches/index.html +1 -0
  164. package/test/runner.tmpl +1 -0
  165. package/test/testutils.js +43 -0
  166. 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
+ });
@@ -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>
@@ -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 () {
@@ -193,7 +193,7 @@ describe('Check', function () {
193
193
  }
194
194
  }).run(fixture, {}, function (d) {
195
195
  assert.instanceOf(d, CheckResult);
196
- assert.deepEqual(d.value, data);
196
+ assert.deepEqual(d.result, data);
197
197
  done();
198
198
  });
199
199
 
@@ -78,9 +78,9 @@
78
78
 
79
79
  <script src="/tmp/core/utils/aggregateChecks.js"></script>
80
80
 
81
- <script src="/tmp/core/utils/aggregateResult.js"></script>
81
+ <script src="/tmp/core/utils/aggregateNodeResults.js"></script>
82
82
 
83
- <script src="/tmp/core/utils/aggregateRule.js"></script>
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/aggregateResult.js"></script>
216
+ <script src="utils/aggregateNodeResults.js"></script>
212
217
 
213
- <script src="utils/aggregateRule.js"></script>
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.aggregateRule', function() {
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.aggregateRule);
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults(
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.aggregateRule( createTestResults({
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.aggregateRule( createTestResults({
114
+ var ruleResult = axe.utils.aggregateNodeResults( createTestResults({
119
115
  none: { result: true, impact: 'moderate' },
120
116
  any: { result: true, impact: 'minor' },
121
117
  all: [