OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 chrome.test.runWithNativesEnabled(function() { | |
6 var moduleSystem = chrome.test.getModuleSystem(window); | |
7 window.AutomationRootNode = | |
8 moduleSystem.require('automationNode').AutomationRootNode; | |
9 window.privates = moduleSystem.privates; | |
10 // Unused. | |
11 window.automationUtil = function() {}; | |
12 window.automationUtil.storeTreeCallback = function() {}; | |
13 window.automationUtil.treeChangeObservers = []; | |
14 }); | |
15 | |
16 var assertEq = chrome.test.assertEq; | |
17 var assertFalse = chrome.test.assertFalse; | |
18 var assertTrue = chrome.test.assertTrue; | |
19 var assertIsDef = function(obj) { | |
20 assertTrue(obj !== null && obj !== undefined); | |
21 } | |
22 var assertIsNotDef = function(obj) { | |
23 assertTrue(obj === null || obj === undefined); | |
24 } | |
25 var succeed = chrome.test.succeed; | |
26 | |
27 var tests = [ | |
28 function testAutomationRootNode() { | |
29 var root = new AutomationRootNode(); | |
30 assertTrue(root.isRootNode); | |
31 | |
32 succeed(); | |
33 }, | |
34 | |
35 function testAriaRelationshipAttributes() { | |
36 var data = { | |
37 'eventType': 'loadComplete', | |
38 'processID': 17, 'routingID': 2, 'targetID': 1, | |
39 'update': { 'nodeIdToClear': 0, 'nodes': [ | |
40 { | |
41 'id': 1, 'role': 'rootWebArea', | |
42 'boolAttributes': {'docLoaded': true }, | |
43 'childIds': [5, 6, 7, 8, 9, 10, 11] | |
44 }, | |
45 { | |
46 'id': 11, 'role': 'div', | |
47 'childIds': [], | |
48 'htmlAttributes': {'id': 'target' } | |
49 }, | |
50 { | |
51 'id': 5, 'role': 'div', | |
52 'childIds': [], | |
53 'htmlAttributes': {'aria-activedescendant': 'target', | |
54 'id': 'activedescendant'}, | |
55 'intAttributes': {'activedescendantId': 11}, | |
56 }, | |
57 { | |
58 'id': 6, 'role': 'div', | |
59 'childIds': [], | |
60 'htmlAttributes': {'aria-controls': 'target', 'id': 'controlledBy'}, | |
61 'intlistAttributes': {'controlsIds': [11]}, | |
62 }, | |
63 { | |
64 'id': 7, 'role': 'div', | |
65 'childIds': [], | |
66 'htmlAttributes': {'aria-describedby': 'target', 'id': 'describedBy'}, | |
67 'intlistAttributes': {'describedbyIds': [11, 6]}, | |
68 }, | |
69 { | |
70 'id': 8, 'role': 'div', | |
71 'childIds': [], | |
72 'htmlAttributes': {'aria-flowto': 'target', 'id': 'flowTo'}, | |
73 'intlistAttributes': {'flowtoIds': [11]}, | |
74 }, | |
75 { | |
76 'id': 9, 'role': 'div', | |
77 'childIds': [], | |
78 'htmlAttributes': {'aria-labelledby': 'target', 'id': 'labelledBy'}, | |
79 'intlistAttributes': {'labelledbyIds': [11]} | |
80 }, | |
81 { | |
82 'id': 10, 'role': 'div', | |
83 'childIds': [], | |
84 'htmlAttributes': {'aria-owns': 'target', 'id': 'owns'}, | |
85 'intlistAttributes': {'ownsIds': [11]}, | |
86 } | |
87 ]} | |
88 } | |
89 | |
90 var tree = new AutomationRootNode(); | |
91 try { | |
92 privates(tree).impl.onAccessibilityEvent(data); | |
93 } catch (e) { | |
94 console.log(e.stack); | |
95 } | |
96 | |
97 var activedescendant = tree.firstChild; | |
98 assertIsDef(activedescendant); | |
99 assertEq('activedescendant', activedescendant.attributes.id); | |
100 assertEq( | |
101 'target', | |
102 activedescendant.attributes['aria-activedescendant'].attributes.id); | |
103 | |
104 assertFalse(activedescendant.activedescendant == null, | |
105 'activedescendant should not be null'); | |
106 assertEq( | |
107 'target', | |
108 activedescendant.activedescendant.attributes.id); | |
109 assertIsNotDef(activedescendant.attributes.activedescendantId); | |
110 | |
111 var controlledBy = activedescendant.nextSibling; | |
112 assertIsDef(controlledBy); | |
113 assertEq('controlledBy', controlledBy.attributes.id); | |
114 assertEq(1, controlledBy.attributes['aria-controls'].length); | |
115 assertEq('target', | |
116 controlledBy.attributes['aria-controls'][0].attributes.id); | |
117 assertEq(1, controlledBy.controls.length); | |
118 assertEq('target', controlledBy.controls[0].attributes.id); | |
119 assertIsNotDef(controlledBy.attributes.controlledbyIds); | |
120 | |
121 var describedBy = controlledBy.nextSibling; | |
122 assertIsDef(describedBy); | |
123 assertEq('describedBy', describedBy.attributes.id); | |
124 assertEq(2, describedBy.attributes['aria-describedby'].length); | |
125 assertEq('target', | |
126 describedBy.attributes['aria-describedby'][0].attributes.id); | |
127 assertEq('controlledBy', | |
128 describedBy.attributes['aria-describedby'][1].attributes.id); | |
129 assertEq(2, describedBy.describedby.length); | |
130 assertEq('target', describedBy.describedby[0].attributes.id); | |
131 assertEq('controlledBy', | |
132 describedBy.describedby[1].attributes.id); | |
133 assertIsNotDef(describedBy.attributes.describedbyIds); | |
134 | |
135 var flowTo = describedBy.nextSibling; | |
136 assertIsDef(flowTo); | |
137 assertEq('flowTo', flowTo.attributes.id); | |
138 assertEq(1, flowTo.attributes['aria-flowto'].length); | |
139 assertEq('target', | |
140 flowTo.attributes['aria-flowto'][0].attributes.id); | |
141 assertEq(1, flowTo.flowto.length); | |
142 assertEq('target', flowTo.flowto[0].attributes.id); | |
143 assertIsNotDef(flowTo.attributes.flowtoIds); | |
144 | |
145 var labelledBy = flowTo.nextSibling; | |
146 assertIsDef(labelledBy); | |
147 assertEq('labelledBy', labelledBy.attributes.id); | |
148 assertEq(1, labelledBy.attributes['aria-labelledby'].length); | |
149 assertEq('target', | |
150 labelledBy.attributes['aria-labelledby'][0].attributes.id); | |
151 assertEq(1, labelledBy.labelledby.length); | |
152 assertEq('target', | |
153 labelledBy.labelledby[0].attributes.id); | |
154 assertIsNotDef(labelledBy.attributes.labelledbyIds); | |
155 | |
156 var owns = labelledBy.nextSibling; | |
157 assertIsDef(owns); | |
158 assertEq('owns', owns.attributes.id); | |
159 assertEq(1, owns.attributes['aria-owns'].length); | |
160 assertEq('target', owns.attributes['aria-owns'][0].attributes.id); | |
161 assertEq(1, owns.owns.length); | |
162 assertEq('target', owns.owns[0].attributes.id); | |
163 assertIsNotDef(owns.attributes.ownsIds); | |
164 | |
165 succeed(); | |
166 }, | |
167 | |
168 function testCannotSetAttribute() { | |
169 var update = | |
170 { | |
171 'nodeIdToClear': 0, 'nodes': [ | |
172 { | |
173 'id': 1, 'role': 'rootWebArea', | |
174 'boolAttributes': {'docLoaded': true}, | |
175 'childIds': [11] | |
176 }, | |
177 { | |
178 'id': 11, 'role': 'button', | |
179 'stringAttributes': {'name': 'foo'}, | |
180 'childIds': [] | |
181 }] | |
182 } | |
183 | |
184 var tree = new AutomationRootNode(); | |
185 assertTrue(privates(tree).impl.unserialize(update)); | |
186 var button = tree.firstChild; | |
187 assertEq('button', button.role); | |
188 assertEq('foo', button.name); | |
189 button.name = 'bar'; | |
190 assertEq('foo', button.name); | |
191 | |
192 succeed(); | |
193 }, | |
194 | |
195 function testBadUpdateInvalidChildIds() { | |
196 var update = | |
197 { | |
198 'nodeIdToClear': 0, 'nodes': [ | |
199 { | |
200 'id': 1, 'role': 'rootWebArea', | |
201 'boolAttributes': {'docLoaded': true}, | |
202 'childIds': [5, 6, 7, 8, 9, 10, 11] | |
203 }] | |
204 } | |
205 | |
206 var tree = new AutomationRootNode(); | |
207 | |
208 // This is a bad update because the root references non existent child ids. | |
209 assertFalse(privates(tree).impl.unserialize(update)); | |
210 | |
211 succeed(); | |
212 }, | |
213 | |
214 function testMultipleUpdateNameChanged() { | |
215 var update = | |
216 { | |
217 'nodeIdToClear': 0, 'nodes': [ | |
218 { | |
219 'id': 1, 'role': 'rootWebArea', | |
220 'boolAttributes': {'docLoaded': true}, | |
221 'childIds': [11] | |
222 }, | |
223 { | |
224 'id': 11, 'role': 'button', | |
225 'stringAttributes': {'name': 'foo'}, | |
226 'childIds': [] | |
227 }] | |
228 } | |
229 | |
230 // First, setup the initial tree. | |
231 var tree = new AutomationRootNode(); | |
232 assertTrue(privates(tree).impl.unserialize(update)); | |
233 var button = tree.firstChild; | |
234 assertEq('button', button.role); | |
235 assertEq('foo', button.name); | |
236 | |
237 // Now, apply an update that changes the button's name. | |
238 // Remove the root since the native serializer stops at the LCA. | |
239 update.nodes.splice(0, 1); | |
240 update.nodes[0].stringAttributes.name = 'bar'; | |
241 | |
242 // Make sure the name changes. | |
243 assertTrue(privates(tree).impl.unserialize(update)); | |
244 assertEq('bar', button.name); | |
245 | |
246 succeed(); | |
247 }, | |
248 | |
249 function testDocumentAndScrollableMixins() { | |
250 var update = { 'nodeIdToClear': 0, 'nodes': [ | |
251 { | |
252 'id': 1, 'role': 'rootWebArea', | |
253 'boolAttributes': { 'docLoaded': false }, | |
254 'stringAttributes': { 'docUrl': 'chrome://terms', | |
255 'docTitle': 'Google Chrome Terms of Service' }, | |
256 'intAttributes': { 'scrollY': 583, | |
257 'scrollYMax': 9336 }, | |
258 'floatAttributes': { 'docLoadingProgress': 0.9 }, | |
259 'childIds': [2] | |
260 }, | |
261 { | |
262 'id': 2, 'role': 'div', | |
263 'childIds': [], | |
264 'htmlAttributes': { 'id': 'child' }, | |
265 }, | |
266 ] }; | |
267 | |
268 var tree = new AutomationRootNode(); | |
269 assertTrue(privates(tree).impl.unserialize(update)); | |
270 assertEq(false, tree.docLoaded); | |
271 assertEq('chrome://terms', tree.docUrl); | |
272 assertEq('Google Chrome Terms of Service', tree.docTitle); | |
273 assertEq('0.9', tree.docLoadingProgress.toPrecision(1)); | |
274 assertEq(583, tree.scrollY); | |
275 assertEq(9336, tree.scrollYMax); | |
276 // Default values will be set for mixin attributes even if not in data. | |
277 assertEq(0, tree.scrollYMin); | |
278 assertEq(0, tree.scrollX); | |
279 assertEq(0, tree.scrollXMin); | |
280 assertEq(0, tree.scrollXMax); | |
281 | |
282 succeed(); | |
283 }, | |
284 | |
285 function testEditableTextMixins() { | |
286 var update = { 'nodeIdToClear': 0, 'nodes': [ | |
287 { | |
288 'id': 1, 'role': 'rootWebArea', | |
289 'boolAttributes': { 'docLoaded': true }, | |
290 'stringAttributes': { 'docUrl': 'chrome://terms', | |
291 'docTitle': 'Google Chrome Terms of Service' }, | |
292 'intAttributes': { 'scrollY': 583, | |
293 'scrollYMax': 9336 }, | |
294 'childIds': [2, 3] | |
295 }, | |
296 { | |
297 'id': 2, 'role': 'textField', | |
298 'intAttributes': { 'textSelStart': 10, 'textSelEnd': 20 }, | |
299 'childIds': [] | |
300 }, | |
301 { | |
302 'id': 3, 'role': 'textField', | |
303 'childIds': [] | |
304 }, | |
305 | |
306 ] }; | |
307 | |
308 var tree = new AutomationRootNode(); | |
309 assertTrue(privates(tree).impl.unserialize(update)); | |
310 assertEq(true, tree.docLoaded); | |
311 assertFalse('textSelStart' in tree); | |
312 assertFalse('textSelEnd' in tree); | |
313 var textField = tree.firstChild; | |
314 assertEq(10, textField.textSelStart); | |
315 assertEq(20, textField.textSelEnd); | |
316 var textArea = textField.nextSibling; | |
317 assertEq(-1, textArea.textSelStart); | |
318 assertEq(-1, textArea.textSelEnd); | |
319 | |
320 succeed(); | |
321 }, | |
322 | |
323 function testRangeMixins() { | |
324 var update = { 'nodeIdToClear': 0, 'nodes': [ | |
325 { | |
326 'id': 1, 'role': 'rootWebArea', | |
327 'boolAttributes': { 'docLoaded': true }, | |
328 'stringAttributes': { 'docUrl': 'chrome://terms', | |
329 'docTitle': 'Google Chrome Terms of Service' }, | |
330 'intAttributes': { 'scrollY': 583, | |
331 'scrollYMax': 9336 }, | |
332 'childIds': [2, 3, 4, 5] | |
333 }, | |
334 { | |
335 'id': 2, 'role': 'progressIndicator', | |
336 'floatAttributes': { 'valueForRange': 1.0, | |
337 'minValueForRange': 0.0, | |
338 'maxValueForRange': 1.0 }, | |
339 'childIds': [] | |
340 }, | |
341 { | |
342 'id': 3, 'role': 'scrollBar', | |
343 'floatAttributes': { 'valueForRange': 0.3, | |
344 'minValueForRange': 0.0, | |
345 'maxValueForRange': 1.0 }, | |
346 'childIds': [] | |
347 }, | |
348 { | |
349 'id': 4, 'role': 'slider', | |
350 'floatAttributes': { 'valueForRange': 3.0, | |
351 'minValueForRange': 1.0, | |
352 'maxValueForRange': 5.0 }, | |
353 'childIds': [] | |
354 }, | |
355 { | |
356 'id': 5, 'role': 'spinButton', | |
357 'floatAttributes': { 'valueForRange': 14.0, | |
358 'minValueForRange': 1.0, | |
359 'maxValueForRange': 31.0 }, | |
360 'childIds': [] | |
361 } | |
362 ] }; | |
363 | |
364 var tree = new AutomationRootNode(); | |
365 assertTrue(privates(tree).impl.unserialize(update)); | |
366 assertEq(true, tree.docLoaded); | |
367 assertFalse('valueForRange' in tree); | |
368 assertFalse('minValueForRange' in tree); | |
369 assertFalse('maxValueForRange' in tree); | |
370 | |
371 var progressIndicator = tree.firstChild; | |
372 assertEq(1.0, progressIndicator.valueForRange); | |
373 assertEq(0.0, progressIndicator.minValueForRange); | |
374 assertEq(1.0, progressIndicator.maxValueForRange); | |
375 | |
376 var scrollBar = progressIndicator.nextSibling; | |
377 assertEq(0.3, scrollBar.valueForRange); | |
378 assertEq(0.0, scrollBar.minValueForRange); | |
379 assertEq(1.0, scrollBar.maxValueForRange); | |
380 | |
381 var slider = scrollBar.nextSibling; | |
382 assertEq(3.0, slider.valueForRange); | |
383 assertEq(1.0, slider.minValueForRange); | |
384 assertEq(5.0, slider.maxValueForRange); | |
385 | |
386 var spinButton = slider.nextSibling; | |
387 assertEq(14.0, spinButton.valueForRange); | |
388 assertEq(1.0, spinButton.minValueForRange); | |
389 assertEq(31.0, spinButton.maxValueForRange); | |
390 | |
391 succeed(); | |
392 }, | |
393 | |
394 function testTableMixins() { | |
395 var update = { 'nodeIdToClear': 0, 'nodes': [ | |
396 { | |
397 'id': 1, 'role': 'rootWebArea', | |
398 'boolAttributes': { 'docLoaded': true }, | |
399 'stringAttributes': { 'docUrl': 'chrome://terms', | |
400 'docTitle': 'Google Chrome Terms of Service' }, | |
401 'intAttributes': { 'scrollY': 583, | |
402 'scrollYMax': 9336 }, | |
403 'childIds': [2] | |
404 }, | |
405 { | |
406 'id': 2, 'role': 'table', | |
407 'childIds': [3, 6], | |
408 'intAttributes': { tableRowCount: 2, tableColumnCount: 3 } | |
409 }, | |
410 { | |
411 'id': 3, 'role': 'row', | |
412 'childIds': [4, 5] | |
413 }, | |
414 { | |
415 'id': 4, 'role': 'cell', | |
416 'intAttributes': { 'tableCellColumnIndex': 0, | |
417 'tableCellColumnSpan': 2, | |
418 'tableCellRowIndex': 0, | |
419 'tableCellRowSpan': 1 }, | |
420 'childIds': [] | |
421 }, | |
422 { | |
423 'id': 5, 'role': 'cell', | |
424 'intAttributes': { 'tableCellColumnIndex': 2, | |
425 'tableCellColumnSpan': 1, | |
426 'tableCellRowIndex': 0, | |
427 'tableCellRowSpan': 2 }, | |
428 'childIds': [] | |
429 }, | |
430 { | |
431 'id': 6, 'role': 'row', | |
432 'childIds': [7, 8] | |
433 }, | |
434 { | |
435 'id': 7, 'role': 'cell', | |
436 'intAttributes': { 'tableCellColumnIndex': 0, | |
437 'tableCellColumnSpan': 1, | |
438 'tableCellRowIndex': 1, | |
439 'tableCellRowSpan': 1 }, | |
440 'childIds': [] | |
441 }, | |
442 { | |
443 'id': 8, 'role': 'cell', | |
444 'intAttributes': { 'tableCellColumnIndex': 1, | |
445 'tableCellColumnSpan': 1, | |
446 'tableCellRowIndex': 1, | |
447 'tableCellRowSpan': 1 }, | |
448 'childIds': [] | |
449 } | |
450 ] }; | |
451 | |
452 var tree = new AutomationRootNode(); | |
453 try { | |
454 assertTrue(privates(tree).impl.unserialize(update)); | |
455 } catch (e) { | |
456 console.log(e.stack); | |
457 } | |
458 var TableMixinAttributes = { | |
459 tableRowCount: 0, | |
460 tableColumnCount: 0 | |
461 }; | |
462 for (var attribute in TableMixinAttributes) | |
463 assertFalse(attribute in tree); | |
464 | |
465 var TableCellMixinAttributes = { | |
466 tableCellColumnIndex: 0, | |
467 tableCellColumnSpan: 1, | |
468 tableCellRowIndex: 0, | |
469 tableCellRowSpan: 1 | |
470 }; | |
471 for (var attribute in TableCellMixinAttributes) | |
472 assertFalse(attribute in tree); | |
473 | |
474 var table = tree.firstChild; | |
475 assertEq(2, table.tableRowCount); | |
476 assertEq(3, table.tableColumnCount); | |
477 | |
478 var row1 = table.firstChild; | |
479 var cell1 = row1.firstChild; | |
480 assertEq(0, cell1.tableCellColumnIndex); | |
481 assertEq(2, cell1.tableCellColumnSpan); | |
482 assertEq(0, cell1.tableCellRowIndex); | |
483 assertEq(1, cell1.tableCellRowSpan); | |
484 | |
485 var cell2 = cell1.nextSibling; | |
486 assertEq(2, cell2.tableCellColumnIndex); | |
487 assertEq(1, cell2.tableCellColumnSpan); | |
488 assertEq(0, cell2.tableCellRowIndex); | |
489 assertEq(2, cell2.tableCellRowSpan); | |
490 | |
491 var row2 = row1.nextSibling; | |
492 var cell3 = row2.firstChild; | |
493 assertEq(0, cell3.tableCellColumnIndex); | |
494 assertEq(1, cell3.tableCellColumnSpan); | |
495 assertEq(1, cell3.tableCellRowIndex); | |
496 assertEq(1, cell3.tableCellRowSpan); | |
497 | |
498 var cell4 = cell3.nextSibling; | |
499 assertEq(1, cell4.tableCellColumnIndex); | |
500 assertEq(1, cell4.tableCellColumnSpan); | |
501 assertEq(1, cell4.tableCellRowIndex); | |
502 assertEq(1, cell4.tableCellRowSpan); | |
503 | |
504 succeed(); | |
505 } | |
506 ]; | |
507 | |
508 chrome.test.runTests(tests); | |
OLD | NEW |