testaro 27.0.0 → 28.0.0

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 (118) hide show
  1. package/CONTRIBUTING.md +3 -1
  2. package/README.md +14 -3
  3. package/package.json +2 -1
  4. package/procs/aslint.js +83 -0
  5. package/procs/nav.js +56 -14
  6. package/procs/standardize.js +36 -0
  7. package/run.js +35 -22
  8. package/tests/aslint.js +83 -0
  9. package/tests/axe.js +4 -0
  10. package/tests/qualWeb.js +6 -0
  11. package/aslint/LICENSE +0 -362
  12. package/aslint/README.md +0 -260
  13. package/aslint/app/rules/abstract-rule.ts +0 -83
  14. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.documentation.md +0 -36
  15. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.test.ts +0 -113
  16. package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.ts +0 -103
  17. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.documentation.md +0 -34
  18. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.test.ts +0 -82
  19. package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.ts +0 -44
  20. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.documentation.md +0 -40
  21. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.test.ts +0 -48
  22. package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.ts +0 -37
  23. package/aslint/app/rules/aslint/links-language-destination/links-language-destination.test.ts +0 -50
  24. package/aslint/app/rules/aslint/links-language-destination/links-language-destination.ts +0 -70
  25. package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.test.ts +0 -55
  26. package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.ts +0 -83
  27. package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.test.ts +0 -12
  28. package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.ts +0 -73
  29. package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.test.ts +0 -12
  30. package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.ts +0 -87
  31. package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.test.ts +0 -48
  32. package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.ts +0 -40
  33. package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.test.ts +0 -12
  34. package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.ts +0 -66
  35. package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.test.ts +0 -12
  36. package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.ts +0 -134
  37. package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.test.ts +0 -12
  38. package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.ts +0 -90
  39. package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.test.ts +0 -12
  40. package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.ts +0 -48
  41. package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.test.ts +0 -12
  42. package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.ts +0 -148
  43. package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.test.ts +0 -12
  44. package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.ts +0 -66
  45. package/aslint/app/rules/aslint/outline-zero/outline-zero.test.ts +0 -12
  46. package/aslint/app/rules/aslint/outline-zero/outline-zero.ts +0 -85
  47. package/aslint/app/rules/aslint/overlay/overlay.test.ts +0 -122
  48. package/aslint/app/rules/aslint/overlay/overlay.ts +0 -141
  49. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.documentation.md +0 -49
  50. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.test.ts +0 -91
  51. package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.ts +0 -62
  52. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.documentation.md +0 -44
  53. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.test.ts +0 -111
  54. package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.ts +0 -120
  55. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.documentation.md +0 -45
  56. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.test.ts +0 -63
  57. package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.ts +0 -44
  58. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.documentation.md +0 -55
  59. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.test.ts +0 -80
  60. package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.ts +0 -58
  61. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.documentation.md +0 -48
  62. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.test.ts +0 -52
  63. package/aslint/app/rules/aslint/redundant/flash-content/flash-content.ts +0 -32
  64. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.documentation.md +0 -44
  65. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.test.ts +0 -12
  66. package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.ts +0 -83
  67. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.documentation.md +0 -46
  68. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.test.ts +0 -46
  69. package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.ts +0 -36
  70. package/aslint/app/rules/aslint/role-application/role-application.test.ts +0 -48
  71. package/aslint/app/rules/aslint/role-application/role-application.ts +0 -38
  72. package/aslint/app/rules/aslint/rtl-content/rtl-content.test.ts +0 -12
  73. package/aslint/app/rules/aslint/rtl-content/rtl-content.ts +0 -75
  74. package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.test.ts +0 -12
  75. package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.ts +0 -48
  76. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.test.ts +0 -73
  77. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.ts +0 -34
  78. package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden.documentation.md +0 -32
  79. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.docmentation.md +0 -48
  80. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.test.ts +0 -67
  81. package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.ts +0 -63
  82. package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.test.ts +0 -12
  83. package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.ts +0 -63
  84. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.documentation.md +0 -65
  85. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.test.ts +0 -53
  86. package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.ts +0 -47
  87. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.documentation.md +0 -57
  88. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.test.ts +0 -52
  89. package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.ts +0 -63
  90. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.documentation.md +0 -39
  91. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.test.ts +0 -66
  92. package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.ts +0 -37
  93. package/aslint/utils/aria.test.ts +0 -12
  94. package/aslint/utils/aria.ts +0 -120
  95. package/aslint/utils/async.test.ts +0 -25
  96. package/aslint/utils/async.ts +0 -22
  97. package/aslint/utils/common.test.ts +0 -239
  98. package/aslint/utils/common.ts +0 -168
  99. package/aslint/utils/console.test.ts +0 -85
  100. package/aslint/utils/console.ts +0 -89
  101. package/aslint/utils/css.test.ts +0 -153
  102. package/aslint/utils/css.ts +0 -191
  103. package/aslint/utils/dom.test.ts +0 -627
  104. package/aslint/utils/dom.ts +0 -1051
  105. package/aslint/utils/env.test.ts +0 -14
  106. package/aslint/utils/env.ts +0 -8
  107. package/aslint/utils/func.test.ts +0 -160
  108. package/aslint/utils/func.ts +0 -70
  109. package/aslint/utils/global.test.ts +0 -12
  110. package/aslint/utils/global.ts +0 -25
  111. package/aslint/utils/object.test.ts +0 -524
  112. package/aslint/utils/object.ts +0 -278
  113. package/aslint/utils/report.test.ts +0 -56
  114. package/aslint/utils/report.ts +0 -36
  115. package/aslint/utils/text.test.ts +0 -270
  116. package/aslint/utils/text.ts +0 -165
  117. package/aslint/utils/time.test.ts +0 -43
  118. package/aslint/utils/time.ts +0 -33
