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,
24 * @return {!MockFeedback}
26 createMockFeedback: function() {
27 var mockFeedback = new MockFeedback(this.newCallback(),
28 this.newCallback.bind(this));
29 mockFeedback.install();
34 * Create a function which perform the command |cmd|.
36 * @return {function() : void}
38 doCmd: function(cmd) {
40 global.backgroundObj.onGotCommand(cmd);
44 linksAndHeadingsDoc: function() {/*!
46 <a href='#a'>alpha</a>
50 <a href='foo'>delta</a>
52 <a href='#bar'>echo</a>
54 <p>end<span>of test</span></p>
57 formsDoc: function() {/*!
58 <select id="fruitSelect">
59 <option>apple</option>
60 <option>grape</option>
61 <option> banana</option>
66 /** Tests that ChromeVox classic is in this context. */
67 SYNC_TEST_F('BackgroundTest', 'ClassicNamespaces', function() {
68 assertEquals('object', typeof(cvox));
69 assertEquals('function', typeof(cvox.ChromeVoxBackground));
72 /** Tests that ChromeVox next is in this context. */
73 SYNC_TEST_F('BackgroundTest', 'NextNamespaces', function() {
74 assertEquals('function', typeof(Background));
77 /** Tests consistency of navigating forward and backward. */
78 TEST_F('BackgroundTest', 'ForwardBackwardNavigation', function() {
79 var mockFeedback = this.createMockFeedback();
80 this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
81 var doCmd = this.doCmd.bind(this);
83 mockFeedback.expectSpeech('start').expectBraille('start');
85 mockFeedback.call(doCmd('nextLink'))
86 .expectSpeech('alpha', 'Link')
87 .expectBraille('alpha lnk');
88 mockFeedback.call(doCmd('nextLink'))
89 .expectSpeech('beta', 'Link')
90 .expectBraille('beta lnk');
91 mockFeedback.call(doCmd('nextLink'))
92 .expectSpeech('delta', 'Link')
93 .expectBraille('delta lnk');
94 mockFeedback.call(doCmd('previousLink'))
95 .expectSpeech('beta', 'Link')
96 .expectBraille('beta lnk');
97 mockFeedback.call(doCmd('nextHeading'))
98 .expectSpeech('Heading 1', 'charlie')
99 .expectBraille('h1 charlie');
100 mockFeedback.call(doCmd('nextHeading'))
101 .expectSpeech('Heading 2', 'foxtraut')
102 .expectBraille('h2 foxtraut');
103 mockFeedback.call(doCmd('previousHeading'))
104 .expectSpeech('Heading 1', 'charlie')
105 .expectBraille('h1 charlie');
107 mockFeedback.call(doCmd('nextElement'))
108 .expectSpeech('delta', 'Link')
109 .expectBraille('delta lnk');
110 mockFeedback.call(doCmd('nextElement'))
111 .expectSpeech('echo', 'Link')
112 .expectBraille('echo lnk');
113 mockFeedback.call(doCmd('nextElement'))
114 .expectSpeech('Heading 2', 'foxtraut')
115 .expectBraille('h2 foxtraut');
116 mockFeedback.call(doCmd('nextElement'))
118 .expectBraille('end');
119 mockFeedback.call(doCmd('previousElement'))
120 .expectSpeech('Heading 2', 'foxtraut')
121 .expectBraille('h2 foxtraut');
122 mockFeedback.call(doCmd('nextLine'))
123 .expectSpeech('end', 'of test')
124 .expectBraille('end of test');
126 mockFeedback.call(doCmd('goToBeginning'))
127 .expectSpeech('start')
128 .expectBraille('start');
129 mockFeedback.call(doCmd('goToEnd'))
130 .expectSpeech('of test')
131 .expectBraille('of test');
133 mockFeedback.replay();
137 TEST_F('BackgroundTest', 'CaretNavigation', function() {
138 // TODO(plundblad): Add braille expectaions when crbug.com/523285 is fixed.
139 var mockFeedback = this.createMockFeedback();
140 this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
141 var doCmd = this.doCmd.bind(this);
143 mockFeedback.expectSpeech('start');
144 mockFeedback.call(doCmd('nextCharacter'))
146 mockFeedback.call(doCmd('nextCharacter'))
148 mockFeedback.call(doCmd('nextWord'))
149 .expectSpeech('Link', 'alpha');
150 mockFeedback.call(doCmd('nextWord'))
151 .expectSpeech('Link', 'beta');
152 mockFeedback.call(doCmd('nextWord'))
153 .expectSpeech('Heading 1', 'charlie');
154 mockFeedback.call(doCmd('nextLine'))
155 .expectSpeech('Link', 'delta');
156 mockFeedback.call(doCmd('nextLine'))
157 .expectSpeech('Link', 'echo');
158 mockFeedback.call(doCmd('nextLine'))
159 .expectSpeech('Heading 2', 'foxtraut');
160 mockFeedback.call(doCmd('nextLine'))
161 .expectSpeech('end', 'of test');
162 mockFeedback.call(doCmd('nextCharacter'))
164 mockFeedback.call(doCmd('previousCharacter'))
166 mockFeedback.call(doCmd('previousCharacter'))
167 .expectSpeech('Heading 2', 't');
168 mockFeedback.call(doCmd('previousWord'))
169 .expectSpeech('foxtraut');
170 mockFeedback.call(doCmd('previousWord'))
171 .expectSpeech('Link', 'echo');
172 mockFeedback.call(doCmd('previousCharacter'))
173 .expectSpeech('Link', 'a');
174 mockFeedback.call(doCmd('previousCharacter'))
176 mockFeedback.call(doCmd('nextWord'))
177 .expectSpeech('Link', 'echo');
178 mockFeedback.replay();
182 TEST_F('BackgroundTest', 'SelectSingleBasic', function() {
183 var mockFeedback = this.createMockFeedback();
184 this.runWithLoadedTree(this.formsDoc, function() {
185 var sendDownToSelect =
186 this.sendKeyToElement.bind(this, undefined, 'Down', '#fruitSelect');
187 mockFeedback.expectSpeech('apple', 'Menu item', /1 of 3/)
188 .expectBraille('apple mnuitm 1/3')
189 .call(sendDownToSelect)
190 .expectSpeech('grape', /2 of 3/)
191 .expectBraille('grape mnuitm 2/3')
192 .call(sendDownToSelect)
193 .expectSpeech('banana', /3 of 3/)
194 .expectBraille('banana mnuitm 3/3');
195 mockFeedback.replay();
199 TEST_F('BackgroundTest', 'ContinuousRead', function() {
200 var mockFeedback = this.createMockFeedback();
201 this.runWithLoadedTree(this.linksAndHeadingsDoc, function() {
202 mockFeedback.expectSpeech('start')
203 .call(this.doCmd('continuousRead'))
208 'Heading 1', 'charlie');
209 mockFeedback.replay();
213 TEST_F('BackgroundTest', 'LiveRegionAddElement', function() {
214 var mockFeedback = this.createMockFeedback();
215 this.runWithLoadedTree(
217 <h1>Document with live region</h1>
218 <p id="live" aria-live="polite"></p>
219 <button id="go">Go</button>
221 document.getElementById('go').addEventListener('click', function() {
222 document.getElementById('live').innerHTML = 'Hello, world';
227 var go = rootNode.find({ role: chrome.automation.RoleType.button });
228 mockFeedback.call(go.doDefault.bind(go))
229 .expectSpeech('Hello, world');
230 mockFeedback.replay();
234 TEST_F('BackgroundTest', 'LiveRegionRemoveElement', function() {
235 var mockFeedback = this.createMockFeedback();
236 this.runWithLoadedTree(
238 <h1>Document with live region</h1>
239 <p id="live" aria-live="polite" aria-relevant="removals">Hello, world</p>
240 <button id="go">Go</button>
242 document.getElementById('go').addEventListener('click', function() {
243 document.getElementById('live').innerHTML = '';
248 var go = rootNode.find({ role: chrome.automation.RoleType.button });
250 mockFeedback.expectSpeech('removed:')
251 .expectSpeech('Hello, world');
252 mockFeedback.replay();
256 TEST_F('BackgroundTest', 'InitialFocus', function() {
257 var mockFeedback = this.createMockFeedback();
258 this.runWithLoadedTree('<a href="a">a</a>',
260 mockFeedback.expectSpeech('a')
261 .expectSpeech('Link');
262 mockFeedback.replay();
266 TEST_F('BackgroundTest', 'AriaLabel', function() {
267 var mockFeedback = this.createMockFeedback();
268 this.runWithLoadedTree('<a aria-label="foo" href="a">a</a>',
270 rootNode.find({role: 'link'}).focus();
271 mockFeedback.expectSpeech('foo')
272 .expectSpeech('Link')
273 .expectBraille('foo lnk');
274 mockFeedback.replay();
279 TEST_F('BackgroundTest', 'ShowContextMenu', function() {
280 var mockFeedback = this.createMockFeedback();
281 this.runWithLoadedTree('<a href="a">a</a>',
283 mockFeedback.expectSpeech(/menu opened/)
285 // When shown, the context menu pushes a new message loop so test
286 // messages sent to the browser do not get processed. Ensure we
287 // exit the context menu here.
288 go.showContextMenu();
290 mockFeedback.replay();
292 var go = rootNode.find({ role: chrome.automation.RoleType.link });
293 this.listenOnce(go, 'focus', function(e) {
294 this.doCmd('showContextMenu')();
300 TEST_F('BackgroundTest', 'BrailleRouting', function() {
301 var mockFeedback = this.createMockFeedback();
302 var route = function(position) {
303 assertTrue(global.backgroundObj.onBrailleKeyEvent(
304 {command: cvox.BrailleKeyCommand.ROUTING,
305 displayPosition: position},
306 mockFeedback.lastMatchedBraille));
308 this.runWithLoadedTree(
311 <button id="btn1">Click me</button>
313 <button id="btn2">Focus me</button>
314 <p>Some more text</p>
315 <input type="text" id ="text" value="Edit me">
317 document.getElementById('btn1').addEventListener('click', function() {
318 document.getElementById('btn2').focus();
323 var button1 = rootNode.find({role: chrome.automation.RoleType.button,
325 var textField = rootNode.find(
326 {role: chrome.automation.RoleType.textField});
327 mockFeedback.expectBraille('start')
328 .call(button1.focus.bind(button1))
329 .expectBraille(/^Click me btn/)
330 .call(route.bind(null, 5))
331 .expectBraille(/Focus me btn/)
332 .call(textField.focus.bind(textField))
333 .expectBraille('Edit me ed', {startIndex: 0})
334 .call(route.bind(null, 3))
335 .expectBraille('Edit me ed', {startIndex: 3})
337 assertEquals(3, textField.textSelStart);
339 mockFeedback.replay();