Initial commit of new ChromeVox earcon engine.
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / cvox2 / background / background_test.extjs
blob82810f95a0d6354b845c04ee2469497e09c6c62e
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.
5 // Include test fixture.
6 GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js',
7              '../../testing/assert_additions.js']);
9 GEN_INCLUDE(['../../testing/mock_feedback.js']);
11 /**
12  * Test fixture for Background.
13  * @constructor
14  * @extends {ChromeVoxNextE2ETest}
15  */
16 function BackgroundTest() {
17   ChromeVoxNextE2ETest.call(this);
20 BackgroundTest.prototype = {
21   __proto__: ChromeVoxNextE2ETest.prototype,
23   /** @override */
24   setUp: function() {
25     global.backgroundObj.forceChromeVoxNextActive();
26   },
28   /**
29    * @return {!MockFeedback}
30    */
31   createMockFeedback: function() {
32     var mockFeedback = new MockFeedback(this.newCallback(),
33                                         this.newCallback.bind(this));
34     mockFeedback.install();
35     return mockFeedback;
36   },
38   /**
39    * Create a function which perform the command |cmd|.
40    * @param {string} cmd
41    * @return {function() : void}
42    */
43   doCmd: function(cmd) {
44     return function() {
45       global.backgroundObj.onGotCommand(cmd);
46     };
47   },
49   linksAndHeadingsDoc: function() {/*!
50     <p>start</p>
51     <a href='#a'>alpha</a>
52     <a href='#b'>beta</a>
53     <p>
54       <h1>charlie</h1>
55       <a href='foo'>delta</a>
56     </p>
57     <a href='#bar'>echo</a>
58     <h2>foxtraut</h2>
59     <p>end<span>of test</span></p>
60   */},
62   formsDoc: function() {/*!
63     <select id="fruitSelect">
64       <option>apple</option>
65       <option>grape</option>
66       <option> banana</option>
67     </select>
68   */}
71 /** Tests that ChromeVox classic is in this context. */
72 SYNC_TEST_F('BackgroundTest', 'ClassicNamespaces', function() {
73   assertEquals('object', typeof(cvox));
74   assertEquals('function', typeof(cvox.ChromeVoxBackground));
75 });
77 /** Tests that ChromeVox next is in this context. */
78 SYNC_TEST_F('BackgroundTest', 'NextNamespaces', function() {
79   assertEquals('function', typeof(Background));
80 });
82 /** Tests consistency of navigating forward and backward. */
83 TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() {
84   var mockFeedback = this.createMockFeedback();
85   this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
86     var doCmd = this.doCmd.bind(this);
88     mockFeedback.expectSpeech('start').expectBraille('start');
90     mockFeedback.call(doCmd('nextLink'))
91         .expectSpeech('alpha', 'Link')
92         .expectBraille('alpha lnk');
93     mockFeedback.call(doCmd('nextLink'))
94         .expectSpeech('beta', 'Link')
95         .expectBraille('beta lnk');
96     mockFeedback.call(doCmd('nextLink'))
97         .expectSpeech('delta', 'Link')
98         .expectBraille('delta lnk');
99     mockFeedback.call(doCmd('previousLink'))
100         .expectSpeech('beta', 'Link')
101         .expectBraille('beta lnk');
102     mockFeedback.call(doCmd('nextHeading'))
103         .expectSpeech('Heading 1', 'charlie')
104         .expectBraille('h1 charlie');
105     mockFeedback.call(doCmd('nextHeading'))
106         .expectSpeech('Heading 2', 'foxtraut')
107         .expectBraille('h2 foxtraut');
108     mockFeedback.call(doCmd('previousHeading'))
109         .expectSpeech('Heading 1', 'charlie')
110         .expectBraille('h1 charlie');
112     mockFeedback.call(doCmd('nextElement'))
113         .expectSpeech('delta', 'Link')
114         .expectBraille('delta lnk');
115     mockFeedback.call(doCmd('nextElement'))
116         .expectSpeech('echo', 'Link')
117         .expectBraille('echo lnk');
118     mockFeedback.call(doCmd('nextElement'))
119         .expectSpeech('Heading 2', 'foxtraut')
120         .expectBraille('h2 foxtraut');
121     mockFeedback.call(doCmd('nextElement'))
122         .expectSpeech('end')
123         .expectBraille('end');
124     mockFeedback.call(doCmd('previousElement'))
125         .expectSpeech('Heading 2', 'foxtraut')
126         .expectBraille('h2 foxtraut');
127     mockFeedback.call(doCmd('nextLine'))
128         .expectSpeech('end', 'of test')
129         .expectBraille('end of test');
131     mockFeedback.call(doCmd('goToBeginning'))
132         .expectSpeech('start')
133         .expectBraille('start');
134     mockFeedback.call(doCmd('goToEnd'))
135         .expectSpeech('of test')
136         .expectBraille('of test');
138     mockFeedback.replay();
139   });
142 TEST_F('BackgroundTest', 'CaretNavigation', function() {
143   // TODO(plundblad): Add braille expectaions when crbug.com/523285 is fixed.
144   var mockFeedback = this.createMockFeedback();
145   this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
146     var doCmd = this.doCmd.bind(this);
148     mockFeedback.expectSpeech('start');
149     mockFeedback.call(doCmd('nextCharacter'))
150         .expectSpeech('t');
151     mockFeedback.call(doCmd('nextCharacter'))
152         .expectSpeech('a');
153     mockFeedback.call(doCmd('nextWord'))
154         .expectSpeech('Link', 'alpha');
155     mockFeedback.call(doCmd('nextWord'))
156         .expectSpeech('Link', 'beta');
157     mockFeedback.call(doCmd('nextWord'))
158         .expectSpeech('Heading 1', 'charlie');
159     mockFeedback.call(doCmd('nextLine'))
160         .expectSpeech('Link', 'delta');
161     mockFeedback.call(doCmd('nextLine'))
162         .expectSpeech('Link', 'echo');
163     mockFeedback.call(doCmd('nextLine'))
164         .expectSpeech('Heading 2', 'foxtraut');
165     mockFeedback.call(doCmd('nextLine'))
166         .expectSpeech('end', 'of test');
167     mockFeedback.call(doCmd('nextCharacter'))
168         .expectSpeech('n');
169     mockFeedback.call(doCmd('previousCharacter'))
170         .expectSpeech('e');
171     mockFeedback.call(doCmd('previousCharacter'))
172         .expectSpeech('Heading 2', 't');
173     mockFeedback.call(doCmd('previousWord'))
174         .expectSpeech('foxtraut');
175     mockFeedback.call(doCmd('previousWord'))
176         .expectSpeech('Link', 'echo');
177     mockFeedback.call(doCmd('previousCharacter'))
178         .expectSpeech('Link', 'a');
179     mockFeedback.call(doCmd('previousCharacter'))
180         .expectSpeech('t');
181     mockFeedback.call(doCmd('nextWord'))
182         .expectSpeech('Link', 'echo');
183     mockFeedback.replay();
184   });
187 TEST_F('BackgroundTest', 'SelectSingleBasic', function() {
188   var mockFeedback = this.createMockFeedback();
189   this.runWithLoadedTree(this.formsDoc, function() {
190     var sendDownToSelect =
191         this.sendKeyToElement.bind(this, undefined, 'Down', '#fruitSelect');
192     mockFeedback.expectSpeech('apple', 'Menu item', /1 of 3/)
193         .expectBraille('apple mnuitm 1/3')
194         .call(sendDownToSelect)
195         .expectSpeech('grape', /2 of 3/)
196         .expectBraille('grape mnuitm 2/3')
197         .call(sendDownToSelect)
198         .expectSpeech('banana', /3 of 3/)
199         .expectBraille('banana mnuitm 3/3');
200     mockFeedback.replay();
201   });
204 TEST_F('BackgroundTest', 'ContinuousRead', function() {
205   var mockFeedback = this.createMockFeedback();
206   this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
207     mockFeedback.expectSpeech('start')
208         .call(this.doCmd('continuousRead'))
209         .expectSpeech(
210             'start',
211             'alpha', 'Link',
212             'beta', 'Link',
213             'Heading 1', 'charlie');
214     mockFeedback.replay();
215   });
218 TEST_F('BackgroundTest', 'LiveRegionAddElement', function() {
219   var mockFeedback = this.createMockFeedback();
220   this.runWithLoadedTree(
221     function() {/*!
222       <h1>Document with live region</h1>
223       <p id="live" aria-live="polite"></p>
224       <button id="go">Go</button>
225       <script>
226         document.getElementById('go').addEventListener('click', function() {
227           document.getElementById('live').innerHTML = 'Hello, world';
228         }, false);
229       </script>
230     */},
231     function(rootNode) {
232       var go = rootNode.find({ role: chrome.automation.RoleType.button });
233       mockFeedback.call(go.doDefault.bind(go))
234           .expectSpeech('Hello, world');
235       mockFeedback.replay();
236     });
239 TEST_F('BackgroundTest', 'LiveRegionRemoveElement', function() {
240   var mockFeedback = this.createMockFeedback();
241   this.runWithLoadedTree(
242     function() {/*!
243       <h1>Document with live region</h1>
244       <p id="live" aria-live="polite" aria-relevant="removals">Hello, world</p>
245       <button id="go">Go</button>
246       <script>
247         document.getElementById('go').addEventListener('click', function() {
248           document.getElementById('live').innerHTML = '';
249         }, false);
250       </script>
251     */},
252     function(rootNode) {
253       var go = rootNode.find({ role: chrome.automation.RoleType.button });
254       go.doDefault();
255       mockFeedback.expectSpeech('removed:')
256           .expectSpeech('Hello, world');
257       mockFeedback.replay();
258     });
261 TEST_F('BackgroundTest', 'InitialFocus', function() {
262   var mockFeedback = this.createMockFeedback();
263   this.runWithLoadedTree('<a href="a">a</a>',
264     function(rootNode) {
265       mockFeedback.expectSpeech('a')
266           .expectSpeech('Link');
267       mockFeedback.replay();
268     });
271 TEST_F('BackgroundTest', 'AriaLabel', function() {
272   var mockFeedback = this.createMockFeedback();
273   this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>',
274     function(rootNode) {
275       rootNode.find({role: 'link'}).focus();
276       mockFeedback.expectSpeech('foo')
277           .expectSpeech('Link')
278           .expectBraille('foo lnk');
279       mockFeedback.replay();
280     }
281   );
284 TEST_F('BackgroundTest', 'ShowContextMenu', function() {
285   var mockFeedback = this.createMockFeedback();
286   this.runWithLoadedTree('<a href="a">a</a>',
287     function(rootNode) {
288       mockFeedback.expectSpeech(/menu opened/)
289           .call(function() {
290             // When shown, the context menu pushes a new message loop so test
291             // messages sent to the browser do not get processed. Ensure we
292             // exit the context menu here.
293             go.showContextMenu();
294           });
295       mockFeedback.replay();
297       var go = rootNode.find({ role: chrome.automation.RoleType.link });
298       this.listenOnce(go, 'focus', function(e) {
299         this.doCmd('showContextMenu')();
300       }.bind(this), true);
301       go.focus();
302     }.bind(this));
305 TEST_F('BackgroundTest', 'BrailleRouting', function() {
306   var mockFeedback = this.createMockFeedback();
307   var route = function(position) {
308     assertTrue(global.backgroundObj.onBrailleKeyEvent(
309         {command: cvox.BrailleKeyCommand.ROUTING,
310          displayPosition: position},
311         mockFeedback.lastMatchedBraille));
312   };
313   this.runWithLoadedTree(
314       function() {/*!
315         <p>start</p>
316         <button id="btn1">Click me</button>
317         <p>Some text</p>
318         <button id="btn2">Focus me</button>
319         <p>Some more text</p>
320         <input type="text" id ="text" value="Edit me">
321         <script>
322           document.getElementById('btn1').addEventListener('click', function() {
323             document.getElementById('btn2').focus();
324           }, false);
325         </script>
326       */},
327       function(rootNode) {
328         var button1 = rootNode.find({role: chrome.automation.RoleType.button,
329                                      name: 'Click me'});
330         var textField = rootNode.find(
331             {role: chrome.automation.RoleType.textField});
332         mockFeedback.expectBraille('start')
333             .call(button1.focus.bind(button1))
334             .expectBraille(/^Click me btn/)
335             .call(route.bind(null, 5))
336             .expectBraille(/Focus me btn/)
337             .call(textField.focus.bind(textField))
338             .expectBraille('Edit me ed', {startIndex: 0})
339             .call(route.bind(null, 3))
340             .expectBraille('Edit me ed', {startIndex: 3})
341             .call(function() {
342               assertEquals(3, textField.textSelStart);
343             });
344         mockFeedback.replay();
345       });
348 TEST_F('BackgroundTest', 'FocusInputElement', function() {
349   var mockFeedback = this.createMockFeedback();
350   this.runWithLoadedTree(
351     function() {/*!
352       <input id="name" value="Lancelot">
353       <input id="quest" value="Grail">
354       <input id="color" value="Blue">
355     */},
356     function(rootNode) {
357       var name = rootNode.find({ attributes: { value: 'Lancelot' } });
358       var quest = rootNode.find({ attributes: { value: 'Grail' } });
359       var color = rootNode.find({ attributes: { value: 'Blue' } });
361       mockFeedback.call(quest.focus.bind(quest))
362           .expectSpeech('Grail', 'Edit text')
363           .call(color.focus.bind(color))
364           .expectSpeech('Blue', 'Edit text')
365           .call(name.focus.bind(name))
366           .expectNextSpeechUtteranceIsNot('Blue')
367           .expectSpeech('Lancelot', 'Edit text');
368       mockFeedback.replay();
369     }.bind(this));