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. 4 5GEN_INCLUDE([ 6 'chrome/browser/resources/chromeos/chromevox/testing/assert_additions.js']); 7 8/** 9 * Shortcut for document.getElementById. 10 * @param {string} id of the element. 11 * @return {HTMLElement} with the id. 12 */ 13function $(id) { 14 return document.getElementById(id); 15} 16 17/** 18 * Base test fixture for ChromeVox unit tests. 19 * 20 * Note that while conceptually these are unit tests, these tests need 21 * to run in a full web page, so they're actually run as WebUI browser 22 * tests. 23 * 24 * @constructor 25 * @extends {testing.Test} 26 */ 27function ChromeVoxUnitTestBase() {} 28 29ChromeVoxUnitTestBase.prototype = { 30 __proto__: testing.Test.prototype, 31 32 /** @override */ 33 closureModuleDeps: [ 34 'cvox.ChromeVoxTester', 35 'cvox.ChromeVoxUserCommands', 36 'cvox.SpokenListBuilder', 37 ], 38 39 /** @override */ 40 browsePreload: DUMMY_URL, 41 42 /** 43 * @override 44 * It doesn't make sense to run the accessibility audit on these tests, 45 * since many of them are deliberately testing inaccessible html. 46 */ 47 runAccessibilityChecks: false, 48 49 /** 50 * Loads some inlined html into the body of the current document, replacing 51 * whatever was there previously. 52 * @param {string} html The html to load as a string. 53 */ 54 loadHtml: function(html) { 55 while (document.head.firstChild) { 56 document.head.removeChild(document.head.firstChild); 57 } 58 while (document.body.firstChild) { 59 document.body.removeChild(document.body.firstChild); 60 } 61 this.appendHtml(html); 62 }, 63 64 /** 65 * Loads some inlined html into the current document, replacing 66 * whatever was there previously. This version takes the html 67 * encoded as a comment inside a function, so you can use it like this: 68 * 69 * this.loadDoc(function() {/*! 70 * <p>Html goes here</p> 71 * * /}); 72 * 73 * @param {Function} commentEncodedHtml The html to load, embedded as a 74 * comment inside an anonymous function - see example, above. 75 */ 76 loadDoc: function(commentEncodedHtml) { 77 var html = this.extractHtmlFromCommentEncodedString_(commentEncodedHtml); 78 this.loadHtml(html); 79 }, 80 81 /** 82 * Appends some inlined html into the current document, at the end of 83 * the body element. Takes the html encoded as a comment inside a function, 84 * so you can use it like this: 85 * 86 * this.appendDoc(function() {/*! 87 * <p>Html goes here</p> 88 * * /}); 89 * 90 * @param {Function} commentEncodedHtml The html to load, embedded as a 91 * comment inside an anonymous function - see example, above. 92 */ 93 appendDoc: function(commentEncodedHtml) { 94 var html = this.extractHtmlFromCommentEncodedString_(commentEncodedHtml); 95 this.appendHtml(html); 96 }, 97 98 /** 99 * Appends some inlined html into the current document, at the end of 100 * the body element. 101 * @param {string} html The html to load as a string. 102 */ 103 appendHtml: function(html) { 104 var div = document.createElement('div'); 105 div.innerHTML = html; 106 var fragment = document.createDocumentFragment(); 107 while (div.firstChild) { 108 fragment.appendChild(div.firstChild); 109 } 110 document.body.appendChild(fragment); 111 }, 112 113 /** 114 * Extracts some inlined html encoded as a comment inside a function, 115 * so you can use it like this: 116 * 117 * this.appendDoc(function() {/*! 118 * <p>Html goes here</p> 119 * * /}); 120 * 121 * @param {Function} commentEncodedHtml The html , embedded as a 122 * comment inside an anonymous function - see example, above. 123 @ @return {String} The html text. 124 */ 125 extractHtmlFromCommentEncodedString_: function(commentEncodedHtml) { 126 return commentEncodedHtml.toString(). 127 replace(/^[^\/]+\/\*!?/, ''). 128 replace(/\*\/[^\/]+$/, ''); 129 }, 130 131 /** 132 * Waits for the queued events in ChromeVoxEventWatcher to be 133 * handled, then calls a callback function with provided arguments 134 * in the test case scope. Very useful for asserting the results of events. 135 * 136 * @param {function()} func A function to call when ChromeVox is ready. 137 * @param {*} var_args Additional arguments to pass through to the function. 138 * @return {ChromeVoxUnitTestBase} this. 139 */ 140 waitForCalm: function(func, var_args) { 141 var me = this; 142 var calmArguments = Array.prototype.slice.call(arguments); 143 calmArguments.shift(); 144 cvox.ChromeVoxEventWatcher.addReadyCallback(function() { 145 func.apply(me, calmArguments); 146 }); 147 return this; // for chaining. 148 }, 149 150 /** 151 * Asserts the TTS engine spoke a certain string. Clears the TTS buffer. 152 * @param {string} expectedText The expected text. 153 * @return {ChromeVoxUnitTestBase} this. 154 */ 155 assertSpoken: function(expectedText) { 156 assertEquals(expectedText, 157 cvox.ChromeVoxTester.testTts().getUtterancesAsString()); 158 cvox.ChromeVoxTester.clearUtterances(); 159 return this; // for chaining. 160 }, 161 162 /** 163 * Asserts a list of utterances are in the correct queue mode. 164 * @param {cvox.SpokenListBuilder|Array} expectedList A list 165 * of [text, queueMode] tuples OR a SpokenListBuilder with the expected 166 * utterances. 167 * @return {ChromeVoxUnitTestBase} this. 168 */ 169 assertSpokenList: function(expectedList) { 170 if (expectedList instanceof cvox.SpokenListBuilder) { 171 expectedList = expectedList.build(); 172 } 173 174 var ulist = cvox.ChromeVoxTester.testTts().getUtteranceInfoList(); 175 for (var i = 0; i < expectedList.length; i++) { 176 var text = expectedList[i][0]; 177 var queueMode = expectedList[i][1]; 178 this.assertSingleUtterance_(text, queueMode, 179 ulist[i].text, ulist[i].queueMode); 180 } 181 cvox.ChromeVoxTester.clearUtterances(); 182 return this; // for chaining. 183 }, 184 185 assertSingleUtterance_: function( 186 expectedText, expectedQueueMode, text, queueMode) { 187 assertEquals(expectedQueueMode, queueMode); 188 assertEquals(expectedText, text); 189 }, 190 191 /** 192 * Focuses an element. 193 * @param {string} id The id of the element to focus. 194 * @return {ChromeVoxUnitTestBase} this. 195 */ 196 setFocus: function(id) { 197 $(id).focus(); 198 return this; // for chaining. 199 }, 200 201 /** 202 * Executes a ChromeVox user command. 203 * @param {string} command The name of the command to run. 204 * @return {ChromeVoxUnitTestBase} this. 205 */ 206 userCommand: function(command) { 207 cvox.ChromeVoxUserCommands.commands[command](); 208 return this; // for chaining. 209 }, 210 211 /** 212 * @return {cvox.SpokenListBuilder} A new builder. 213 */ 214 spokenList: function() { 215 return new cvox.SpokenListBuilder(); 216 } 217}; 218