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

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/chromevox/injected/navigation_manager_test.unitjs

Issue 614673002: Port ChromeVox navigation manager and user commands tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « no previous file | chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // Include test fixture.
6 GEN_INCLUDE(['../../testing/chromevox_unittest_base.js']);
7
8 /**
9 * Test fixture.
10 * @constructor
11 * @extends {ChromeVoxUnitTestBase}
12 */
13 function CvoxNavigationManagerUnitTest() {}
14
15 CvoxNavigationManagerUnitTest.prototype = {
16 __proto__: ChromeVoxUnitTestBase.prototype,
17
18 /** @override */
19 isAsync: true,
20
21 /** @override */
22 closureModuleDeps: [
23 'cvox.ChromeVoxTester',
24 'cvox.NavigationShifter',
25 'cvox.TestTts',
26 ],
27
28 /** @override */
29 setUp: function() {
30 cvox.ChromeVoxTester.setUp(document);
31 },
32
33 /** @override */
34 tearDown: function() {
35 cvox.ChromeVoxTester.tearDown(document);
36 },
37
38 /**
39 * Check a sequence of navigations.
40 *
41 * @param {Array.<string>} strategies A list of nav strategies to try.
42 * @param {Array.<Object>} commandsAndExpectations An array of objects,
43 * each one of which should contain:
44 * 'command': The UserCommands command to execute.
45 * 'text': The expected text of the node that's navigated to.
46 * 'annotation': The expected annotation of the node navigated to.
47 */
48 checkNavSequence: function(strategies, commandsAndExpectations) {
49 if (strategies.length == 0)
50 testDone();
51
52 var strategy = strategies.shift();
53 this.waitForCalm(cvox.ChromeVoxTester.setStrategy, strategy)
54 .waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
55
56 var depth = 0;
57 commandsAndExpectations.forEach((function(ce) {
58 this.waitForCalm(function() {
59 if (ce.command) {
60 this.userCommand(ce.command);
61 depth = 0;
62 }
63 });
64 this.waitForCalm(function() {
65 if (ce.context)
66 this.assertNodeContext(ce.context, depth);
67 if (ce.text)
68 this.assertNodeText(ce.text, depth);
69 if (ce.userValue)
70 this.assertNodeUserValue(ce.userValue, depth);
71 if (ce.annotation)
72 this.assertNodeAnnotation(ce.annotation, depth);
73 depth++;
74 });
75 }).bind(this));
76 this.waitForCalm(function() {
77 this.checkNavSequence(strategies, commandsAndExpectations);
78 });
79 },
80
81 currentDescription_: function(opt_depth) {
82 var depth = opt_depth || 0;
83 return cvox.ChromeVox.navigationManager.getDescription()[depth] ||
84 new cvox.NavDescription({text: ''});
85 },
86
87 assertTextEquals: function(expected, actual) {
88 try {
89 assertEquals(expected, actual);
90 } catch (e) {
91 throw new Error('Expecting ' + expected + ' Actual ' + actual);
92 }
93 },
94
95 assertNodeText: function(expectedText, opt_depth) {
96 this.assertTextEquals(expectedText,
97 this.currentDescription_(opt_depth).text);
98 return this;
99 },
100
101 assertNodeAnnotation: function(expectedAnnotation, opt_depth) {
102 this.assertTextEquals(expectedAnnotation,
103 this.currentDescription_(opt_depth).annotation);
104 return this;
105 },
106
107 assertNodeContext: function(expectedContext, opt_depth) {
108 this.assertTextEquals(expectedContext,
109 this.currentDescription_(opt_depth).context);
110 return this;
111 },
112
113 assertNodeUserValue: function(expectedUserValue, opt_depth) {
114 this.assertTextEquals(expectedUserValue,
115 this.currentDescription_(opt_depth).userValue);
116 return this;
117 }
118 };
119
120 TEST_F('CvoxNavigationManagerUnitTest', 'SimpleStaticHTML', function() {
121 this.loadHtml(
122 '<div>' +
123 '<p id="before">Before</p>' +
124 '<h1>FirstHeading</h1>' +
125 '<h2>SecondHeading</h2>' +
126 '</div>');
127 this.checkNavSequence(
128 ['lineardom', 'smart', 'selection'],
129 [
130 { 'command': 'forward',
131 'text': 'FirstHeading',
132 'annotation': 'Heading 1'
133 },
134 { 'command': 'forward',
135 'text': 'SecondHeading',
136 'annotation': 'Heading 2'
137 }
138 ]);
139 });
140
141
142 /**
143 * Test navigation of simple static HTML with some control elements to validate
144 * the text and annotation returned when doing navigation.
145 */
146 TEST_F('CvoxNavigationManagerUnitTest', 'ControlElements', function() {
147 this.loadHtml(
148 '<div>' +
149 '<p id="before">Before</p>' +
150 '<p>Some text</p>' +
151 '<input type="text"/>' +
152 '<p>Some more text</p>' +
153 '<input type="button"/>' +
154 '</div>');
155 this.checkNavSequence(
156 ['lineardom', 'smart', 'selection'],
157 [
158 { 'command': 'forward',
159 'text': 'Some text',
160 'annotation': ''
161 },
162 { 'command': 'forward',
163 'text': '',
164 'annotation': 'Edit text'
165 },
166 { 'command': 'forward',
167 'text': 'Some more text',
168 'annotation': ''
169 },
170 { 'command': 'forward',
171 'text': '',
172 'annotation': 'Button'
173 }
174 ]);
175 });
176
177
178 /**
179 * Test navigation of simple static HTML with some control elements inside a
180 * fieldset to validate the text and annotation returned when doing
181 * navigation.
182 */
183 TEST_F('CvoxNavigationManagerUnitTest', 'ControlElementsWithFieldset', function( ) {
184 this.loadHtml(
185 '<div>' +
186 '<p id="before">Before</p>' +
187 '<p>Some text</p>' +
188 '<fieldset id="Fieldset">' +
189 '<legend>This is a legend inside a fieldset</legend>' +
190 '<input type="text"/>' +
191 '<p>Some more text</p>' +
192 '<input type="button"/>' +
193 '</fieldset>' +
194 '</div>');
195 this.checkNavSequence(
196 ['lineardom', 'selection'],
197 [
198 { 'command': 'forward',
199 'text': 'Some text',
200 'annotation': ''
201 },
202 { 'command': 'forward',
203 'text': 'This is a legend inside a fieldset'
204 },
205 { 'command': 'forward',
206 'annotation': 'Edit text'
207 },
208 { 'command': 'forward',
209 'text': 'Some more text',
210 'annotation': ''
211 },
212 { 'command': 'forward',
213 'text': '',
214 'annotation': 'Button'
215 }
216 ]);
217 });
218
219
220 /**
221 * Test skip to next/prev element navigation.
222 */
223 TEST_F('CvoxNavigationManagerUnitTest', 'SkipNavigation', function() {
224 this.loadHtml(
225 '<div>' +
226 '<p id="before">Before</p>' +
227 '<h1> <i>FirstHeading</i> </h1>' +
228 'asdf' +
229 '<p>Here is some text</p>' +
230 'asdf' +
231 '<h2>SecondHeading</h2>' +
232 '</div>');
233
234 cvox.ChromeVoxUserCommands.enableCommandDispatchingToPage = false;
235
236 this.checkNavSequence(
237 ['smart'],
238 [
239 { 'command': 'forward',
240 'text': 'FirstHeading',
241 'annotation': 'Heading 1'
242 },
243 { 'command': 'forward',
244 'text': 'asdf',
245 'annotation': ''
246 },
247 { 'command': 'nextHeading',
248 'text': 'SecondHeading',
249 'annotation': 'Heading 2'
250 },
251 { 'command': 'previousHeading',
252 'text': 'FirstHeading',
253 'annotation': 'Heading 1'
254 }
255 ]);
256 });
257
258
259 /**
260 * Test finding the next heading.
261 */
262 TEST_F('CvoxNavigationManagerUnitTest', 'FindNextHeading', function() {
263 this.loadHtml(
264 '<div>' +
265 '<p id="before">Before</p>' +
266 'Some text.' +
267 '<h1>A heading</h1>' +
268 'More text after the heading.' +
269 '<p>Even more text after the heading.</p>' +
270 '<p id="after">After</p>' +
271 '</div>');
272 cvox.ChromeVox.navigationManager.ignoreIframesNoMatterWhat();
273 this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom');
274 this.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
275
276 this.waitForCalm(this.userCommand, 'forward');
277 this.waitForCalm(this.assertSpoken, 'Some text.');
278
279 this.waitForCalm(this.userCommand, 'nextHeading');
280 this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
281
282 this.waitForCalm(this.userCommand, 'nextHeading');
283 this.waitForCalm(this.assertSpoken,
284 'Wrapped to top A heading Heading 1');
285
286 this.waitForCalm(this.userCommand, 'forward');
287 this.waitForCalm(this.assertSpoken, 'More text after the heading.');
288
289 this.waitForCalm(this.userCommand, 'previousHeading');
290 this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
291
292 this.waitForCalm(this.userCommand, 'previousHeading');
293 this.waitForCalm(this.assertSpoken,
294 'Wrapped to bottom A heading Heading 1');
295
296 this.waitForCalm(this.userCommand, 'backward');
297 this.waitForCalm(this.assertSpoken, 'Some text.');
298
299 this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'smart');
300 this.waitForCalm(cvox.ChromeVoxTester.syncToFirstNode);
301
302 this.waitForCalm(this.userCommand, 'forward');
303 this.waitForCalm(this.assertSpoken, 'Some text.');
304
305 this.waitForCalm(this.userCommand, 'nextHeading');
306 this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
307
308 this.waitForCalm(this.userCommand, 'nextHeading');
309 this.waitForCalm(this.assertSpoken,
310 'Wrapped to top A heading Heading 1');
311
312 this.waitForCalm(this.userCommand, 'forward');
313 this.waitForCalm(this.assertSpoken, 'More text after the heading.');
314
315 this.waitForCalm(this.userCommand, 'previousHeading');
316 this.waitForCalm(this.assertSpoken, 'A heading Heading 1');
317
318 this.waitForCalm(this.userCommand, 'previousHeading');
319 this.waitForCalm(this.assertSpoken,
320 'Wrapped to bottom A heading Heading 1');
321
322 this.waitForCalm(this.userCommand, 'backward');
323 this.waitForCalm(this.assertSpoken, 'Some text.');
324
325 this.waitForCalm(testDone);
326 });
327
328
329 /**
330 * Test navigation of HTML and ARIA lists.
331 */
332 TEST_F('CvoxNavigationManagerUnitTest', 'ListLinearNav', function() {
333 this.loadHtml(
334 '<div>' +
335 '<p id="before">Before</p>' +
336 '<ul>' +
337 '<li>First' +
338 '<li><div>Second</div></li>' +
339 '<div role="listitem"><a href="#">Third</a></div>' +
340 '</ul>' +
341 '<div role="list">' +
342 '<div role="listitem"><a href="#">First</a></div>' +
343 '<li>Second' +
344 '</div>' +
345 '<p id="after">After</p>' +
346 '</div>');
347 this.checkNavSequence(
348 ['lineardom'],
349 [
350 { 'command': 'forward',
351 'context': 'List with 3 items',
352 'text': 'First',
353 'annotation': 'List item'
354 },
355 { 'command': 'forward',
356 'context': '',
357 'text': 'Second',
358 'annotation': 'List item'
359 },
360 { 'command': 'forward',
361 'context': '',
362 'text': 'Third',
363 'annotation': 'Internal link List item'
364 },
365 { 'command': 'forward',
366 'context': 'List with 2 items',
367 'text': 'First',
368 'annotation': 'Internal link List item'
369 },
370 { 'command': 'forward',
371 'context': '',
372 'text': 'Second',
373 'annotation': 'List item'
374 },
375 { 'command': 'forward',
376 'context': '',
377 'text': 'After',
378 'annotation': ''
379 },
380 { 'command': 'backward',
381 'context': 'List with 2 items',
382 'text': 'Second',
383 'annotation': 'List item'
384 },
385 { 'command': 'backward',
386 'context': '',
387 'text': 'First',
388 'annotation': 'Internal link List item'
389 }
390 ]);
391 });
392
393
394 /**
395 * Test navigation of HTML and ARIA lists.
396 */
397 TEST_F('CvoxNavigationManagerUnitTest', 'ListSmartNav', function() {
398 this.loadHtml(
399 '<div>' +
400 '<p id="before">Before</p>' +
401 '<ul>' +
402 '<li>First</li>' +
403 '<li>Second</li>' +
404 '<div role="listitem">Third</div>' +
405 '</ul>' +
406 '<div role="list">' +
407 '<div role="listitem"><a href="#">First</a></div>' +
408 '<li>Second' +
409 '</div>' +
410 '<p id="after">After</p>' +
411 '</div>');
412 this.checkNavSequence(
413 ['smart'],
414 [
415 { 'command': 'forward',
416 'context': 'List with 3 items',
417 'text': 'First',
418 'annotation': 'List item'
419 },
420 { 'text': 'Second',
421 'annotation': 'List item'
422 },
423 { 'text': 'Third',
424 'annotation': 'List item'
425 },
426 { 'command': 'forward',
427 'context': 'List with 2 items',
428 'text': 'First',
429 'annotation': 'Internal link List item'
430 },
431 { 'text': 'Second',
432 'annotation': 'List item'
433 },
434 { 'command': 'forward',
435 'text': 'After'
436 },
437 { 'command': 'backward',
438 'context': 'List with 2 items',
439 'text': 'First',
440 'annotation': 'Internal link List item'
441 },
442 { 'text': 'Second',
443 'annotation': 'List item'
444 }
445 ]);
446 });
447
448
449 /**
450 * Test smart navigation of link collections.
451 */
452 TEST_F('CvoxNavigationManagerUnitTest', 'LinkCollectionSmartNav', function() {
453 this.loadHtml(
454 '<div>' +
455 '<p id="before">Before</p>' +
456 '<p>' +
457 '<a href="#">First</a>' +
458 '<a href="#">Second</a>' +
459 '<a href="#">Third</a>' +
460 '</p>' +
461 '<p>' +
462 '<a href="#">First</a> and' +
463 '<a href="#">Second</a> and' +
464 '<a href="#">Third</a>' +
465 '</p>' +
466 '<p id="after">After</p>' +
467 '</div>');
468
469 // TODO: The way we implemented this feature breaks the i18n_check.
470 if (cvox.I18nCheck)
471 return;
472
473 this.checkNavSequence(
474 ['smart'],
475 [
476 { 'command': 'forward',
477 'annotation': 'Link collection with 3 items'
478 },
479 { 'text': 'First'
480 },
481 { 'text': 'Second'
482 },
483 { 'text': 'Third'
484 },
485 { 'command': 'forward',
486 'text': 'First',
487 'annotation': 'Internal link'
488 },
489 { 'text': 'and'
490 },
491 { 'text': 'Second',
492 'annotation': 'Internal link'
493 },
494 { 'text': 'and'
495 },
496 { 'text': 'Third',
497 'annotation': 'Internal link'
498 },
499 { 'command': 'forward',
500 'text': 'After'
501 }
502 ]);
503 });
504
505
506 /**
507 * Test navigation of a control followed by its label.
508 */
509 TEST_F('CvoxNavigationManagerUnitTest', 'ControlThenLabel', function() {
510 this.loadHtml(
511 '<div>' +
512 '<p id="before">Before</p>' +
513 '<input type="checkbox" id="aaa">' +
514 '<label for="aaa">Alpha</label>' +
515 '<p id="after">After</p>' +
516 '</div>');
517 this.checkNavSequence(
518 ['lineardom'],
519 [
520 { 'command': 'forward',
521 'text': 'Alpha',
522 'annotation': 'Check box not checked'
523 },
524 { 'command': 'forward',
525 'text': 'After',
526 'annotation': ''
527 },
528 { 'command': 'backward',
529 'text': 'Alpha',
530 'annotation': 'Check box not checked'
531 },
532 { 'command': 'backward',
533 'text': 'Before',
534 'annotation': ''
535 }
536 ]);
537 });
538
539
540 /**
541 * Test navigation of a label followed by its control.
542 */
543 TEST_F('CvoxNavigationManagerUnitTest', 'LabelThenControl', function() {
544 this.loadHtml(
545 '<div>' +
546 '<p id="before">Before</p>' +
547 '<label for="bbb">Beta</label>' +
548 '<input type="checkbox" id="bbb">' +
549 '<p id="after">After</p>' +
550 '</div>');
551 this.checkNavSequence(
552 ['lineardom'],
553 [
554 { 'command': 'forward',
555 'text': 'Beta',
556 'annotation': 'Check box not checked'
557 },
558 { 'command': 'forward',
559 'text': 'After',
560 'annotation': ''
561 },
562 { 'command': 'backward',
563 'text': 'Beta',
564 'annotation': 'Check box not checked'
565 },
566 { 'command': 'backward',
567 'text': 'Before',
568 'annotation': ''
569 }
570 ]);
571 });
572
573
574 /**
575 * Test navigation of a control inside a label element (yes, this is
576 * valid HTML and should be supported).
577 */
578 TEST_F('CvoxNavigationManagerUnitTest', 'ControlInsideLabel', function() {
579 this.loadHtml(
580 '<div>' +
581 '<p id="before">Before</p>' +
582 '<label>' +
583 'First name:' +
584 '<input type="text" name="name" value="Linus">' +
585 '</label>' +
586 '<p>' +
587 '<label>Remember me' +
588 '<input type="checkbox" id="remember" />' +
589 '</label>' +
590 '</p>' +
591 '<p id="after">After</p>' +
592 '</div>');
593 this.checkNavSequence(
594 ['lineardom'],
595 [
596 { 'command': 'forward',
597 'text': 'First name:',
598 'userValue': 'Linus',
599 'annotation': 'Edit text'
600 },
601 { 'command': 'forward',
602 'text': 'Remember me',
603 'annotation': 'Check box not checked'
604 },
605 { 'command': 'forward',
606 'text': 'After',
607 'annotation': ''
608 },
609 { 'command': 'backward',
610 'text': 'Remember me',
611 'annotation': 'Check box not checked'
612 },
613 { 'command': 'backward',
614 'text': 'First name:',
615 'userValue': 'Linus',
616 'annotation': 'Edit text'
617 },
618 { 'command': 'backward',
619 'text': 'Before',
620 'annotation': ''
621 }
622 ]);
623 });
624
625
626 /**
627 * Test navigation of two controls inside a single label element - this
628 * is nonstandard but we should make sure we don't totally fail!
629 */
630 TEST_F('CvoxNavigationManagerUnitTest', 'TwoControlsInsideLabel', function() {
631 this.loadHtml(
632 '<div>' +
633 '<p id="before">Before</p>' +
634 '<label>' +
635 'LabelText' +
636 '<input type="text" value="Value">' +
637 '<input type="checkbox">' +
638 '</label>' +
639 '<p id="after">After</p>' +
640 '</div>');
641 this.checkNavSequence(
642 ['lineardom'],
643 [
644 { 'command': 'forward',
645 'text': 'LabelText',
646 'userValue': 'Value',
647 'annotation': 'Edit text'
648 },
649 { 'command': 'forward',
650 'text': 'LabelText',
651 'annotation': 'Check box not checked'
652 },
653 { 'command': 'forward',
654 'text': 'After',
655 'annotation': ''
656 },
657 { 'command': 'backward',
658 'text': 'LabelText',
659 'annotation': 'Check box not checked'
660 },
661 { 'command': 'backward',
662 'text': 'LabelText',
663 'userValue': 'Value',
664 'annotation': 'Edit text'
665 },
666 { 'command': 'backward',
667 'text': 'Before',
668 'annotation': ''
669 }
670 ]);
671 });
672
673
674 /**
675 * Test invalid labels - if a label doesn't point to a control, it
676 * should just be read as if it wasn't a label.
677 */
678 TEST_F('CvoxNavigationManagerUnitTest', 'InvalidLabels', function() {
679 this.loadHtml(
680 '<div>' +
681 '<p id="before">Before</p>' +
682 '<label for="xxx">Label for nonexistent control</label>' +
683 '<label>Label with no associated control</label>' +
684 '<p id="after">After</p>' +
685 '</div>');
686 this.checkNavSequence(
687 ['lineardom'],
688 [
689 { 'command': 'forward',
690 'text': 'Label for nonexistent control',
691 'annotation': ''
692 },
693 { 'command': 'forward',
694 'text': 'Label with no associated control',
695 'annotation': ''
696 },
697 { 'command': 'forward',
698 'text': 'After',
699 'annotation': ''
700 },
701 { 'command': 'backward',
702 'text': 'Label with no associated control',
703 'annotation': ''
704 },
705 { 'command': 'backward',
706 'text': 'Label for nonexistent control',
707 'annotation': ''
708 },
709 { 'command': 'backward',
710 'text': 'Before',
711 'annotation': ''
712 }
713 ]);
714 });
715
716
717 /**
718 * Test scrollbar value readout.
719 */
720 TEST_F('CvoxNavigationManagerUnitTest', 'Scrollbar', function() {
721 this.loadHtml(
722 '<div>' +
723 '<p id="before">Before</p>' +
724 '<div id="progress1" role="progressbar" class="range"' +
725 'aria-valuemin="0" aria-valuenow="1" aria-valuemax="5">' +
726 '<div>[==&nbsp;&nbsp;&nbsp;]</div>' +
727 '</div>' +
728 '<p id="after">After</p>' +
729 '</div>');
730 this.checkNavSequence(
731 ['lineardom', 'smart'],
732 [
733 { 'command': 'forward',
734 'text': '',
735 'annotation': 'Progress bar 20%'
736 }
737 ]);
738 });
739
740
741 /**
742 * Test ARIA listbox where the whole box gets focus.
743 */
744 TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxActiveDescendant', function( ) {
745 this.loadHtml(
746 '<div>' +
747 '<p id="before">Before</p>' +
748 '<select size="3">' +
749 '<option selected>Red</option>' +
750 '<option>Yellow</option>' +
751 '<option>Green</option>' +
752 '</select>' +
753 '<p id="middle1">Middle 1</p>' +
754 '<div id="listbox" role="listbox" tabindex="0" aria-activedescendant="red" >' +
755 '<div id="red" aria-selected="true" role="option">Red</div>' +
756 '<div id="yellow" role="option">Yellow</div>' +
757 '<div id="green" role="option">Green</div>' +
758 '</div>' +
759 '<p id="middle2">Middle 2</p>' +
760 '<div id="listbox2" role="listbox" tabindex="0"' +
761 'aria-activedescendant="red2">' +
762 '<div id="red2" aria-selected="true" role="option"' +
763 'aria-posinset="10" aria-setsize="30">Red</div>' +
764 '<div id="yellow2" role="option"' +
765 'aria-posinset="20" aria-setsize="30">Yellow</div>' +
766 '<div id="green2" role="option"' +
767 'aria-posinset="30" aria-setsize="30">Green</div>' +
768 '</div>' +
769 '<p id="after">After</p>' +
770 '</div>');
771 this.checkNavSequence(
772 ['lineardom', 'smart'],
773 [
774 { 'command': 'forward',
775 'userValue': 'Red',
776 'annotation': 'Combo box 1 of 3'
777 },
778 { 'command': 'forward',
779 'text': 'Middle 1',
780 'annotation': ''
781 },
782 { 'command': 'forward',
783 'userValue': 'Red',
784 'annotation': 'List box Selected 1 of 3'
785 },
786 { 'command': 'forward',
787 'text': 'Middle 2',
788 'annotation': ''
789 },
790 { 'command': 'forward',
791 'userValue': 'Red',
792 'annotation': 'List box Selected 10 of 30'
793 },
794 { 'command': 'forward',
795 'text': 'After',
796 'annotation': ''
797 }
798 ]);
799 });
800
801
802 /**
803 * Test ARIA listbox where each option gets focus.
804 */
805 TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxOption', function() {
806 this.loadHtml(
807 '<div>' +
808 '<p id="before">Before</p>' +
809 '<div id="listbox" role="listbox">' +
810 '<div id="red" tabindex="0" aria-selected="true" role="option">Red</div> ' +
811 '<div id="yellow" tabindex="-1" role="option">Yellow</div>' +
812 '<div id="green" tabindex="-1" role="option">Green</div>' +
813 '</div>' +
814 '<p id="before">Middle</p>' +
815 '<div id="listbox2" role="listbox">' +
816 '<div id="red2" tabindex="0" aria-selected="true" role="option"' +
817 'aria-posinset="2" aria-setsize="6">Red</div>' +
818 '<div id="yellow2" tabindex="-1" role="option"' +
819 'aria-posinset="4" aria-setsize="6">Yellow</div>' +
820 '<div id="green2" tabindex="-1" role="option"' +
821 'aria-posinset="6" aria-setsize="6">Green</div>' +
822 '</div>' +
823 '<p id="after">After</p>' +
824 '</div>');
825 this.checkNavSequence(
826 ['lineardom', 'smart'],
827 [
828 { 'command': 'forward',
829 'context': 'List box',
830 'text': 'Red',
831 'annotation': 'Selected 1 of 3'
832 },
833 { 'command': 'forward',
834 'text': 'Yellow',
835 'annotation': '2 of 3'
836 },
837 { 'command': 'forward',
838 'text': 'Green',
839 'annotation': '3 of 3'
840 },
841 { 'command': 'forward',
842 'text': 'Middle',
843 'annotation': ''
844 },
845 { 'command': 'forward',
846 'context': 'List box',
847 'text': 'Red',
848 'annotation': 'Selected 2 of 6'
849 },
850 { 'command': 'forward',
851 'text': 'Yellow',
852 'annotation': '4 of 6'
853 },
854 { 'command': 'forward',
855 'text': 'Green',
856 'annotation': '6 of 6'
857 },
858 { 'command': 'forward',
859 'text': 'After',
860 'annotation': ''
861 },
862 { 'command': 'backward',
863 'context': 'List box',
864 'text': 'Green',
865 'annotation': '6 of 6'
866 },
867 { 'command': 'backward',
868 'text': 'Yellow',
869 'annotation': '4 of 6'
870 },
871 { 'command': 'backward',
872 'text': 'Red',
873 'annotation': 'Selected 2 of 6'
874 },
875 { 'command': 'backward',
876 'text': 'Middle',
877 'annotation': ''
878 },
879 { 'command': 'backward',
880 'context': 'List box',
881 'text': 'Green',
882 'annotation': '3 of 3'
883 },
884 { 'command': 'backward',
885 'text': 'Yellow',
886 'annotation': '2 of 3'
887 },
888 { 'command': 'backward',
889 'text': 'Red',
890 'annotation': 'Selected 1 of 3'
891 }
892 ]);
893 });
894
895
896 /**
897 * Test ARIA listbox where each option gets focus and the outer container has
898 * tabindex="-1"
899 */
900 TEST_F('CvoxNavigationManagerUnitTest', 'AriaListboxOptionOuterFocus', function( ) {
901 this.loadHtml(
902 '<div>' +
903 '<p id="before">Before</p>' +
904 '<div id="listbox" role="listbox" tabindex="-1">' +
905 '<div id="red" tabindex="0" aria-selected="true" role="option">Red</div> ' +
906 '<div id="yellow" tabindex="-1" role="option">Yellow</div>' +
907 '<div id="green" tabindex="-1" role="option">Green</div>' +
908 '</div>' +
909 '<p id="after">After</p>' +
910 '</div>');
911 this.checkNavSequence(
912 ['smart'],
913 [
914 { 'command': 'forward',
915 'context': 'List box',
916 'text': 'Red',
917 'annotation': 'Selected 1 of 3'
918 },
919 { 'command': 'forward',
920 'text': 'Yellow',
921 'annotation': '2 of 3'
922 },
923 { 'command': 'forward',
924 'text': 'Green',
925 'annotation': '3 of 3'
926 },
927 { 'command': 'forward',
928 'text': 'After',
929 'annotation': ''
930 }
931 ]);
932 });
933
934
935
936 /**
937 * Test ARIA menus.
938 */
939 TEST_F('CvoxNavigationManagerUnitTest', 'AriaMenus', function() {
940 this.loadHtml(
941 '<div>' +
942 '<p id="before">Before</p>' +
943 '<div role="menubar">' +
944 '<div role="menuitem">File</div>' +
945 '<div role="menuitem">Edit</div>' +
946 '</div>' +
947 '<div role="menu">' +
948 '<div role="menuitem">New</div>' +
949 '<div role="menuitem">Open</div>' +
950 '</div>' +
951 '<p id="after">After</p>' +
952 '</div>');
953 this.checkNavSequence(
954 ['lineardom', 'smart'],
955 [
956 { 'command': 'forward',
957 'context': 'Menu bar',
958 'text': 'File',
959 'annotation': 'Menu'
960 },
961 { 'command': 'forward',
962 'text': 'Edit',
963 'annotation': 'Menu'
964 },
965 { 'command': 'forward',
966 'text': 'New',
967 'annotation': 'Menu item 1 of 2'
968 },
969 { 'command': 'forward',
970 'text': 'Open',
971 'annotation': 'Menu item 2 of 2'
972 }
973 ]);
974 });
975
976 /**
977 * Test left and right navigation at the group level.
978 */
979 TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightGroupNavigation', function() {
980 this.loadHtml(
981 '<div>' +
982 '<p id="before">Before</p>' +
983 '<h1>Alphabetical Fruits</h1>' +
984 'Apple <a href=\'#\'>Banana</a> Cranberry <a href=\'#\'>Date</a> Eggplant' +
985 '<p id="after">After</p>' +
986 '</div>');
987 this.checkNavSequence(
988 ['smart'],
989 [
990 { 'command': 'forward',
991 'text': 'Alphabetical Fruits',
992 'annotation': 'Heading 1'
993 },
994 { 'command': 'right',
995 'text': 'Apple'
996 },
997 { 'command': 'right',
998 'text': 'Banana',
999 'annotation': 'Internal link'
1000 },
1001 { 'command': 'left',
1002 'text': 'Apple'
1003 },
1004 { 'command': 'forward',
1005 'text': 'Banana',
1006 'annotation': 'Internal link'
1007 },
1008 { 'command': 'right',
1009 'text': 'Cranberry'
1010 },
1011 { 'command': 'backward',
1012 'text': 'Banana',
1013 'annotation': 'Internal link'
1014 }
1015 ]);
1016 });
1017
1018 /**
1019 * Test left and right navigation at the sentence level.
1020 */
1021 TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightSentenceNavigation', function( ) {
1022 this.loadHtml(
1023 '<div>' +
1024 '<p id="before">Before</p>' +
1025 '<h1>Alphabetical Fruits</h1>' +
1026 'Apples are delicious. An apple a day keeps the doctor away.' +
1027 '<a href="#">Banana</a> Cranberries are delicious. ' +
1028 'A cranberry a day keeps the doctor away.' +
1029 '<p id="after">After</p>' +
1030 '</div>');
1031
1032 // TODO(dtseng): This is here until we can remove or fix all tests relating to
1033 // sentences. This test framework holds state across runs, so only this
1034 // expression is needed.
1035 cvox.NavigationShifter.allowSentence = true;
1036 this.checkNavSequence(
1037 ['lineardom'],
1038 [
1039 { 'command': 'forward',
1040 'text': 'Alphabetical Fruits',
1041 'annotation': 'Heading 1'
1042 },
1043 { 'command': 'forward',
1044 'text': 'Apples are delicious. An apple a day keeps the doctor away.'
1045 },
1046 { 'command': 'right',
1047 'text': 'An apple a day keeps the doctor away.'
1048 },
1049 { 'command': 'right',
1050 'text': 'Banana',
1051 'annotation': 'Internal link'
1052 },
1053 { 'command': 'right',
1054 'text': 'Cranberries are delicious.'
1055 },
1056 { 'command': 'right',
1057 'text': 'A cranberry a day keeps the doctor away.'
1058 },
1059 { 'command': 'left',
1060 'text': 'Cranberries are delicious.'
1061 },
1062 { 'command': 'left',
1063 'text': 'Banana',
1064 'annotation': 'Internal link'
1065 },
1066 { 'command': 'forward',
1067 'text': 'Cranberries are delicious. A cranberry a day keeps the doctor away.'
1068 }
1069 ]);
1070 });
1071
1072 /**
1073 * Test left and right navigation at the word level.
1074 */
1075 TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightWordNavigation', function() {
1076 this.loadHtml(
1077 '<div>' +
1078 '<p id="before">Before</p>' +
1079 '<h1>Alphabetical Fruits</h1>' +
1080 'Apples are delicious. An apple a day keeps the doctor away.' +
1081 '<h2><a href="#">Banana</a></h2> Cranberries are delicious. ' +
1082 'A cranberry a day keeps the doctor away.' +
1083 '<p id="after">After</p>' +
1084 '</div>');
1085 this.checkNavSequence(
1086 ['selection'],
1087 [
1088 { 'command': 'forward',
1089 'text': 'Alphabetical Fruits',
1090 'annotation': 'Heading 1'
1091 },
1092 { 'command': 'forward',
1093 'text': 'Apples are delicious.'
1094 },
1095 { 'command': 'nextGranularity' },
1096 { 'command': 'right',
1097 'text': 'are'
1098 },
1099 { 'command': 'right',
1100 'text': 'delicious.'
1101 },
1102 { 'command': 'right',
1103 'text': 'An'
1104 },
1105 { 'command': 'right',
1106 'text': 'apple'
1107 },
1108 { 'command': 'right',
1109 'text': 'a'
1110 },
1111 { 'command': 'left',
1112 'text': 'apple'
1113 },
1114 { 'command': 'left',
1115 'text': 'An'
1116 },
1117 { 'command': 'forward',
1118 'text': 'Banana'
1119 },
1120 { 'command': 'right',
1121 'text': 'Cranberries'
1122 },
1123 { 'command': 'previousGranularity' },
1124 { 'command': 'previousGranularity',
1125 'text': 'Cranberries are delicious. A cranberry a day keeps the doctor away.'
1126 }
1127 ]);
1128 });
1129
1130 /**
1131 * Test left and right navigation at the character level.
1132 */
1133 TEST_F('CvoxNavigationManagerUnitTest', 'LeftRightCharacterNavigation', function () {
1134 this.loadHtml(
1135 '<div>' +
1136 '<p id="before">Before</p>' +
1137 '<h1>Alphabetical Fruits</h1>' +
1138 'Apples are delicious. An apple a day keeps the doctor away.' +
1139 '<a href="#">Banana</a> Cranberries are delicious. ' +
1140 'A cranberry a day keeps ' +
1141 'the doctor away.' +
1142 '<p id="after">After</p>' +
1143 '</div>');
1144 this.checkNavSequence(
1145 ['selection'],
1146 [
1147 { 'command': 'forward',
1148 'text': 'Alphabetical Fruits',
1149 'annotation': 'Heading 1'
1150 },
1151 { 'command': 'forward',
1152 'text': 'Apples are delicious.'
1153 },
1154 { 'command': 'nextGranularity' },
1155 { 'command': 'nextGranularity',
1156 'text': 'Apples'
1157 },
1158 { 'command': 'right',
1159 'text': 'p'
1160 },
1161 { 'command': 'right',
1162 'text': 'p'
1163 },
1164 { 'command': 'right',
1165 'text': 'l'
1166 },
1167 { 'command': 'right',
1168 'text': 'e'
1169 },
1170 { 'command': 'right',
1171 'text': 's'
1172 },
1173 { 'command': 'right',
1174 'text': ' '
1175 },
1176 { 'command': 'right',
1177 'text': 'a'
1178 },
1179 { 'command': 'right',
1180 'text': 'r'
1181 },
1182 { 'command': 'right',
1183 'text': 'e'
1184 },
1185 { 'command': 'left',
1186 'text': 'r'
1187 },
1188 { 'command': 'left',
1189 'text': 'a'
1190 },
1191 { 'command': 'forward',
1192 'text': 'delicious.'
1193 },
1194 { 'command': 'right',
1195 'text': 'e'
1196 },
1197 { 'command': 'nextGranularity' },
1198 { 'command': 'previousGranularity',
1199 'text': 'elicious.'
1200 }
1201 ]);
1202 });
1203
1204 /**
1205 * Test whether fullyDescribe works
1206 */
1207 TEST_F('CvoxNavigationManagerUnitTest', 'FullyDescribe', function() {
1208 this.loadHtml(
1209 '<div>' +
1210 '<p id="before">Before</p>' +
1211 '<ul>' +
1212 '<li>A</li>' +
1213 '<ul>' +
1214 '<li>1</li>' +
1215 '<li>2</li>' +
1216 '</ul>' +
1217 '</ul>' +
1218 '<p id="after">After</p>' +
1219 '</div>');
1220 this.checkNavSequence(
1221 ['lineardom'],
1222 [
1223 { 'command': 'forward',
1224 'context': 'List with 1 items',
1225 'text': 'A',
1226 'annotation': 'List item'
1227 },
1228 { 'command': 'forward',
1229 'context': 'List with 2 items',
1230 'text': '1',
1231 'annotation': 'List item'
1232 },
1233 { 'command': 'forward',
1234 'context': '',
1235 'text': '2',
1236 'annotation': 'List item'
1237 },
1238 { 'command': 'fullyDescribe',
1239 'context': '',
1240 'text': '2',
1241 'annotation': 'List item'
1242 }
1243 ]);
1244 this.waitForCalm(this.assertSpoken,
1245 'List with 1 items A List item ' +
1246 'List with 2 items 1 List item 2 List item ' +
1247 'List with 1 items List with 2 items 2 List item');
1248 });
1249
1250
1251 /**
1252 * Test continuous reading mode.
1253 */
1254 TEST_F('CvoxNavigationManagerUnitTest', 'ContinuousReading', function() {
1255 this.loadHtml(
1256 '<div id="continuousTest">' +
1257 '<p id="before">Before</p>' +
1258 '<div>Some text.</div>' +
1259 '<div>First</div>' +
1260 '<div>Second</div>' +
1261 '<a href="#">Third</a>' +
1262 '<p id="after">After</p>' +
1263 '</div>');
1264 cvox.ChromeVox.navigationManager.ignoreIframesNoMatterWhat();
1265 this.waitForCalm(cvox.ChromeVoxTester.setStrategy, 'lineardom')
1266 .waitForCalm(cvox.ChromeVoxTester.syncToFirstNode)
1267 .waitForCalm(cvox.ChromeVoxTester.readFromHere)
1268 .waitForCalm(this.assertSpoken,
1269 'Before Some text. First Second Third Internal link After')
1270 .waitForCalm(testDone);
1271 });
1272
1273
1274 /**
1275 * Test HTML5 semantic elements
1276 */
1277 TEST_F('CvoxNavigationManagerUnitTest', 'SemanticElts', function() {
1278 this.loadHtml(
1279 '<p id="before">Before</p>' +
1280 '<article>' +
1281 '<header>' +
1282 '<time datetime="2009-10-22" pubdate="">October 22, 2009</time>' +
1283 '<h1>' +
1284 '<a href="#">Travel day</a>' +
1285 '</h1>' +
1286 '</header>' +
1287 '<p>Blah blah blah</p>' +
1288 '</article>' +
1289 '<div>' +
1290 '<p>October 17, 2009</p>' +
1291 '<h2>' +
1292 '<a href="#">I am going to Prague!</a>' +
1293 '</h2>' +
1294 '<p>More blah blah blah</p>' +
1295 '</div>' +
1296 '<p id="after">After</p>');
1297
1298 this.checkNavSequence(
1299 ['smart'],
1300 [
1301 { 'command': 'forward',
1302 'text': 'October 22, 2009',
1303 'context': 'Article Header',
1304 'annotation': 'Time'
1305 },
1306 {
1307 'text': 'Travel day',
1308 'context': '',
1309 'annotation': 'Internal link Heading 1'
1310 },
1311 {
1312 'text': 'Blah blah blah'
1313 },
1314 { 'command': 'forward',
1315 'text': 'October 17, 2009'
1316 },
1317 {
1318 'command': 'forward',
1319 'text': 'I am going to Prague!',
1320 'context': '',
1321 'annotation': 'Internal link Heading 2'
1322 },
1323 {
1324 'command': 'forward',
1325 'text': 'More blah blah blah'
1326 }
1327 ]);
1328 });
1329
1330
1331 /**
1332 * Test aria-haspopup
1333 */
1334 TEST_F('CvoxNavigationManagerUnitTest', 'AriaHasPopup', function() {
1335 this.loadHtml(
1336 '<div>' +
1337 '<p id="before">Before</p>' +
1338 '<button>Alpha</button>' +
1339 '<button aria-haspopup="true">Bravo</button>' +
1340 '<div role="button" tabindex="0">Charlie</div>' +
1341 '<div role="button" aria-haspopup="true" tabindex="0">Delta</div>' +
1342 '<div role="menuitem" tabindex="0">Echo</div>' +
1343 '<div role="menuitem" aria-haspopup="true" tabindex="0">Foxtrot</div>' +
1344 '</div>');
1345 this.checkNavSequence(
1346 ['lineardom', 'smart'],
1347 [
1348 { 'command': 'forward',
1349 'text': 'Alpha',
1350 'annotation': 'Button'
1351 },
1352 { 'command': 'forward',
1353 'text': 'Bravo',
1354 'annotation': 'Pop-up button'
1355 },
1356 { 'command': 'forward',
1357 'text': 'Charlie',
1358 'annotation': 'Button'
1359 },
1360 { 'command': 'forward',
1361 'text': 'Delta',
1362 'annotation': 'Pop-up button'
1363 },
1364 { 'command': 'forward',
1365 'text': 'Echo',
1366 'annotation': 'Menu item'
1367 },
1368 { 'command': 'forward',
1369 'text': 'Foxtrot',
1370 'annotation': 'Menu item with submenu'
1371 }
1372 ]);
1373 });
1374
1375
1376 /** Test Aria Math Roles. */
1377 TEST_F('CvoxNavigationManagerUnitTest', 'AriaMathRoles', function() {
1378 this.loadHtml(
1379 '<p><div role="math"' +
1380 'aria-label="a times x squared plus b times x plus c equals 0">' +
1381 '<math xmlns="http://www.w3.org/1998/Math/MathML">' +
1382 '<mrow><mrow><mrow><mi>a</mi><mo> &InvisibleTimes; </mo>' +
1383 ' <msup id="foo"><mi>x</mi><mn>2</mn></msup>' +
1384 '</mrow><mo>+</mo><mrow><mi>b</mi><mo> &InvisibleTimes; </mo>' +
1385 '<mi>x</mi></mrow><mo>+</mo><mi>c</mi></mrow><mo>=</mo><mn>0</mn></mrow>' +
1386 '</math></div></p>' +
1387 '<p><div role="math" aria-label="square root of n cube">' +
1388 '<math><msqrt><msup><mi>n</mi><mn>3</mn></msup></msqrt></math></div></p>'
1389 );
1390
1391 this.waitForCalm(this.userCommand, 'forward')
1392 .waitForCalm(this.assertSpoken, 'Math a times x squared plus b times x plu s c equals 0')
1393 .waitForCalm(this.userCommand, 'forward')
1394 .waitForCalm(this.assertSpoken, 'Math square root of n cube')
1395 .waitForCalm(testDone);
1396 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/chromeos/chromevox/chromevox/injected/user_commands_test.unitjs » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698