@@ -1,627 +0,0 @@
1
- import { DomUtility } from './dom';
2
-
3
- describe('Utils', () => {
4
-
5
- describe('DomUtility', () => {
6
-
7
- let fakeDom: HTMLDivElement;
8
-
9
- beforeEach(() => {
10
- fakeDom = document.createElement('div');
11
- fakeDom.id = 'fakedom';
12
- document.body.appendChild(fakeDom);
13
- });
14
-
15
- afterEach(() => {
16
- DomUtility.remove(document.getElementById('fakedom'));
17
- fakeDom = undefined;
18
- });
19
-
20
- describe('#getRootElement', () => {
21
-
22
- it('should return <html> element', () => {
23
- const root = DomUtility.getRootElement();
24
-
25
- expect(root.nodeName.toLowerCase()).toBe('html');
26
- });
27
-
28
- });
29
-
30
- describe('#getBodyElement', () => {
31
-
32
- it('should return <body> element', () => {
33
- const root = DomUtility.getBodyElement() as HTMLElement;
34
-
35
- expect(root.nodeName.toLowerCase()).toBe('body');
36
- });
37
-
38
- });
39
-
40
- describe('#getTextFromDescendantContent', () => {
41
-
42
- it('should get all text nodes data from descendant content (text contains no spaces)', () => {
43
-
44
- const el = document.createElement('div');
45
-
46
- el.innerHTML = 'This<p>hello</p>should<span>test</span>be only taken.';
47
-
48
- expect(el.childNodes.length).toBe(5);
49
- expect(DomUtility.getTextFromDescendantContent(el)).toBe('Thisshouldbe only taken.');
50
- });
51
-
52
- it('should get all text nodes data from descendant content (text contains spaces)', () => {
53
-
54
- const el = document.createElement('div');
55
-
56
- el.innerHTML = 'This <p>hello</p>should<span>test</span> be only taken.';
57
-
58
- expect(el.childNodes.length).toBe(5);
59
- expect(DomUtility.getTextFromDescendantContent(el)).toBe('This should be only taken.');
60
- });
61
-
62
- });
63
-
64
- describe('#isVisibleForAssistiveTechnologies', () => {
65
-
66
- it('should return false if passed non-html argument', () => {
67
- expect(DomUtility.isVisibleForAssistiveTechnologies({} as HTMLElement)).toBeFalsy();
68
- });
69
-
70
- it('should return true if node has defined aria-hidden="false" and class .visuallyhidden', () => {
71
- fakeDom.innerHTML = '<p aria-hidden="false">Test</p>';
72
- const el = fakeDom.querySelector('p');
73
-
74
- el.style.cssText = 'position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px);';
75
-
76
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeTruthy();
77
- });
78
-
79
- it('should return true if node has defined aria-hidden="false" and class .sr-only (Bootstrap)', () => {
80
- fakeDom.innerHTML = '<p aria-hidden="false">Test</p>';
81
- const el = fakeDom.querySelector('p');
82
-
83
- el.style.cssText = 'position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0;';
84
-
85
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeTruthy();
86
- });
87
-
88
- it('should return true if node has defined aria-hidden="false"', () => {
89
- fakeDom.innerHTML = '<p aria-hidden="false">Test</p>';
90
- const el = fakeDom.querySelector('p');
91
-
92
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeTruthy();
93
- });
94
-
95
- it('should return false if node has defined aria-hidden="true"', () => {
96
- fakeDom.innerHTML = '<p aria-hidden="true">Test</p>';
97
-
98
- const el = fakeDom.querySelector('p');
99
-
100
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeFalsy();
101
- });
102
-
103
- it('should return true if node has defined non-empty aria-label', () => {
104
- fakeDom.innerHTML = '<p aria-label="This is test">Test</p>';
105
-
106
- const el = fakeDom.querySelector('p');
107
-
108
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeTruthy();
109
- });
110
-
111
- it('should return true if node has defined aria-labelledby and destination defined in aria-labelledby exists', () => {
112
- fakeDom.innerHTML = '<p aria-labelledby="test">Test</p><span id="test"></span>';
113
-
114
- const el = fakeDom.querySelector('p');
115
-
116
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeTruthy();
117
- });
118
-
119
- it('should return false if node has defined aria-labelledby and destination defined in aria-labelledby does not exists', () => {
120
- fakeDom.innerHTML = '<p aria-labelledby="test">Test</p>';
121
-
122
- const el = fakeDom.querySelector('p');
123
-
124
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeFalsy();
125
- });
126
-
127
- it('should return false if node has defined display: none;', () => {
128
- fakeDom.innerHTML = '<p>Test</p>';
129
-
130
- const el = fakeDom.querySelector('p');
131
-
132
- el.style.cssText = 'display: none;';
133
-
134
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeFalsy();
135
- });
136
-
137
- it('should return false if node has defined visibility: hidden;', () => {
138
- fakeDom.innerHTML = '<p>Test</p>';
139
- const el = fakeDom.querySelector('p');
140
-
141
- el.style.cssText = 'visibility: hidden;';
142
-
143
- expect(DomUtility.isVisibleForAssistiveTechnologies(el)).toBeFalsy();
144
- });
145
-
146
- });
147
-
148
- describe('#isEmptyElement', () => {
149
-
150
- it('should determine that element is empty (does not contains any nodes, except comment nodes)', () => {
151
-
152
- fakeDom.innerHTML = '<p></p>';
153
- expect(DomUtility.isEmptyElement(fakeDom.querySelector('p'))).toBeTruthy();
154
- });
155
-
156
- it('should determine that element contains only comments and therefore is empty', () => {
157
-
158
- fakeDom.innerHTML = '<p></p>';
159
-
160
- const p = fakeDom.querySelector('p');
161
-
162
- const commentNode: Comment = document.createComment('This is a comment');
163
-
164
- p.appendChild(commentNode);
165
-
166
- expect(DomUtility.isEmptyElement(p)).toBeTruthy();
167
- });
168
-
169
- it('should determine that element contains content (including whitespaces)', () => {
170
-
171
- fakeDom.innerHTML = '<p> </p>';
172
- expect(DomUtility.isEmptyElement(fakeDom.querySelector('p'))).toBeFalsy();
173
-
174
- fakeDom.innerHTML = '<p> <span>test</span></p>';
175
- expect(DomUtility.isEmptyElement(fakeDom.querySelector('p'))).toBeFalsy();
176
- });
177
-
178
- });
179
-
180
- describe('#getParentElement', () => {
181
- it('should return node if founded parent element', () => {
182
- fakeDom.innerHTML = '<p><span><em id="test"></em></span></p>';
183
- const p = fakeDom.querySelector('p');
184
-
185
- expect(DomUtility.getParentElement(fakeDom.querySelector('#test'), 'p')).toBe(p);
186
- });
187
-
188
- });
189
-
190
- describe('#getXPath', () => {
191
-
192
- it('should return correct xpath for svg', () => {
193
- fakeDom.innerHTML = '<div><div><div class="test"><svg xmlns="http://www.w3.org/2000/svg"></svg></div></div></div>';
194
-
195
- expect(DomUtility.getXPath(fakeDom.querySelector('svg'))).toBe(`.//html/body/div/div/div/div/*[name()='svg']`);
196
- });
197
-
198
- it('should return path .//html/body/div/div/div/div for specified node', () => {
199
-
200
- fakeDom.innerHTML = '<div><div><div class="test"><span><em id="test" class="test"></em></span></div></div></div>';
201
- expect(DomUtility.getXPath(fakeDom.querySelector('div.test'))).toBe('.//html/body/div/div/div/div');
202
- });
203
-
204
- it('should return path .//html/body/div/p/span/em for specified node', () => {
205
-
206
- fakeDom.innerHTML = '<p><span><em id="test"></em></span></p>';
207
- expect(DomUtility.getXPath(fakeDom.querySelector('#test'))).toBe('.//html/body/div/p/span/em');
208
- });
209
-
210
- it('should return path .//html/body/div/p[2]/span/em for specified node with duplicated id', () => {
211
-
212
- fakeDom.innerHTML = '<p><span><em id="test"></em></span></p><p><span><em id="test"></em></span></p>';
213
- expect(DomUtility.getXPath(fakeDom.querySelectorAll('#test')[1])).toBe('.//html/body/div/p[2]/span/em');
214
- });
215
-
216
- it('should return path .//html/body/div/p/span for specified node', () => {
217
-
218
- fakeDom.innerHTML = '<p><span><em id="test" class="test"></em></span></p>';
219
- expect(DomUtility.getXPath(fakeDom.querySelector('span'))).toBe('.//html/body/div/p/span');
220
- });
221
-
222
- it('should return path .//html/body/div/p for specified node', () => {
223
-
224
- fakeDom.innerHTML = '<p><span><em id="test" class="test"></em></span></p>';
225
- expect(DomUtility.getXPath(fakeDom.querySelector('p'))).toBe('.//html/body/div/p');
226
- });
227
-
228
- it('should return path to text node for specified text node', () => {
229
-
230
- fakeDom.innerHTML = '<p><span><em id="test" class="test">test</em></span></p>';
231
- expect(DomUtility.getXPath(fakeDom.querySelector('em').firstChild as Element)).toBe('.//html/body/div/p/span/em/text()');
232
- });
233
-
234
- it('should return path (including root) for specified node', () => {
235
-
236
- const temp = document.createElement('div'),
237
- temp2 = document.createElement('div');
238
-
239
- temp.innerHTML = '<div><div class="testelm"></div></div><div><p>test</p></div>';
240
- temp2.innerHTML = '<div><div class="testelm"></div></div><div><p>test</p></div>';
241
-
242
- DomUtility.remove(fakeDom);
243
-
244
- document.body.insertBefore(temp, document.body.firstChild);
245
- document.body.insertBefore(temp2, document.body.firstChild);
246
-
247
- expect(DomUtility.getXPath(document.querySelector('div.testelm'))).toBe('.//html/body/div[1]/div[1]/div');
248
- DomUtility.remove(temp);
249
- DomUtility.remove(temp2);
250
- });
251
-
252
- it('should return empty path for non-DOM object', () => {
253
- expect(DomUtility.getXPath(null)).toBe('');
254
- });
255
-
256
- });
257
-
258
- describe('#isElementVisible', () => {
259
-
260
- it('should return true if passed element is positioned inside visible area', () => {
261
- fakeDom.innerHTML = 'Test visible area';
262
-
263
- expect(DomUtility.isElementVisible(fakeDom)).toBeTruthy();
264
- });
265
-
266
- it('should return false if passed non-HTML element', () => {
267
- expect(DomUtility.isElementVisible(null)).toBeFalsy();
268
- // @ts-ignore
269
- expect(DomUtility.isElementVisible({})).toBeFalsy();
270
- // @ts-ignore
271
- expect(DomUtility.isElementVisible([])).toBeFalsy();
272
- // @ts-ignore
273
- expect(DomUtility.isElementVisible('')).toBeFalsy();
274
- });
275
-
276
- it('should return false if passed element with display: none;', () => {
277
-
278
- fakeDom.innerHTML = 'Test';
279
- fakeDom.style.cssText = 'display: none;';
280
-
281
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
282
- });
283
-
284
- it('should return false if passed element with opacity: 0;', () => {
285
-
286
- fakeDom.innerHTML = 'Test';
287
- fakeDom.style.cssText = 'opacity: 0;';
288
-
289
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
290
- });
291
-
292
- it('should return false if passed element with visibility: hidden;', () => {
293
-
294
- fakeDom.innerHTML = 'Test';
295
- fakeDom.style.cssText = 'visibility: hidden;';
296
-
297
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
298
- });
299
-
300
- it('should return false if passed element is visually hidden, but exposed to AT (here using Bootstrap sr-only)', () => {
301
-
302
- fakeDom.innerHTML = 'Test';
303
- fakeDom.style.cssText = 'position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0;';
304
-
305
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
306
- });
307
-
308
- it('should return false if passed element is visually hidden, but exposed to AT (here using CSS clip)', () => {
309
-
310
- fakeDom.innerHTML = 'Test';
311
- fakeDom.style.cssText = 'position: absolute !important; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px);';
312
-
313
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
314
- });
315
-
316
- it('should return false if passed element is positioned out of visible area using top: -10000px', () => {
317
- jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => {
318
- return {
319
- height: 1,
320
- left: 0,
321
- top: -10000,
322
- width: 1
323
- } as DOMRect;
324
- });
325
-
326
- fakeDom.innerHTML = 'Test';
327
- fakeDom.style.cssText = 'position: absolute; top: -10000px;';
328
-
329
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
330
-
331
- (Element.prototype.getBoundingClientRect as jest.Mock).mockReset();
332
- });
333
-
334
- it('should return false if passed element is positioned out of visible area using bottom: -10000px', () => {
335
- jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => {
336
- return {
337
- bottom: -10000,
338
- height: 1,
339
- left: 0,
340
- width: 1
341
- } as DOMRect;
342
- });
343
-
344
- fakeDom.innerHTML = 'Test';
345
- fakeDom.style.cssText = 'position: fixed; bottom: -10000px;';
346
-
347
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
348
-
349
- (Element.prototype.getBoundingClientRect as jest.Mock).mockReset();
350
- });
351
-
352
- it('should return false if passed element is positioned out of visible area using left: -10000px', () => {
353
- jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => {
354
- return {
355
- height: 1,
356
- left: -10000,
357
- top: 0,
358
- width: 1
359
- } as DOMRect;
360
- });
361
-
362
- fakeDom.innerHTML = 'Test';
363
- fakeDom.style.cssText = 'position: absolute; left: -10000px;';
364
-
365
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
366
-
367
- (Element.prototype.getBoundingClientRect as jest.Mock).mockReset();
368
- });
369
-
370
- it('should return false if passed element is positioned out of visible area using right: -10000px', () => {
371
- jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => {
372
- return {
373
- height: 1,
374
- right: -10000,
375
- top: 0,
376
- width: 1
377
- } as DOMRect;
378
- });
379
-
380
- fakeDom.innerHTML = 'Test';
381
- fakeDom.style.cssText = 'position: fixed; right: -10000px;';
382
-
383
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
384
-
385
- (Element.prototype.getBoundingClientRect as jest.Mock).mockReset();
386
- });
387
-
388
- it('should return false if passed element is visually hidden, but exposed to AT (here using text-indent)', () => {
389
-
390
- fakeDom.innerHTML = 'Test';
391
- fakeDom.style.cssText = 'position: relative; overflow: hidden; clip: rect(0 0 0 0); margin: -1px; padding: 0; border: 0; cursor: pointer; line-height: 2.5; font-size: 1.5em; border-radius: 40px !important; width: 29px !important; height: 29px; transition: 0.25s ease all; text-indent: -10000px !important;';
392
-
393
- expect(DomUtility.isElementVisible(fakeDom)).toBeFalsy();
394
- });
395
-
396
- });
397
-
398
- describe('#empty', () => {
399
-
400
- it('should remove whole content from given HTML element with parent node', () => {
401
-
402
- const el = document.createElement('div');
403
-
404
- el.innerHTML = '<p><span>123</span><br/></p>';
405
- expect(el.childNodes.length).toBe(1);
406
-
407
- const p = el.querySelector('p');
408
-
409
- DomUtility.empty(p);
410
-
411
- expect(p.childNodes.length).toBe(0);
412
- });
413
-
414
- it('should remove whole content from given HTML element without parent node', () => {
415
-
416
- const el = document.createElement('div');
417
-
418
- el.innerHTML = '<span>123</span><br/>';
419
- expect(el.childNodes.length).toBe(2);
420
-
421
- DomUtility.empty(el);
422
-
423
- expect(el.childNodes.length).toBe(0);
424
- });
425
-
426
- });
427
-
428
- describe('#remove', () => {
429
-
430
- it('should remove specified HTML element', () => {
431
-
432
- const el = document.createElement('div');
433
-
434
- el.innerHTML = '<span>123</span><br/>';
435
- expect(el.childNodes.length).toBe(2);
436
-
437
- DomUtility.remove(el.querySelector('span'));
438
-
439
- expect(el.childNodes.length).toBe(1);
440
- });
441
-
442
- });
443
-
444
- describe('#getHighestZindex', () => {
445
-
446
- it('should return highest z-index on the page', () => {
447
-
448
- const el = document.createElement('div');
449
-
450
- el.id = 'zindextest';
451
- el.innerHTML = '<span>123</span><br/>';
452
- el.style.cssText = 'z-index: 20; position: relative';
453
- document.body.appendChild(el);
454
-
455
- expect(DomUtility.getHighestZindex()).toBe(20);
456
-
457
- el.remove();
458
- });
459
-
460
- it('should return null when the highest z-index can not be determined', () => {
461
-
462
- const el = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
463
-
464
- el.id = 'zindextest';
465
- el.style.cssText = 'z-index: 20; position: relative';
466
- document.body.appendChild(el);
467
-
468
- expect(DomUtility.getHighestZindex()).toBe(20);
469
-
470
- el.remove();
471
- });
472
-
473
- });
474
-
475
- describe('#getIFrameDocument', () => {
476
-
477
- it('should return document object for a given iframe', () => {
478
-
479
- const iframe = document.createElement('iframe');
480
-
481
- document.documentElement.appendChild(iframe);
482
-
483
- expect(DomUtility.getIFrameDocument(iframe).nodeName).toBe('#document');
484
-
485
- iframe.remove();
486
- });
487
-
488
- });
489
-
490
- describe('#getNodeWithTextContent', () => {
491
-
492
- it('should return escaped text content for a given node', () => {
493
-
494
- const node = document.createElement('div');
495
-
496
- node.innerHTML = '<img src="" alt="alternate content"/><p>this is p</p>';
497
-
498
- document.documentElement.appendChild(node);
499
-
500
- expect(DomUtility.getNodeWithTextContent(node)).toBe('&lt;div&gt;this is p&lt;&#x2F;div&gt;');
501
-
502
- node.remove();
503
- });
504
-
505
- });
506
-
507
- describe('#getEscapedOuterHTML', () => {
508
-
509
- it('should return escaped outer HTML for a given node', () => {
510
-
511
- const node = document.createElement('div');
512
-
513
- node.innerHTML = '<a href="#" aria-hidden="true">Click here</a>';
514
-
515
- document.documentElement.appendChild(node);
516
-
517
- expect(DomUtility.getEscapedOuterHTML(node)).toBe('&lt;div&gt;&lt;&#x2F;div&gt;');
518
-
519
- node.remove();
520
- });
521
-
522
- });
523
-
524
- describe('#getEscapedOuterTruncatedHTML', () => {
525
-
526
- it('should return escaped outer HTML with truncated inner HTML in the middle for a given node', () => {
527
-
528
- const node = document.createElement('div');
529
-
530
- node.innerHTML = '<a href="#" aria-hidden="true">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</a>';
531
-
532
- document.documentElement.appendChild(node);
533
-
534
- expect(DomUtility.getEscapedOuterTruncatedHTML(node)).toBe('&lt;div&gt;&lt;a href&#x3D;&quot;#&quot; aria-hidden&#x3D;&quot;true&quot;&gt;Lorem Ipsum is simply dummy text of the [...] g software like Aldus PageMaker including versions of Lorem Ipsum.&lt;&#x2F;a&gt;&lt;&#x2F;div&gt;');
535
-
536
- node.remove();
537
- });
538
-
539
- });
540
-
541
- describe('#isHiddenForAT', () => {
542
-
543
- it('should indicate that the element is hidden from AT using aria-hidden="true", including parents', () => {
544
-
545
- fakeDom.innerHTML = '<div aria-hidden="true"><span>Test</span></div>';
546
- const el = fakeDom.querySelector('span');
547
-
548
- expect(DomUtility.isHiddenForAT(el)).toBe(true);
549
- });
550
-
551
- it('should indicate that the element is not hidden from AT using aria-hidden="true", including parents', () => {
552
-
553
- fakeDom.innerHTML = '<div><span>Test</span></div>';
554
- const el = fakeDom.querySelector('span');
555
-
556
- expect(DomUtility.isHiddenForAT(el)).toBe(false);
557
- });
558
-
559
- });
560
-
561
- describe('#isWhitespace', () => {
562
-
563
- it('should determine that the given string contains only whitespaces', () => {
564
-
565
- const node = document.createElement('div');
566
-
567
- node.innerHTML = ` `;
568
-
569
- expect(DomUtility.isWhitespace(node.textContent)).toBe(true);
570
- });
571
-
572
- });
573
-
574
- describe('#getElementAttribute', () => {
575
-
576
- it('should return null when a given attribute does not exists on specified Element', () => {
577
- const el: Element = document.createElement('span');
578
- const attribute: Attr | null = DomUtility.getElementAttribute(el, 'aria-hidden');
579
-
580
- expect(attribute).toBe(null);
581
- });
582
-
583
- it('should return Attribute object when a given attribute does exists on specified Element', () => {
584
- const el: Element = document.createElement('span');
585
-
586
- el.setAttribute('aria-hidden', 'true');
587
-
588
- const attribute: Attr | null = DomUtility.getElementAttribute(el, 'aria-hidden');
589
-
590
- expect(attribute instanceof Attr).toBe(true);
591
- expect(attribute.name).toBe('aria-hidden');
592
- expect(attribute.value).toBe('true');
593
- });
594
-
595
- });
596
-
597
- describe('#getHtmlInfo', () => {
598
-
599
- const html: string = '<div class="test"><p>Lorem ipsum...</p></div>';
600
-
601
- it('should return size and number of elements for a given root', () => {
602
- const root: HTMLElement = DomUtility.getBodyElement() as HTMLElement;
603
-
604
- root.innerHTML = html;
605
-
606
- expect(DomUtility.getHtmlInfo(root)).toEqual({
607
- htmlSize: html.length + '<body></body>'.length,
608
- nodesNum: 3
609
- });
610
- });
611
-
612
- it('should return size and number of elements for a given root excluding elements skipped by default', () => {
613
- const root: HTMLElement = DomUtility.getBodyElement() as HTMLElement;
614
- const dirtyHtml: string = '<div class="test"><p>Lorem ipsum...</p><script>alert(333);</script><style>p { font-weight: bold; }</style></div>';
615
-
616
- root.innerHTML = dirtyHtml;
617
-
618
- expect(DomUtility.getHtmlInfo(root)).toEqual({
619
- htmlSize: html.length + '<body></body>'.length,
620
- nodesNum: 3
621
- });
622
- });
623
-
624
- });
625
-
626
- });
627
- });