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 GEN_INCLUDE(['../../testing/assert_additions.js']);
6 GEN_INCLUDE(['../../testing/chromevox_next_e2e_test_base.js']);
9 * Gets the braille output and asserts that it matches expected values.
10 * Annotations in the output that are primitive strings are ignored.
12 function checkBrailleOutput(expectedText, expectedSpans, output) {
13 var actualOutput = output.brailleOutputForTest;
14 // Remove string annotations. These are tested in the speech output and
15 // there's no need to clutter the tests with the corresponding braille
17 actualOutput.spans_ = actualOutput.spans_.filter(function(span) {
18 return (typeof span.value !== 'string');
20 assertEqualsJSON({string_: expectedText, spans_: expectedSpans},
25 * Test fixture for output.js.
27 * @extends {ChromeVoxNextE2ETestBase}
29 function OutputE2ETest() {
30 ChromeVoxNextE2ETest.call(this);
33 OutputE2ETest.prototype = {
34 __proto__: ChromeVoxNextE2ETest.prototype,
38 window.Dir = AutomationUtil.Dir;
42 TEST_F('OutputE2ETest', 'Links', function() {
43 this.runWithLoadedTree('<a href="#">Click here</a>',
45 var el = root.firstChild.firstChild;
46 var range = cursors.Range.fromNode(el);
47 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
48 assertEqualsJSON({string_: 'Click here|Link', 'spans_': [
50 {value: 'name', start: 0, end: 10},
52 // Link earcon (based on the name).
53 {value: {earconId: 'LINK'}, start: 0, end: 10},
55 {value: 'role', start: 11, end: 15}
56 ]}, o.speechOutputForTest);
57 checkBrailleOutput('Click here lnk', [], o);
61 TEST_F('OutputE2ETest', 'Checkbox', function() {
62 this.runWithLoadedTree('<input type="checkbox">',
64 var el = root.firstChild.firstChild;
65 var range = cursors.Range.fromNode(el);
66 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
67 assertEqualsJSON({string_: '|Check box|not checked', 'spans_': [
69 {value: 'name', start: 0, end: 0},
70 {value: 'role', start: 1, end: 10},
71 {value: 'state', start: 11, end: 22},
73 // Checkbox earcon (based on the state).
74 {value: {earconId: 'CHECK_OFF'}, start: 11, end: 22}
75 ]}, o.speechOutputForTest);
76 checkBrailleOutput('chk ( )', [], o);
80 TEST_F('OutputE2ETest', 'InLineTextBoxValueGetsIgnored', function() {
81 this.runWithLoadedTree('<p>OK',
83 var el = root.firstChild.firstChild.firstChild;
84 assertEquals('inlineTextBox', el.role);
85 var range = cursors.Range.fromNode(el);
86 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
87 assertEqualsJSON({string_: 'OK', 'spans_': [
89 {value: 'name', start: 0, end: 2}
90 ]}, o.speechOutputForTest);
91 checkBrailleOutput('OK', [], o);
93 el = root.firstChild.firstChild;
94 assertEquals('staticText', el.role);
95 range = cursors.Range.fromNode(el);
96 o = new Output().withSpeechAndBraille(range, null, 'navigate');
97 assertEqualsJSON({string_: 'OK|', 'spans_': [
99 {value: 'value', start: 0, end: 2},
101 // The name is an empty string.
102 {value: 'name', start: 3, end: 3}
103 ]}, o.speechOutputForTest);
104 checkBrailleOutput('OK', [], o);
108 TEST_F('OutputE2ETest', 'Headings', function() {
109 this.runWithLoadedTree(function() {/*!
110 <h1>a</h1><h2>b</h2><h3>c</h3><h4>d</h4><h5>e</h5><h6>f</h6>
111 <h1><a href="a.com">b</a></h1> */},
113 var el = root.firstChild;
114 for (var i = 1; i <= 6; ++i) {
115 var range = cursors.Range.fromNode(el);
116 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
117 var letter = String.fromCharCode('a'.charCodeAt(0) + i -1);
118 assertEqualsJSON({string_: 'Heading ' + i + '|' + letter, 'spans_': [
120 {value: 'nameOrDescendants', start: 10, end: 11}
121 ]}, o.speechOutputForTest);
122 checkBrailleOutput('h' + i + ' ' + letter, [], o);
126 range = cursors.Range.fromNode(el);
127 o = new Output().withSpeechAndBraille(range, null, 'navigate');
128 assertEqualsJSON({string_: 'Heading 1|b|Link', 'spans_': [
130 {value: 'name', start: 10, end: 11},
131 {value: {earconId: "LINK"}, start: 10, end: 11},
132 {value: 'role', start: 12, end: 16}
133 ]}, o.speechOutputForTest);
134 checkBrailleOutput('h1 b lnk', [], o);
138 TEST_F('OutputE2ETest', 'Audio', function() {
139 this.runWithLoadedTree('<audio src="foo.mp3" controls></audio>',
141 var el = root.firstChild.firstChild.firstChild.firstChild;
142 var range = cursors.Range.fromNode(el);
143 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
145 {string_: 'media control|Tool bar|||play|begin playback|Button',
147 // Entered container toolbar.
150 [{value: 'name', start: 23, end: 23},
153 {value: {earconId: "BUTTON"}, start: 23, end: 23},
155 {value: 'value', start: 24, end: 24},
156 {value: 'description', start: 25, end: 29},
157 {value: 'help', start: 30, end: 44},
158 {value: 'role', start: 45, end: 51}]
159 }, o.speechOutputForTest);
160 checkBrailleOutput('media control tlbar play begin playback btn', [], o);
163 var prevRange = range;
164 range = cursors.Range.fromNode(el);
165 var o = new Output().withSpeechAndBraille(range, prevRange, 'navigate');
166 assertEqualsJSON({string_: '0, , slider|audio time scrubber',
168 [{value: 'help', start: 12, end: 31}]
169 }, o.speechOutputForTest);
170 // TODO(plundblad): Investigate this.
171 checkBrailleOutput('0, , slider audio time scrubber', [], o);
175 TEST_F('OutputE2ETest', 'Input', function() {
176 this.runWithLoadedTree(
177 '<input type="text"></input>' +
178 '<input type="email"></input>' +
179 '<input type="password"></input>' +
180 '<input type="tel"></input>' +
181 '<input type="number"></input>' +
182 '<input type="time"></input>' +
183 '<input type="date"></input>',
185 var expected = {string_: '', 'spans_': [
186 {value: 'name', start: 0, end: 0},
189 {value: {earconId: 'EDITABLE_TEXT'}, start: 0, end: 0},
192 {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
194 {value: 'value', start: 1, end: 1}
197 var expectedSpeechValues = [
199 '||Edit text, email entry',
200 '||Password edit text',
201 '||Edit text, number entry',
202 {string_: '||Spin button', spans_: [{value: 'name', start: 0, end: 0},
203 {value: {earconId:'LISTBOX'}, start: 0, end: 0},
204 {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
205 {value: 'value', start: 1, end: 1},
206 {value: 'role', start: 2, end: 13}]},
207 {string_: '||Time control', spans_: [{value: 'name', start: 0, end: 0},
208 {value: 'value', start: 1, end: 1},
209 {value: 'role', start: 2, end: 14}]},
210 {string_: '||Date control', spans_: [{value: 'name', start: 0, end: 0},
211 {value: 'value', start: 1, end: 1},
212 {value: 'role', start: 2, end: 14}]}
214 // TODO(plundblad): Some of these are wrong, there should be an initial
215 // space for the cursor in edit fields.
216 var expectedBrailleValues = [
222 {string_: 'time', spans_: []},
223 {string_: 'date', spans_: []}
225 assertEquals(expectedSpeechValues.length, expectedBrailleValues.length);
227 var el = root.firstChild.firstChild;
228 expectedSpeechValues.forEach(function(expectedValue) {
229 var range = cursors.Range.fromNode(el);
230 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
231 if (typeof expectedValue == 'object') {
232 assertEqualsJSON(expectedValue, o.speechOutputForTest);
234 expected.string_ = expectedValue;
235 assertEqualsJSON(expected, o.speechOutputForTest);
240 el = root.firstChild.firstChild;
241 expectedBrailleValues.forEach(function(expectedValue) {
242 var range = cursors.Range.fromNode(el);
243 var o = new Output().withBraille(range, null, 'navigate');
244 if (typeof expectedValue === 'string') {
245 checkBrailleOutput(expectedValue,
246 [{'value': {'startIndex': 0, 'endIndex':0},
250 checkBrailleOutput(expectedValue.string_, expectedValue.spans_, o);
257 TEST_F('OutputE2ETest', 'List', function() {
258 this.runWithLoadedTree(
259 '<ul><li>a<li>b<li>c</ul>',
261 var el = root.firstChild.firstChild;
262 var range = cursors.Range.fromNode(el);
263 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
264 assertEqualsJSON({string_: 'list|with 3 items|a||List item', spans_: [
265 {value: 'name', start: 18, end: 19},
266 {value: {earconId:'LIST_ITEM'}, start: 18, end: 19},
267 {value: 'value', start:20, end: 20},
268 {value: 'role', start: 21, end: 30}
269 ]}, o.speechOutputForTest);
270 // TODO(0lundblad): This output is wrong. Add special handling for
272 checkBrailleOutput('list + a lstitm', [], o);
276 TEST_F('OutputE2ETest', 'Tree', function() {
277 this.runWithLoadedTree(function() {/*!
279 <li aria-expanded="true" role="treeitem">a
280 <li role="treeitem">b
281 <li aria-expanded="false" role="treeitem">c
285 var el = root.firstChild.children[0].firstChild;
286 var range = cursors.Range.fromNode(el);
287 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
289 {string_: '|Tree|with 3 items|Tree item|Expanded| 1 of 3 | level 1 |a|',
294 {value: 'role','start': 19, end: 28},
295 {value: 'state', start: 29, end: 37},
298 {value: 'value', start: 57, end: 58},
299 {value: 'name', start: 59, end: 59}
300 ]}, o.speechOutputForTest);
301 // TODO(plundblad): Braille output is wrong.
302 checkBrailleOutput('tree + tritm - 1/3 level 1 a', [], o);
304 el = root.firstChild.children[1].firstChild;
305 var range = cursors.Range.fromNode(el);
306 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
308 {string_: '|Tree|with 3 items|Tree item| 2 of 3 | level 1 |b|',
313 {value: 'role','start': 19, end: 28},
316 {value: 'value', start: 48, end: 49},
317 {value: 'name', start: 50, end: 50}
318 ]}, o.speechOutputForTest);
319 // TODO(plundblad): Braille output is wrong.
320 checkBrailleOutput('tree + tritm 2/3 level 1 b', [], o);
322 el = root.firstChild.children[2].firstChild;
323 var range = cursors.Range.fromNode(el);
324 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
326 {string_: '|Tree|with 3 items|Tree item|Collapsed| 3 of 3 | level 1 |c|',
331 {value: 'role','start': 19, end: 28},
332 {value: 'state', start: 29, end: 38},
335 {value: 'value', start: 58, end: 59},
336 {value: 'name', start: 60, end: 60}
337 ]}, o.speechOutputForTest);
338 // TODO(plundblad): Braille output is wrong.
339 checkBrailleOutput('tree + tritm + 3/3 level 1 c', [], o);
343 TEST_F('OutputE2ETest', 'Menu', function() {
344 this.runWithLoadedTree(function() {/*!
346 <div role="menuitem">a</div>
350 var el = root.firstChild.firstChild;
351 var range = cursors.Range.fromNode(el);
352 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
353 assertEqualsJSON({string_:
354 '|Menu|with 1 item|a|Menu item| 1 of 1 ', spans_: [
355 {value: 'name', start: 18, end: 19},
356 {value: 'role', start:20, end: 29}
357 ]}, o.speechOutputForTest);
358 checkBrailleOutput('mnu + a mnuitm 1/1', [], o);
362 TEST_F('OutputE2ETest', 'ListBox', function() {
363 this.runWithLoadedTree(function() {/*!
370 var el = root.firstChild.firstChild.firstChild;
371 var range = cursors.Range.fromNode(el);
372 var o = new Output().withSpeechAndBraille(range, null, 'navigate');
373 assertEqualsJSON({string_: '|List box|with 2 items||List item| 1 of 2 ',
377 {value: {earconId:'LISTBOX'}, start: 0, end: 0},
379 {value: 'name', start: 23, end: 23},
382 {value: {earconId: 'LIST_ITEM'}, start: 23, end: 23},
384 {value: 'role', start:24, end: 33}
385 ]}, o.speechOutputForTest);
386 checkBrailleOutput('lstbx + lstitm 1/2', [], o);
390 SYNC_TEST_F('OutputE2ETest', 'MessageIdAndEarconValidity', function() {
391 for (var key in Output.ROLE_INFO_) {
392 var value = Output.ROLE_INFO_[key];
393 cvox.ChromeVox.msgs.getMsg(value.msgId);
394 cvox.ChromeVox.msgs.getMsg(value.msgId + '_brl');
395 assertFalse(/[A-Z]+/.test(value.msgId));
397 assertNotNullNorUndefined(cvox.AbstractEarcons[value.earconId]);
399 for (var key in Output.STATE_INFO_) {
400 var value = Output.STATE_INFO_[key];
401 for (innerKey in value) {
402 var innerValue = value[innerKey];
403 cvox.ChromeVox.msgs.getMsg(innerValue.msgId);
404 cvox.ChromeVox.msgs.getMsg(innerValue.msgId + '_brl');
405 assertFalse(/[A-Z]+/.test(innerValue.msgId));
406 if (innerValue.earconId)
407 assertNotNullNorUndefined(cvox.AbstractEarcons[innerValue.earconId]);