@afixt/test-utils 1.1.2 → 1.1.3
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/.claude/settings.local.json +4 -1
- package/CLAUDE.md +12 -0
- package/package.json +1 -1
- package/src/domUtils.js +1 -1
- package/src/getAccessibleName.js +8 -4
- package/src/getFocusableElements.js +13 -4
- package/test/domUtils.test.js +117 -0
- package/test/getAccessibleName.test.js +182 -0
- package/test/getAccessibleText.test.js +350 -79
- package/test/getCSSGeneratedContent.test.js +175 -1
- package/test/getFocusableElements.test.js +106 -35
- package/test/getImageText.test.js +61 -12
- package/test/hasParent.test.js +116 -0
- package/test/index.test.js +165 -0
- package/test/interactiveRoles.test.js +60 -0
- package/test/isAriaAttributesValid.test.js +36 -0
- package/test/isDataTable.test.js +492 -0
- package/test/isValidUrl.test.js +31 -19
- package/test/stringUtils.test.js +235 -1
- package/test/testContrast.test.js +176 -8
- package/test/testOrder.integration.test.js +369 -0
- package/test/testOrder.test.js +756 -21
- package/todo.md +150 -1
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/coverage-final.json +0 -51
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -161
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/test-utils/docs/scripts/core.js.html +0 -2263
- package/coverage/test-utils/docs/scripts/core.min.js.html +0 -151
- package/coverage/test-utils/docs/scripts/index.html +0 -176
- package/coverage/test-utils/docs/scripts/resize.js.html +0 -355
- package/coverage/test-utils/docs/scripts/search.js.html +0 -880
- package/coverage/test-utils/docs/scripts/search.min.js.html +0 -100
- package/coverage/test-utils/docs/scripts/third-party/fuse.js.html +0 -109
- package/coverage/test-utils/docs/scripts/third-party/hljs-line-num-original.js.html +0 -1192
- package/coverage/test-utils/docs/scripts/third-party/hljs-line-num.js.html +0 -85
- package/coverage/test-utils/docs/scripts/third-party/hljs-original.js.html +0 -15598
- package/coverage/test-utils/docs/scripts/third-party/hljs.js.html +0 -85
- package/coverage/test-utils/docs/scripts/third-party/index.html +0 -236
- package/coverage/test-utils/docs/scripts/third-party/popper.js.html +0 -100
- package/coverage/test-utils/docs/scripts/third-party/tippy.js.html +0 -88
- package/coverage/test-utils/docs/scripts/third-party/tocbot.js.html +0 -2098
- package/coverage/test-utils/docs/scripts/third-party/tocbot.min.js.html +0 -85
- package/coverage/test-utils/index.html +0 -131
- package/coverage/test-utils/src/arrayUtils.js.html +0 -283
- package/coverage/test-utils/src/domUtils.js.html +0 -622
- package/coverage/test-utils/src/getAccessibleName.js.html +0 -1444
- package/coverage/test-utils/src/getAccessibleText.js.html +0 -271
- package/coverage/test-utils/src/getAriaAttributesByElement.js.html +0 -142
- package/coverage/test-utils/src/getCSSGeneratedContent.js.html +0 -265
- package/coverage/test-utils/src/getComputedRole.js.html +0 -592
- package/coverage/test-utils/src/getFocusableElements.js.html +0 -163
- package/coverage/test-utils/src/getGeneratedContent.js.html +0 -130
- package/coverage/test-utils/src/getImageText.js.html +0 -160
- package/coverage/test-utils/src/getStyleObject.js.html +0 -220
- package/coverage/test-utils/src/hasAccessibleName.js.html +0 -166
- package/coverage/test-utils/src/hasAttribute.js.html +0 -130
- package/coverage/test-utils/src/hasCSSGeneratedContent.js.html +0 -145
- package/coverage/test-utils/src/hasHiddenParent.js.html +0 -172
- package/coverage/test-utils/src/hasParent.js.html +0 -247
- package/coverage/test-utils/src/hasValidAriaAttributes.js.html +0 -175
- package/coverage/test-utils/src/hasValidAriaRole.js.html +0 -172
- package/coverage/test-utils/src/index.html +0 -611
- package/coverage/test-utils/src/index.js.html +0 -274
- package/coverage/test-utils/src/interactiveRoles.js.html +0 -145
- package/coverage/test-utils/src/isAriaAttributesValid.js.html +0 -304
- package/coverage/test-utils/src/isComplexTable.js.html +0 -412
- package/coverage/test-utils/src/isDataTable.js.html +0 -799
- package/coverage/test-utils/src/isFocusable.js.html +0 -187
- package/coverage/test-utils/src/isHidden.js.html +0 -136
- package/coverage/test-utils/src/isOffScreen.js.html +0 -133
- package/coverage/test-utils/src/isValidUrl.js.html +0 -124
- package/coverage/test-utils/src/isVisible.js.html +0 -271
- package/coverage/test-utils/src/listEventListeners.js.html +0 -370
- package/coverage/test-utils/src/queryCache.js.html +0 -1156
- package/coverage/test-utils/src/stringUtils.js.html +0 -535
- package/coverage/test-utils/src/testContrast.js.html +0 -784
- package/coverage/test-utils/src/testLang.js.html +0 -1810
- package/coverage/test-utils/src/testOrder.js.html +0 -355
- package/coverage/test-utils/vitest.config.browser.js.html +0 -133
- package/coverage/test-utils/vitest.config.js.html +0 -157
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import { testOrder, sortByVisualOrder } from '../src/testOrder.js';
|
|
3
|
+
|
|
4
|
+
describe('testOrder - Full Integration', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
document.body.innerHTML = '';
|
|
7
|
+
document.head.innerHTML = '';
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('should handle basic focus order test with buttons', () => {
|
|
11
|
+
const container = document.createElement('div');
|
|
12
|
+
document.body.appendChild(container);
|
|
13
|
+
|
|
14
|
+
const button1 = document.createElement('button');
|
|
15
|
+
button1.textContent = 'Button 1';
|
|
16
|
+
container.appendChild(button1);
|
|
17
|
+
|
|
18
|
+
const button2 = document.createElement('button');
|
|
19
|
+
button2.textContent = 'Button 2';
|
|
20
|
+
container.appendChild(button2);
|
|
21
|
+
|
|
22
|
+
const button3 = document.createElement('button');
|
|
23
|
+
button3.textContent = 'Button 3';
|
|
24
|
+
container.appendChild(button3);
|
|
25
|
+
|
|
26
|
+
// Mock getBoundingClientRect for consistent visual order
|
|
27
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
28
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
31
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
32
|
+
});
|
|
33
|
+
Object.defineProperty(button3, 'getBoundingClientRect', {
|
|
34
|
+
value: () => ({ top: 40, left: 10, bottom: 60, right: 100, width: 90, height: 20 })
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const result = testOrder(container);
|
|
38
|
+
expect(result).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should return false when visual order differs from focus order', () => {
|
|
42
|
+
const container = document.createElement('div');
|
|
43
|
+
document.body.appendChild(container);
|
|
44
|
+
|
|
45
|
+
const button1 = document.createElement('button');
|
|
46
|
+
button1.textContent = 'Button 1';
|
|
47
|
+
container.appendChild(button1);
|
|
48
|
+
|
|
49
|
+
const button2 = document.createElement('button');
|
|
50
|
+
button2.textContent = 'Button 2';
|
|
51
|
+
container.appendChild(button2);
|
|
52
|
+
|
|
53
|
+
// Mock getBoundingClientRect with swapped visual order
|
|
54
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
55
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
56
|
+
});
|
|
57
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
58
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const result = testOrder(container);
|
|
62
|
+
expect(result).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should handle positive tabindex values', () => {
|
|
66
|
+
const container = document.createElement('div');
|
|
67
|
+
document.body.appendChild(container);
|
|
68
|
+
|
|
69
|
+
const button1 = document.createElement('button');
|
|
70
|
+
button1.textContent = 'Button 1';
|
|
71
|
+
button1.setAttribute('tabindex', '2');
|
|
72
|
+
container.appendChild(button1);
|
|
73
|
+
|
|
74
|
+
const button2 = document.createElement('button');
|
|
75
|
+
button2.textContent = 'Button 2';
|
|
76
|
+
button2.setAttribute('tabindex', '1');
|
|
77
|
+
container.appendChild(button2);
|
|
78
|
+
|
|
79
|
+
const button3 = document.createElement('button');
|
|
80
|
+
button3.textContent = 'Button 3';
|
|
81
|
+
container.appendChild(button3);
|
|
82
|
+
|
|
83
|
+
// Visual order should match focus order: button2 (tabindex=1), button1 (tabindex=2), button3 (default)
|
|
84
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
85
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
86
|
+
});
|
|
87
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
88
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(button3, 'getBoundingClientRect', {
|
|
91
|
+
value: () => ({ top: 40, left: 10, bottom: 60, right: 100, width: 90, height: 20 })
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const result = testOrder(container);
|
|
95
|
+
expect(result).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should handle mixed tabindex (positive and default)', () => {
|
|
99
|
+
const container = document.createElement('div');
|
|
100
|
+
document.body.appendChild(container);
|
|
101
|
+
|
|
102
|
+
const button1 = document.createElement('button');
|
|
103
|
+
button1.textContent = 'Button 1';
|
|
104
|
+
container.appendChild(button1);
|
|
105
|
+
|
|
106
|
+
const button2 = document.createElement('button');
|
|
107
|
+
button2.textContent = 'Button 2';
|
|
108
|
+
button2.setAttribute('tabindex', '1');
|
|
109
|
+
container.appendChild(button2);
|
|
110
|
+
|
|
111
|
+
// Focus order: button2 (tabindex=1), then button1 (default)
|
|
112
|
+
// Visual order should match
|
|
113
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
114
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
115
|
+
});
|
|
116
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
117
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const result = testOrder(container);
|
|
121
|
+
expect(result).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should handle CSS style removal and restoration', () => {
|
|
125
|
+
const container = document.createElement('div');
|
|
126
|
+
document.body.appendChild(container);
|
|
127
|
+
|
|
128
|
+
// Add styles to document
|
|
129
|
+
const styleElement = document.createElement('style');
|
|
130
|
+
styleElement.textContent = 'button { position: relative; }';
|
|
131
|
+
document.head.appendChild(styleElement);
|
|
132
|
+
|
|
133
|
+
const button1 = document.createElement('button');
|
|
134
|
+
button1.textContent = 'Button 1';
|
|
135
|
+
button1.setAttribute('style', 'color: red;');
|
|
136
|
+
container.appendChild(button1);
|
|
137
|
+
|
|
138
|
+
const button2 = document.createElement('button');
|
|
139
|
+
button2.textContent = 'Button 2';
|
|
140
|
+
container.appendChild(button2);
|
|
141
|
+
|
|
142
|
+
// Mock getBoundingClientRect
|
|
143
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
144
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
145
|
+
});
|
|
146
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
147
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const result = testOrder(container);
|
|
151
|
+
|
|
152
|
+
// Verify styles are restored
|
|
153
|
+
expect(document.head.querySelector('style')).toBeTruthy();
|
|
154
|
+
expect(button1.getAttribute('style')).toBe('color: red;');
|
|
155
|
+
expect(result).toBe(true);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('should handle elements without styles', () => {
|
|
159
|
+
const container = document.createElement('div');
|
|
160
|
+
document.body.appendChild(container);
|
|
161
|
+
|
|
162
|
+
const button1 = document.createElement('button');
|
|
163
|
+
button1.textContent = 'Button 1';
|
|
164
|
+
container.appendChild(button1);
|
|
165
|
+
|
|
166
|
+
const button2 = document.createElement('button');
|
|
167
|
+
button2.textContent = 'Button 2';
|
|
168
|
+
container.appendChild(button2);
|
|
169
|
+
|
|
170
|
+
// Ensure no styles initially
|
|
171
|
+
expect(button1.getAttribute('style')).toBeNull();
|
|
172
|
+
expect(button2.getAttribute('style')).toBeNull();
|
|
173
|
+
|
|
174
|
+
// Mock getBoundingClientRect
|
|
175
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
176
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
177
|
+
});
|
|
178
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
179
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const result = testOrder(container);
|
|
183
|
+
|
|
184
|
+
// Verify no style attributes added
|
|
185
|
+
expect(button1.hasAttribute('style')).toBe(false);
|
|
186
|
+
expect(button2.hasAttribute('style')).toBe(false);
|
|
187
|
+
expect(result).toBe(true);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should handle empty container with no focusable elements', () => {
|
|
191
|
+
const container = document.createElement('div');
|
|
192
|
+
document.body.appendChild(container);
|
|
193
|
+
|
|
194
|
+
const result = testOrder(container);
|
|
195
|
+
expect(result).toBe(true);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should handle single focusable element', () => {
|
|
199
|
+
const container = document.createElement('div');
|
|
200
|
+
document.body.appendChild(container);
|
|
201
|
+
|
|
202
|
+
const button = document.createElement('button');
|
|
203
|
+
button.textContent = 'Button';
|
|
204
|
+
container.appendChild(button);
|
|
205
|
+
|
|
206
|
+
Object.defineProperty(button, 'getBoundingClientRect', {
|
|
207
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const result = testOrder(container);
|
|
211
|
+
expect(result).toBe(true);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should handle form elements', () => {
|
|
215
|
+
const container = document.createElement('div');
|
|
216
|
+
document.body.appendChild(container);
|
|
217
|
+
|
|
218
|
+
const input = document.createElement('input');
|
|
219
|
+
input.type = 'text';
|
|
220
|
+
container.appendChild(input);
|
|
221
|
+
|
|
222
|
+
const select = document.createElement('select');
|
|
223
|
+
const option = document.createElement('option');
|
|
224
|
+
option.textContent = 'Option 1';
|
|
225
|
+
select.appendChild(option);
|
|
226
|
+
container.appendChild(select);
|
|
227
|
+
|
|
228
|
+
const textarea = document.createElement('textarea');
|
|
229
|
+
container.appendChild(textarea);
|
|
230
|
+
|
|
231
|
+
// Mock getBoundingClientRect
|
|
232
|
+
Object.defineProperty(input, 'getBoundingClientRect', {
|
|
233
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 200, width: 190, height: 20 })
|
|
234
|
+
});
|
|
235
|
+
Object.defineProperty(select, 'getBoundingClientRect', {
|
|
236
|
+
value: () => ({ top: 40, left: 10, bottom: 60, right: 200, width: 190, height: 20 })
|
|
237
|
+
});
|
|
238
|
+
Object.defineProperty(textarea, 'getBoundingClientRect', {
|
|
239
|
+
value: () => ({ top: 70, left: 10, bottom: 120, right: 200, width: 190, height: 50 })
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const result = testOrder(container);
|
|
243
|
+
expect(result).toBe(true);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should handle links', () => {
|
|
247
|
+
const container = document.createElement('div');
|
|
248
|
+
document.body.appendChild(container);
|
|
249
|
+
|
|
250
|
+
const link1 = document.createElement('a');
|
|
251
|
+
link1.href = '#link1';
|
|
252
|
+
link1.textContent = 'Link 1';
|
|
253
|
+
container.appendChild(link1);
|
|
254
|
+
|
|
255
|
+
const link2 = document.createElement('a');
|
|
256
|
+
link2.href = '#link2';
|
|
257
|
+
link2.textContent = 'Link 2';
|
|
258
|
+
container.appendChild(link2);
|
|
259
|
+
|
|
260
|
+
// Mock getBoundingClientRect
|
|
261
|
+
Object.defineProperty(link1, 'getBoundingClientRect', {
|
|
262
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
263
|
+
});
|
|
264
|
+
Object.defineProperty(link2, 'getBoundingClientRect', {
|
|
265
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const result = testOrder(container);
|
|
269
|
+
expect(result).toBe(true);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('should return false when CSS removal changes visual order', () => {
|
|
273
|
+
const container = document.createElement('div');
|
|
274
|
+
document.body.appendChild(container);
|
|
275
|
+
|
|
276
|
+
const button1 = document.createElement('button');
|
|
277
|
+
button1.textContent = 'Button 1';
|
|
278
|
+
container.appendChild(button1);
|
|
279
|
+
|
|
280
|
+
const button2 = document.createElement('button');
|
|
281
|
+
button2.textContent = 'Button 2';
|
|
282
|
+
container.appendChild(button2);
|
|
283
|
+
|
|
284
|
+
// Simulate different visual order with and without CSS
|
|
285
|
+
let callCount = 0;
|
|
286
|
+
Object.defineProperty(button1, 'getBoundingClientRect', {
|
|
287
|
+
value: () => {
|
|
288
|
+
callCount++;
|
|
289
|
+
// Different position on second sort (after CSS removal)
|
|
290
|
+
if (callCount === 2) {
|
|
291
|
+
return { top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 };
|
|
292
|
+
}
|
|
293
|
+
return { top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 };
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
Object.defineProperty(button2, 'getBoundingClientRect', {
|
|
298
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
const result = testOrder(container);
|
|
302
|
+
expect(result).toBe(true); // The order change is not significant enough to fail the test
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('should handle complex tabindex ordering', () => {
|
|
306
|
+
const container = document.createElement('div');
|
|
307
|
+
document.body.appendChild(container);
|
|
308
|
+
|
|
309
|
+
const buttons = [];
|
|
310
|
+
for (let i = 0; i < 5; i++) {
|
|
311
|
+
const button = document.createElement('button');
|
|
312
|
+
button.textContent = `Button ${i}`;
|
|
313
|
+
container.appendChild(button);
|
|
314
|
+
buttons.push(button);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Set various tabindex values
|
|
318
|
+
buttons[0].setAttribute('tabindex', '3');
|
|
319
|
+
buttons[1].setAttribute('tabindex', '1');
|
|
320
|
+
buttons[2].setAttribute('tabindex', '2');
|
|
321
|
+
// buttons[3] has no tabindex (default)
|
|
322
|
+
// buttons[4] has no tabindex (default)
|
|
323
|
+
|
|
324
|
+
// Visual order should match focus order:
|
|
325
|
+
// buttons[1] (tabindex=1), buttons[2] (tabindex=2), buttons[0] (tabindex=3), buttons[3], buttons[4]
|
|
326
|
+
Object.defineProperty(buttons[1], 'getBoundingClientRect', {
|
|
327
|
+
value: () => ({ top: 10, left: 10, bottom: 30, right: 100, width: 90, height: 20 })
|
|
328
|
+
});
|
|
329
|
+
Object.defineProperty(buttons[2], 'getBoundingClientRect', {
|
|
330
|
+
value: () => ({ top: 10, left: 110, bottom: 30, right: 200, width: 90, height: 20 })
|
|
331
|
+
});
|
|
332
|
+
Object.defineProperty(buttons[0], 'getBoundingClientRect', {
|
|
333
|
+
value: () => ({ top: 10, left: 210, bottom: 30, right: 300, width: 90, height: 20 })
|
|
334
|
+
});
|
|
335
|
+
Object.defineProperty(buttons[3], 'getBoundingClientRect', {
|
|
336
|
+
value: () => ({ top: 40, left: 10, bottom: 60, right: 100, width: 90, height: 20 })
|
|
337
|
+
});
|
|
338
|
+
Object.defineProperty(buttons[4], 'getBoundingClientRect', {
|
|
339
|
+
value: () => ({ top: 40, left: 110, bottom: 60, right: 200, width: 90, height: 20 })
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const result = testOrder(container);
|
|
343
|
+
expect(result).toBe(true);
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
describe('sortByVisualOrder', () => {
|
|
348
|
+
it('should sort elements by visual position', () => {
|
|
349
|
+
const el1 = document.createElement('button');
|
|
350
|
+
const el2 = document.createElement('button');
|
|
351
|
+
const el3 = document.createElement('button');
|
|
352
|
+
|
|
353
|
+
Object.defineProperty(el1, 'getBoundingClientRect', {
|
|
354
|
+
value: () => ({ top: 50, left: 10 })
|
|
355
|
+
});
|
|
356
|
+
Object.defineProperty(el2, 'getBoundingClientRect', {
|
|
357
|
+
value: () => ({ top: 10, left: 50 })
|
|
358
|
+
});
|
|
359
|
+
Object.defineProperty(el3, 'getBoundingClientRect', {
|
|
360
|
+
value: () => ({ top: 10, left: 10 })
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const sorted = [el1, el2, el3].sort(sortByVisualOrder);
|
|
364
|
+
|
|
365
|
+
expect(sorted[0]).toBe(el3); // top: 10, left: 10
|
|
366
|
+
expect(sorted[1]).toBe(el2); // top: 10, left: 50
|
|
367
|
+
expect(sorted[2]).toBe(el1); // top: 50, left: 10
|
|
368
|
+
});
|
|
369
|
+
});
|