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']);
12 * Test fixture for Background.
14 * @extends {ChromeVoxNextE2ETest}
16 function BackgroundTest() {
17 ChromeVoxNextE2ETest.call(this);
20 BackgroundTest.prototype = {
21 __proto__: ChromeVoxNextE2ETest.prototype,
25 global.backgroundObj.forceChromeVoxNextActive();
29 * @return {!MockFeedback}
31 createMockFeedback: function() {
32 var mockFeedback = new MockFeedback(this.newCallback(),
33 this.newCallback.bind(this));
34 mockFeedback.install();
39 * Create a function which perform the command |cmd|.
41 * @return {function() : void}
43 doCmd: function(cmd) {
45 global.backgroundObj.onGotCommand(cmd);
49 linksAndHeadingsDoc: function() {/*!
51 <a href='#a'>alpha</a>
55 <a href='foo'>delta</a>
57 <a href='#bar'>echo</a>
59 <p>end<span>of test</span></p>
62 formsDoc: function() {/*!
63 <select id="fruitSelect">
64 <option>apple</option>
65 <option>grape</option>
66 <option> banana</option>
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));
77 /** Tests that ChromeVox next is in this context. */
78 SYNC_TEST_F('BackgroundTest', 'NextNamespaces', function() {
79 assertEquals('function', typeof(Background));
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'))
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();
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'))
151 mockFeedback.call(doCmd('nextCharacter'))
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'))
169 mockFeedback.call(doCmd('previousCharacter'))
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'))
181 mockFeedback.call(doCmd('nextWord'))
182 .expectSpeech('Link', 'echo');
183 mockFeedback.replay();
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();
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'))
213 'Heading 1', 'charlie');
214 mockFeedback.replay();
218 TEST_F('BackgroundTest', 'LiveRegionAddElement', function() {
219 var mockFeedback = this.createMockFeedback();
220 this.runWithLoadedTree(
222 <h1>Document with live region</h1>
223 <p id="live" aria-live="polite"></p>
224 <button id="go">Go</button>
226 document.getElementById('go').addEventListener('click', function() {
227 document.getElementById('live').innerHTML = 'Hello, world';
232 var go = rootNode.find({ role: chrome.automation.RoleType.button });
233 mockFeedback.call(go.doDefault.bind(go))
234 .expectSpeech('Hello, world');
235 mockFeedback.replay();
239 TEST_F('BackgroundTest', 'LiveRegionRemoveElement', function() {
240 var mockFeedback = this.createMockFeedback();
241 this.runWithLoadedTree(
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>
247 document.getElementById('go').addEventListener('click', function() {
248 document.getElementById('live').innerHTML = '';
253 var go = rootNode.find({ role: chrome.automation.RoleType.button });
255 mockFeedback.expectSpeech('removed:')
256 .expectSpeech('Hello, world');
257 mockFeedback.replay();
261 TEST_F('BackgroundTest', 'InitialFocus', function() {
262 var mockFeedback = this.createMockFeedback();
263 this.runWithLoadedTree('<a href="a">a</a>',
265 mockFeedback.expectSpeech('a')
266 .expectSpeech('Link');
267 mockFeedback.replay();
271 TEST_F('BackgroundTest', 'AriaLabel', function() {
272 var mockFeedback = this.createMockFeedback();
273 this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>',
275 rootNode.find({role: 'link'}).focus();
276 mockFeedback.expectSpeech('foo')
277 .expectSpeech('Link')
278 .expectBraille('foo lnk');
279 mockFeedback.replay();
284 TEST_F('BackgroundTest', 'ShowContextMenu', function() {
285 var mockFeedback = this.createMockFeedback();
286 this.runWithLoadedTree('<a href="a">a</a>',
288 mockFeedback.expectSpeech(/menu opened/)
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();
295 mockFeedback.replay();
297 var go = rootNode.find({ role: chrome.automation.RoleType.link });
298 this.listenOnce(go, 'focus', function(e) {
299 this.doCmd('showContextMenu')();
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));
313 this.runWithLoadedTree(
316 <button id="btn1">Click me</button>
318 <button id="btn2">Focus me</button>
319 <p>Some more text</p>
320 <input type="text" id ="text" value="Edit me">
322 document.getElementById('btn1').addEventListener('click', function() {
323 document.getElementById('btn2').focus();
328 var button1 = rootNode.find({role: chrome.automation.RoleType.button,
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})
342 assertEquals(3, textField.textSelStart);
344 mockFeedback.replay();
348 TEST_F('BackgroundTest', 'FocusInputElement', function() {
349 var mockFeedback = this.createMockFeedback();
350 this.runWithLoadedTree(
352 <input id="name" value="Lancelot">
353 <input id="quest" value="Grail">
354 <input id="color" value="Blue">
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();