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