Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / chromevox / cvox2 / background / output_test.extjs
blob73acdeacae7dc1518a0cf7196632097e2bdce310
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']);
8 /**
9  * Gets the braille output and asserts that it matches expected values.
10  * Annotations in the output that are primitive strings are ignored.
11  */
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
16   // annotations.
17   var actualSpans = actualOutput.spans_.filter(function(span) {
18     return (typeof span.value !== 'string');
19   });
20   assertEquals(expectedText, actualOutput.toString());
22   function describeSpan(span) {
23     var obj = {value: span.value, start: span.start, end: span.end};
24     if (obj.value instanceof Output.NodeSpan) {
25       obj.value.node = (obj.value.node.name || '') + ' ' +
26           obj.value.node.toString();
27     }
28     return JSON.stringify(obj);
29   }
31   function describeActualSpans() {
32     return '\nAll actual spans:\n' + actualSpans.map(describeSpan).join('\n');
33   }
35   for (var i = 0, max = Math.max(expectedSpans.length, actualSpans.length);
36        i < max; ++i) {
37     var expectedSpan = expectedSpans[i];
38     var actualSpan = actualSpans[i];
39     if (!expectedSpan)
40       throw Error('Unexpected span in ' + expectedText + ': ' +
41           describeSpan(actualSpan) + describeActualSpans());
42     if (!actualSpan)
43       throw Error('Missing expected span in ' + expectedText + ': ' +
44           describeSpan(expectedSpan) + describeActualSpans());
45     var equal = true;
46     if (expectedSpan.start !== actualSpan.start ||
47         expectedSpan.end !== actualSpan.end) {
48       equal = false;
49     } else if (expectedSpan.value instanceof Output.NodeSpan &&
50         (!(actualSpan.value instanceof Output.NodeSpan) ||
51         expectedSpan.value.node !== actualSpan.value.node)) {
52       equal = false;
53     } else {
54       equal = (JSON.stringify(expectedSpan.value) ===
55           JSON.stringify(actualSpan.value));
56     }
57     if (!equal) {
58       throw Error('Spans differ in ' + expectedText + ':\n' +
59           'Expected: ' + describeSpan(expectedSpan) + '\n' +
60           'Got     : ' + describeSpan(actualSpan) + describeActualSpans());
61     }
62   }
65 /**
66  * Test fixture for output.js.
67  * @constructor
68  * @extends {ChromeVoxNextE2ETestBase}
69  */
70 function OutputE2ETest() {
71   ChromeVoxNextE2ETest.call(this);
74 OutputE2ETest.prototype = {
75   __proto__: ChromeVoxNextE2ETest.prototype,
77   /** @override */
78   setUp: function() {
79     window.Dir = AutomationUtil.Dir;
80   }
83 TEST_F('OutputE2ETest', 'Links', function() {
84   this.runWithLoadedTree('<a href="#">Click here</a>',
85     function(root) {
86       var el = root.firstChild.firstChild;
87       var range = cursors.Range.fromNode(el);
88       var o = new Output().withSpeechAndBraille(range, null, 'navigate');
89       assertEqualsJSON({string_: 'Click here|Link', 'spans_': [
90         // Attributes.
91         {value: 'name', start: 0, end: 10},
93         // Link earcon (based on the name).
94         {value: {earconId: 'LINK'}, start: 0, end: 10},
96         {value: 'role', start: 11, end: 15}
97       ]}, o.speechOutputForTest);
98       checkBrailleOutput(
99           'Click here lnk',
100           [{value: new Output.NodeSpan(el), start: 0, end: 14}],
101           o);
102   });
105 TEST_F('OutputE2ETest', 'Checkbox', function() {
106   this.runWithLoadedTree('<input type="checkbox">',
107     function(root) {
108       var el = root.firstChild.firstChild;
109       var range = cursors.Range.fromNode(el);
110       var o = new Output().withSpeechAndBraille(range, null, 'navigate');
111       assertEqualsJSON({string_: '|Check box|not checked', 'spans_': [
112         // Attributes.
113         {value: 'name', start: 0, end: 0},
114         {value: 'role', start: 1, end: 10},
115         {value: 'state', start: 11, end: 22},
117         // Checkbox earcon (based on the state).
118         {value: {earconId: 'CHECK_OFF'}, start: 11, end: 22}
119       ]}, o.speechOutputForTest);
120       checkBrailleOutput(
121           'chk ( )',
122           [{value: new Output.NodeSpan(el), start: 0, end: 7}],
123           o);
124   });
127 TEST_F('OutputE2ETest', 'InLineTextBoxValueGetsIgnored', function() {
128   this.runWithLoadedTree('<p>OK',
129     function(root) {
130       var el = root.firstChild.firstChild.firstChild;
131       assertEquals('inlineTextBox', el.role);
132       var range = cursors.Range.fromNode(el);
133       var o = new Output().withSpeechAndBraille(range, null, 'navigate');
134       assertEqualsJSON({string_: 'OK', 'spans_': [
135         // Attributes.
136         {value: 'name', start: 0, end: 2}
137       ]}, o.speechOutputForTest);
138       checkBrailleOutput(
139           'OK',
140           [{value: new Output.NodeSpan(el), start: 0, end: 2}],
141           o);
143       el = root.firstChild.firstChild;
144       assertEquals('staticText', el.role);
145       range = cursors.Range.fromNode(el);
146       o = new Output().withSpeechAndBraille(range, null, 'navigate');
147       assertEqualsJSON({string_: 'OK|', 'spans_': [
148         // Attributes.
149         {value: 'value', start: 0, end: 2},
151         // The name is an empty string.
152         {value: 'name', start: 3, end: 3}
153       ]}, o.speechOutputForTest);
154       checkBrailleOutput(
155           'OK',
156           [{value: new Output.NodeSpan(el), start: 0, end: 2}],
157           o);
158   });
161 TEST_F('OutputE2ETest', 'Headings', function() {
162   this.runWithLoadedTree(function() {/*!
163       <h1>a</h1><h2>b</h2><h3>c</h3><h4>d</h4><h5>e</h5><h6>f</h6>
164       <h1><a href="a.com">b</a></h1> */},
165     function(root) {
166       var el = root.firstChild;
167       for (var i = 1; i <= 6; ++i) {
168         var range = cursors.Range.fromNode(el);
169         var o = new Output().withSpeechAndBraille(range, null, 'navigate');
170         var letter = String.fromCharCode('a'.charCodeAt(0) + i -1);
171         assertEqualsJSON({string_: 'Heading ' + i + '|' + letter, 'spans_': [
172           // Attributes.
173           {value: 'nameOrDescendants', start: 10, end: 11}
174         ]}, o.speechOutputForTest);
175         checkBrailleOutput(
176             'h' + i + ' ' + letter,
177             [{value: new Output.NodeSpan(el), start: 0, end: 4}],
178             o);
179         el = el.nextSibling;
180       }
182       range = cursors.Range.fromNode(el);
183       o = new Output().withSpeechAndBraille(range, null, 'navigate');
184       assertEqualsJSON({string_: 'Heading 1|b|Link', 'spans_': [
185         // Link.
186         {value: 'name', start: 10, end: 11},
187         {value: {earconId: "LINK"}, start: 10, end: 11},
188         {value: 'role', start: 12, end: 16}
189       ]}, o.speechOutputForTest);
190       checkBrailleOutput(
191           'h1 b lnk',
192           [{value: new Output.NodeSpan(el), start: 0, end: 2},
193            {value: new Output.NodeSpan(el.firstChild), start: 3, end: 8}],
194           o);
195   });
198 TEST_F('OutputE2ETest', 'Audio', function() {
199   this.runWithLoadedTree('<audio src="foo.mp3" controls></audio>',
200     function(root) {
201       var el = root.firstChild.firstChild.firstChild.firstChild;
202       var range = cursors.Range.fromNode(el);
203       var o = new Output().withSpeechAndBraille(range, null, 'navigate');
204       assertEqualsJSON(
205           {string_: 'audio|Tool bar|play||begin playback|Button',
206            spans_:
207               // Entered container toolbar.
209               // Button.
210               [{value: 'name', start: 15, end: 19},
212               // Button earcon.
213               {value: {earconId: "BUTTON"}, start: 15, end: 19},
215               {value: 'value', start: 20, end: 20},
216               {value: 'help', start: 21, end: 35},
217               {value: 'role', start: 36, end: 42}]
218           }, o.speechOutputForTest);
219       checkBrailleOutput(
220           'audio tlbar play begin playback btn',
221           [{value: new Output.NodeSpan(el.parent), start: 0, end: 11},
222            {value: new Output.NodeSpan(el), start: 12, end: 35}],
223           o);
225       el = el.nextSibling;
226       var prevRange = range;
227       range = cursors.Range.fromNode(el);
228       var o = new Output().withSpeechAndBraille(range, prevRange, 'navigate');
229       assertEqualsJSON({string_: '0, , slider|audio time scrubber',
230           spans_:
231               [{value: 'help', start: 12, end: 31}]
232           }, o.speechOutputForTest);
233       // TODO(plundblad): Investigate this.
234       checkBrailleOutput(
235           '0, , slider audio time scrubber',
236           [{value: new Output.NodeSpan(el), start: 0, end: 31}],
237           o);
238   });
241 TEST_F('OutputE2ETest', 'Input', function() {
242   this.runWithLoadedTree(
243       '<input type="text"></input>' +
244       '<input type="email"></input>' +
245       '<input type="password"></input>' +
246       '<input type="tel"></input>'          +
247       '<input type="number"></input>' +
248       '<input type="time"></input>' +
249       '<input type="date"></input>',
250     function(root) {
251       var expected = {string_: '', 'spans_': [
252               {value: 'name', start: 0, end: 0},
254               // Earcon
255               {value: {earconId: 'EDITABLE_TEXT'}, start: 0, end: 0},
257               // Selection span.
258               {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
260               {value: 'value', start: 1, end: 1}
261       ]};
263       var expectedSpeechValues = [
264         '||Edit text',
265         '||Edit text, email entry',
266         '||Password edit text',
267         '||Edit text, number entry',
268         {string_: '||Spin button', spans_: [{value: 'name', start: 0, end: 0},
269             {value: {earconId:'LISTBOX'}, start: 0, end: 0},
270             {value: {startIndex: 0, endIndex: 0}, start: 1, end: 1},
271             {value: 'value', start: 1, end: 1},
272             {value: 'role', start: 2, end: 13}]},
273         {string_: '||Time control', spans_: [{value: 'name', start: 0, end: 0},
274             {value: 'value', start: 1, end: 1},
275             {value: 'role', start: 2, end: 14}]},
276         {string_: '||Date control', spans_: [{value: 'name', start: 0, end: 0},
277             {value: 'value', start: 1, end: 1},
278             {value: 'role', start: 2, end: 14}]}
279       ];
280       // TODO(plundblad): Some of these are wrong, there should be an initial
281       // space for the cursor in edit fields.
282       var expectedBrailleValues = [
283         ' ed',
284         ' @ed',
285         ' pwded',
286         ' #ed',
287         ' spnbtn',
288         {string_: 'time'},
289         {string_: 'date'}
290       ];
291       assertEquals(expectedSpeechValues.length, expectedBrailleValues.length);
293       var el = root.firstChild.firstChild;
294       expectedSpeechValues.forEach(function(expectedValue) {
295         var range = cursors.Range.fromNode(el);
296         var o = new Output().withSpeechAndBraille(range, null, 'navigate');
297         if (typeof expectedValue == 'object') {
298           assertEqualsJSON(expectedValue, o.speechOutputForTest);
299         } else {
300           expected.string_ = expectedValue;
301           assertEqualsJSON(expected, o.speechOutputForTest);
302         }
303         el = el.nextSibling;
304       });
306       el = root.firstChild.firstChild;
307       expectedBrailleValues.forEach(function(expectedValue) {
308         var range = cursors.Range.fromNode(el);
309         var o = new Output().withBraille(range, null, 'navigate');
310         if (typeof expectedValue === 'string') {
311           checkBrailleOutput(
312               expectedValue,
313               [{value: {startIndex: 0, endIndex: 0}, start: 0, end: 0},
314                {value: new Output.NodeSpan(el), start: 0,
315                 end: expectedValue.length}],
316               o);
317         } else {
318           checkBrailleOutput(
319               expectedValue.string_,
320               [{value: new Output.NodeSpan(el), start: 0,
321                 end: expectedValue.string_.length}],
322               o);
323         }
324         el = el.nextSibling;
325       });
326   });
329 TEST_F('OutputE2ETest', 'List', function() {
330   this.runWithLoadedTree(
331       '<ul><li>a<li>b<li>c</ul>',
332     function(root) {
333       var el = root.firstChild.firstChild;
334       var range = cursors.Range.fromNode(el);
335       var o = new Output().withSpeechAndBraille(range, null, 'navigate');
336       assertEqualsJSON({string_: 'list|with 3 items|a||List item', spans_: [
337           {value: 'name', start: 18, end: 19},
338           {value: {earconId:'LIST_ITEM'}, start: 18, end: 19},
339           {value: 'value', start:20, end: 20},
340           {value: 'role', start: 21, end: 30}
341       ]}, o.speechOutputForTest);
342       // TODO(plundblad): This output is wrong.  Add special handling for
343       // braille here.
344       checkBrailleOutput(
345           'list +3 a lstitm',
346           [{value: new Output.NodeSpan(el.parent), start: 0, end: 7},
347            {value: new Output.NodeSpan(el), start: 8, end: 16}],
348           o);
349   });
352 TEST_F('OutputE2ETest', 'Tree', function() {
353   this.runWithLoadedTree(function() {/*!
354     <ul role="tree">
355       <li aria-expanded="true" role="treeitem">a
356       <li role="treeitem">b
357       <li aria-expanded="false" role="treeitem">c
358     </ul>
359   */},
360   function(root) {
361     var el = root.firstChild.children[0].firstChild;
362     var range = cursors.Range.fromNode(el);
363     var o = new Output().withSpeechAndBraille(range, null, 'navigate');
364     assertEqualsJSON(
365         {string_: '|Tree|with 3 items|Tree item|Expanded| 1 of 3 | level 1 |a|',
366         spans_: [
367           // Enter rule.
369           // TreeItem.
370           {value: 'role','start': 19, end: 28},
371           {value: 'state', start: 29, end: 37},
373           // InLineTextBox.
374           {value: 'value', start: 57, end: 58},
375           {value: 'name', start: 59, end: 59}
376     ]}, o.speechOutputForTest);
377     // TODO(plundblad): Braille output is wrong.
378     checkBrailleOutput(
379         'tree +3 tritm - 1/3  level 1  a',
380         [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
381          {value: new Output.NodeSpan(el.parent), start: 8, end: 29},
382          {value: new Output.NodeSpan(el), start: 30, end: 31}],
383         o);
385     el = root.firstChild.children[1].firstChild;
386     var range = cursors.Range.fromNode(el);
387     var o = new Output().withSpeechAndBraille(range, null, 'navigate');
388     assertEqualsJSON(
389         {string_: '|Tree|with 3 items|Tree item| 2 of 3 | level 1 |b|',
390         spans_: [
391           // Enter rule.
393           // TreeItem.
394           {value: 'role','start': 19, end: 28},
396           // InLineTextBox.
397           {value: 'value', start: 48, end: 49},
398           {value: 'name', start: 50, end: 50}
399     ]}, o.speechOutputForTest);
400     // TODO(plundblad): Braille output is wrong.
401     checkBrailleOutput(
402         'tree +3 tritm 2/3  level 1  b',
403         [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
404          {value: new Output.NodeSpan(el.parent), start: 8, end: 27},
405          {value: new Output.NodeSpan(el), start: 28, end: 29}],
406         o);
408     el = root.firstChild.children[2].firstChild;
409     var range = cursors.Range.fromNode(el);
410     var o = new Output().withSpeechAndBraille(range, null, 'navigate');
411     assertEqualsJSON(
412         {string_: '|Tree|with 3 items|Tree item|Collapsed| 3 of 3 | level 1 |c|',
413         spans_: [
414           // Enter rule.
416           // TreeItem.
417           {value: 'role','start': 19, end: 28},
418           {value: 'state', start: 29, end: 38},
420           // InLineTextBox.
421           {value: 'value', start: 58, end: 59},
422           {value: 'name', start: 60, end: 60}
423     ]}, o.speechOutputForTest);
424     // TODO(plundblad): Braille output is wrong.
425     checkBrailleOutput(
426         'tree +3 tritm + 3/3  level 1  c',
427         [{value: new Output.NodeSpan(el.parent.parent), start: 0, end: 7},
428          {value: new Output.NodeSpan(el.parent), start: 8, end: 29},
429          {value: new Output.NodeSpan(el), start: 30, end: 31}],
430         o);
431   });
434 TEST_F('OutputE2ETest', 'Menu', function() {
435   this.runWithLoadedTree(function() {/*!
436     <div role="menu">
437       <div role="menuitem">a</div>
438     </div>
439   */},
440   function(root) {
441     var el = root.firstChild.firstChild;
442     var range = cursors.Range.fromNode(el);
443     var o = new Output().withSpeechAndBraille(range, null, 'navigate');
444     assertEqualsJSON({string_:
445             '|Menu|with 1 item|a|Menu item| 1 of 1 ', spans_: [
446         {value: 'name', start: 18, end: 19},
447         {value: 'role', start:20, end: 29}
448     ]}, o.speechOutputForTest);
449     checkBrailleOutput(
450         'mnu +1 a mnuitm 1/1',
451         [{value: new Output.NodeSpan(el.parent), start: 0, end: 6},
452          {value: new Output.NodeSpan(el), start: 7, end: 19}],
453         o);
454   });
457 TEST_F('OutputE2ETest', 'ListBox', function() {
458   this.runWithLoadedTree(function() {/*!
459     <select multiple>
460       <option>1</option>
461       <option>2</option>
462     </select>
463   */},
464   function(root) {
465     var el = root.firstChild.firstChild.firstChild;
466     var range = cursors.Range.fromNode(el);
467     var o = new Output().withSpeechAndBraille(range, null, 'navigate');
468     assertEqualsJSON({string_: '|List box|with 2 items||List item| 1 of 2 ',
469         spans_: [
470           // ListBox.
471           // Earcon.
472           {value: {earconId:'LISTBOX'}, start: 0, end: 0},
474           {value: 'name', start: 23, end: 23},
476           // Earcon.
477           {value: {earconId: 'LIST_ITEM'}, start: 23, end: 23},
479           {value: 'role', start:24, end: 33}
480     ]}, o.speechOutputForTest);
481     checkBrailleOutput(
482         'lstbx +2 lstitm 1/2',
483         [{value: new Output.NodeSpan(el.parent), start: 0, end: 8},
484          {value: new Output.NodeSpan(el), start: 9, end: 19}],
485         o);
486   });
489 SYNC_TEST_F('OutputE2ETest', 'MessageIdAndEarconValidity', function() {
490   for (var key in Output.ROLE_INFO_) {
491     var value = Output.ROLE_INFO_[key];
492     cvox.ChromeVox.msgs.getMsg(value.msgId);
493     cvox.ChromeVox.msgs.getMsg(value.msgId + '_brl');
494     assertFalse(/[A-Z]+/.test(value.msgId));
495     if (value.earconId)
496       assertNotNullNorUndefined(cvox.Earcon[value.earconId]);
497   }
498   for (var key in Output.STATE_INFO_) {
499     var value = Output.STATE_INFO_[key];
500     for (innerKey in value) {
501       var innerValue = value[innerKey];
502       cvox.ChromeVox.msgs.getMsg(innerValue.msgId);
503       cvox.ChromeVox.msgs.getMsg(innerValue.msgId + '_brl');
504       assertFalse(/[A-Z]+/.test(innerValue.msgId));
505       if (innerValue.earconId)
506         assertNotNullNorUndefined(cvox.Earcon[innerValue.earconId]);
507     }
508   }