Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1571)

Side by Side Diff: chrome/test/data/extensions/api_test/automation/tests/unit/test.js

Issue 1155183006: Reimplement automation API on top of C++-backed AXTree. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@automation_faster_2
Patch Set: Copy observers Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698