1 // Copyright (c) 2013 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 5 function addTests() { 6 var currentTest = null; 7 8 function dispatchClick(element) { 9 element.dispatchEvent(new MouseEvent('click')); 10 } 11 12 function getVisibleElementByTagName(tag) { 13 var selector = '.function:not([hidden]) ' + tag; 14 return document.querySelector(selector); 15 } 16 17 function clickRadio(name) { 18 currentTest.log('Clicking ' + name + ' radio button.'); 19 dispatchClick(document.getElementById('radio_' + name)); 20 } 21 22 function setInputValue(value) { 23 currentTest.log('Setting input box to "' + value + '".'); 24 getVisibleElementByTagName('input').value = value; 25 } 26 27 function setTextareaValue(value) { 28 currentTest.log('Setting textarea to "' + value + '".'); 29 getVisibleElementByTagName('textarea').value = value; 30 } 31 32 function getTextareaValue() { 33 return getVisibleElementByTagName('textarea').value; 34 } 35 36 function getLastLogMessage() { 37 var logEl = document.getElementById('log'); 38 var logLines = logEl.textContent.split('\n'); 39 return logLines[logLines.length - 1]; 40 } 41 42 function waitForLog(logMessage, onLogChanged, onError) { 43 // First see if the message we want is already there. 44 if (getLastLogMessage() === logMessage) { 45 onLogChanged(); 46 return; 47 } 48 49 // Clear the log. This prevents a previous failure from propagating to the 50 // current check. (NOTE: the log is backed by an array, so as soon as a 51 // message is logged it will be refilled with its previous data in addition 52 // to the new message.) 53 document.getElementById('log').textContent = ''; 54 55 // Poll for log changes. 56 var intervalId = window.setInterval(function() { 57 var lastLogMessage = getLastLogMessage(); 58 59 if (lastLogMessage.lastIndexOf('Error:', 0) === 0) { 60 window.clearInterval(intervalId); 61 if (onError) { 62 currentTest.log('Got error message, continuing.'); 63 onError(); 64 } else { 65 currentTest.fail('Unexpected failure waiting for log change.'); 66 } 67 68 return; 69 } 70 71 if (logMessage !== lastLogMessage) 72 return; 73 74 currentTest.log('Got log message, continuing.'); 75 window.clearInterval(intervalId); 76 onLogChanged(); 77 }, 100); 78 } 79 80 function clickExecuteButtonAndWaitForLog(logMessage, onLogChanged, onError) { 81 waitForLog(logMessage, onLogChanged, onError); 82 currentTest.log('Clicking button.'); 83 dispatchClick(getVisibleElementByTagName('button')); 84 currentTest.log('Waiting for log message: "' + logMessage + '".'); 85 } 86 87 function isFilenameInDirectoryList(filename) { 88 var listItemEls = document.querySelectorAll('#listDirOutput li'); 89 90 currentTest.log('Looking for ' + filename); 91 for (var i = 0; i < listItemEls.length; ++i) { 92 var itemText = listItemEls[i].textContent; 93 currentTest.log('Found ' + itemText); 94 if (itemText === filename) { 95 return true; 96 } 97 } 98 99 return false; 100 } 101 102 function saveFile(filename, fileText, onFileSaved, onError) { 103 clickRadio('saveFile'); 104 setInputValue(filename); 105 setTextareaValue(fileText); 106 clickExecuteButtonAndWaitForLog('Save success', onFileSaved, onError); 107 } 108 109 function loadFile(filename, onFileLoaded, onError) { 110 clickRadio('loadFile'); 111 setInputValue(filename); 112 setTextareaValue(''); // Clear the textarea. 113 clickExecuteButtonAndWaitForLog('Load success', onFileLoaded, onError); 114 } 115 116 function deleteFile(filename, onFileDeleted, onError) { 117 clickRadio('delete'); 118 setInputValue(filename); 119 clickExecuteButtonAndWaitForLog('Delete success', onFileDeleted, onError); 120 } 121 122 function listDir(dirname, onDirectoryListed, onError) { 123 clickRadio('listDir'); 124 setInputValue(dirname); 125 clickExecuteButtonAndWaitForLog('List success', onDirectoryListed, onError); 126 } 127 128 function makeDir(dirname, onDirectoryMade, onError) { 129 clickRadio('makeDir'); 130 setInputValue(dirname); 131 clickExecuteButtonAndWaitForLog('Make directory success', 132 onDirectoryMade, onError); 133 } 134 135 function expectEq(expected, actual, additionalInfo) { 136 var message; 137 if (expected !== actual) { 138 if (additionalInfo) 139 message = additionalInfo + ': '; 140 message += 'Expected "' + expected + '", got "' + actual + '".'; 141 currentTest.fail(message); 142 } else { 143 message = 'OK, "' + expected + '" === "' + actual + '".'; 144 currentTest.log(message); 145 } 146 } 147 148 function expectContains(needle, haystack, additionalInfo) { 149 if (haystack.indexOf(needle) === -1) { 150 if (additionalInfo) 151 message = additionalInfo + ': '; 152 message += 'Expected to find "' + needle + '" in "' + haystack + '".'; 153 currentTest.fail(message); 154 } else { 155 message = 'OK, "' + needle + '" in "' + haystack + '".'; 156 currentTest.log(message); 157 } 158 } 159 160 function expectFilenameInDirectoryList(filename, additionalInfo) { 161 if (!isFilenameInDirectoryList(filename)) { 162 if (additionalInfo) 163 message = additionalInfo + ': '; 164 message += 'Expected to find "' + filename + '" in directory list.'; 165 currentTest.fail(message); 166 } else { 167 message = 'OK, found "' + filename + ' in the directory list.'; 168 currentTest.log(message); 169 } 170 } 171 172 common.tester.addAsyncTest('filesystem_ready', function(test) { 173 // This is a bit fragile; we rely on this test being run first (and 174 // completing) before we can run any of the other tests. 175 currentTest = test; 176 waitForLog('Filesystem ready!', function() { 177 test.pass(); 178 }, function() { 179 test.fail('Got unexpected error waiting for filesystem: '); 180 }); 181 }); 182 183 common.tester.addAsyncTest('save_and_load', function(test) { 184 currentTest = test; 185 var filename = '/save_and_load.txt'; 186 var fileText = 'A penny saved is a penny earned.'; 187 188 // Save the file. 189 saveFile(filename, fileText, function() { 190 // Now try to load it. 191 loadFile(filename, function() { 192 // Make sure the text matches. 193 expectEq(fileText, getTextareaValue(), 'Incorrect textarea'); 194 test.pass(); 195 }); 196 }); 197 }); 198 199 common.tester.addAsyncTest('delete_file', function(test) { 200 currentTest = test; 201 var filename = '/delete_file.txt'; 202 203 saveFile(filename, 'Here today, gone tomorrow.', function() { 204 deleteFile(filename, function() { 205 loadFile(filename, function() { 206 test.fail('Unexpected load success.'); 207 }, 208 function() { 209 expectEq('', getTextareaValue(), 'Unexpected data in file'); 210 expectContains('File not found', getLastLogMessage(), 211 'Unexpected log message'); 212 test.pass(); 213 }); 214 }); 215 }); 216 }); 217 218 common.tester.addAsyncTest('list_directory', function(test) { 219 currentTest = test; 220 var filename = '/list_directory.txt'; 221 222 saveFile(filename, 'I\'ve got a little list...', function() { 223 listDir('/', function() { 224 // Directory listings are relative, so it will not have the leading 225 // slash. 226 var relativeFilename = filename.slice(1); 227 expectFilenameInDirectoryList(relativeFilename); 228 test.pass(); 229 }); 230 }); 231 }); 232 233 common.tester.addAsyncTest('make_directory', function(test) { 234 currentTest = test; 235 var dirname = '/new_directory'; 236 237 makeDir(dirname, function() { 238 listDir('/', function() { 239 // Directory listings are relative, so it will not have the leading 240 // slash. 241 var relativeDirname = dirname.slice(1); 242 expectFilenameInDirectoryList(relativeDirname); 243 244 // Let's see if the file can be written to this directory. 245 var filename = dirname + '/file.txt'; 246 var fileText = 'A file within a directory.'; 247 saveFile(filename, fileText, function() { 248 test.pass(); 249 }); 250 }); 251 }); 252 }); 253 } 254