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.
8 * Extension ID of Files.app.
12 var FILE_MANAGER_EXTENSIONS_ID = 'hhaomjibdihmijegdhdafkllkbggdgoj';
14 var remoteCall = new RemoteCallFilesApp(FILE_MANAGER_EXTENSIONS_ID);
17 * Extension ID of Audio Player.
21 var AUDIO_PLAYER_APP_ID = 'cjbfomnbifhcdnihkgipgfcihmgjfhbf';
23 var audioPlayerApp = new RemoteCall(AUDIO_PLAYER_APP_ID);
26 * Adds check of chrome.test to the end of the given promise.
27 * @param {Promise} promise Promise.
29 function testPromise(promise) {
30 promise.then(function() {
31 return new Promise(checkIfNoErrorsOccured);
32 }).then(chrome.test.callbackPass(function() {
33 // The callbacPass is necessary to avoid prematurely finishing tests.
34 // Don't put chrome.test.succeed() here to avoid doubled success log.
36 chrome.test.fail(error.stack || error);
41 * Executes a sequence of test steps.
44 function StepsRunner() {
47 * @type {Array.<function>}
54 * Creates a StepsRunner instance and runs the passed steps.
56 StepsRunner.run = function(steps) {
57 var stepsRunner = new StepsRunner();
58 stepsRunner.run_(steps);
61 StepsRunner.prototype = {
63 * @return {function} The next closure.
66 return this.steps_[0];
71 * Runs a sequence of the added test steps.
72 * @type {Array.<function>} List of the sequential steps.
74 StepsRunner.prototype.run_ = function(steps) {
75 this.steps_ = steps.slice(0);
77 // An extra step which acts as an empty callback for optional asynchronous
78 // calls in the last provided step.
79 this.steps_.push(function() {});
81 this.steps_ = this.steps_.map(function(f) {
82 return chrome.test.callbackPass(function() {
84 f.apply(this, arguments);
92 * Basic entry set for the local volume.
93 * @type {Array.<TestEntryInfo>}
96 var BASIC_LOCAL_ENTRY_SET = [
105 * Basic entry set for the drive volume.
107 * TODO(hirono): Add a case for an entry cached by FileCache. For testing
108 * Drive, create more entries with Drive specific attributes.
110 * @type {Array.<TestEntryInfo>}
113 var BASIC_DRIVE_ENTRY_SET = [
120 ENTRIES.testDocument,
121 ENTRIES.testSharedDocument
124 var NESTED_ENTRY_SET = [
131 * Expecetd list of preset entries in fake test volumes. This should be in sync
132 * with FakeTestVolume::PrepareTestEntries in the test harness.
134 * @type {Array.<TestEntryInfo>}
137 var BASIC_FAKE_ENTRY_SET = [
143 * Expected files shown in "Recent". Directories (e.g. 'photos') are not in this
144 * list as they are not expected in "Recent".
146 * @type {Array.<TestEntryInfo>}
149 var RECENT_ENTRY_SET = [
155 ENTRIES.testDocument,
156 ENTRIES.testSharedDocument
160 * Expected files shown in "Offline", which should have the files
161 * "available offline". Google Documents, Google Spreadsheets, and the files
162 * cached locally are "available offline".
164 * @type {Array.<TestEntryInfo>}
167 var OFFLINE_ENTRY_SET = [
168 ENTRIES.testDocument,
169 ENTRIES.testSharedDocument
173 * Expected files shown in "Shared with me", which should be the entries labeled
174 * with "shared-with-me".
176 * @type {Array.<TestEntryInfo>}
179 var SHARED_WITH_ME_ENTRY_SET = [
180 ENTRIES.testSharedDocument
184 * Opens a Files.app's main window.
186 * TODO(mtomasz): Pass a volumeId or an enum value instead of full paths.
188 * @param {Object} appState App state to be passed with on opening Files.app.
190 * @param {?string} initialRoot Root path to be used as a default current
191 * directory during initialization. Can be null, for no default path.
192 * @param {function(string)=} opt_callback Callback with the app id.
193 * @return {Promise} Promise to be fulfilled after window creating.
195 function openNewWindow(appState, initialRoot, opt_callback) {
196 // TODO(mtomasz): Migrate from full paths to a pair of a volumeId and a
197 // relative path. To compose the URL communicate via messages with
198 // file_manager_browser_test.cc.
199 var processedAppState = appState || {};
201 processedAppState.currentDirectoryURL =
202 'filesystem:chrome-extension://' + FILE_MANAGER_EXTENSIONS_ID +
203 '/external' + initialRoot;
206 return remoteCall.callRemoteTestUtil('openMainWindow',
213 * Opens a Files.app's main window and waits until it is initialized. Fills
214 * the window with initial files. Should be called for the first window only.
216 * TODO(hirono): Add parameters to specify the entry set to be prepared.
217 * TODO(mtomasz): Pass a volumeId or an enum value instead of full paths.
219 * @param {Object} appState App state to be passed with on opening Files.app.
221 * @param {?string} initialRoot Root path to be used as a default current
222 * directory during initialization. Can be null, for no default path.
223 * @param {function(string, Array.<Array.<string>>)=} opt_callback Callback with
224 * the window ID and with the file list.
225 * @return {Promise} Promise to be fulfilled with window ID.
227 function setupAndWaitUntilReady(appState, initialRoot, opt_callback) {
228 var windowPromise = openNewWindow(appState, initialRoot);
229 var localEntriesPromise = addEntries(['local'], BASIC_LOCAL_ENTRY_SET);
230 var driveEntriesPromise = addEntries(['drive'], BASIC_DRIVE_ENTRY_SET);
231 var detailedTablePromise = windowPromise.then(function(windowId) {
232 return remoteCall.waitForElement(windowId, '#detail-table').
234 // Wait until the elements are loaded in the table.
235 return remoteCall.waitForFileListChange(windowId, 0);
240 opt_callback = chrome.test.callbackPass(opt_callback);
247 ]).then(function(results) {
249 opt_callback(results[0], results[3]);
251 }).catch(function(e) {
252 chrome.test.fail(e.stack || e);
257 * Verifies if there are no Javascript errors in any of the app windows.
258 * @param {function()} Completion callback.
260 function checkIfNoErrorsOccured(callback) {
261 remoteCall.callRemoteTestUtil('getErrorCount', null, [], function(count) {
262 chrome.test.assertEq(0, count, 'The error count is not 0.');
268 * Returns the name of the given file list entry.
269 * @param {Array.<string>} file An entry in a file list.
270 * @return {string} Name of the file.
272 function getFileName(fileListEntry) {
273 return fileListEntry[0];
277 * Returns the size of the given file list entry.
278 * @param {Array.<string>} An entry in a file list.
279 * @return {string} Size of the file.
281 function getFileSize(fileListEntry) {
282 return fileListEntry[1];
286 * Returns the type of the given file list entry.
287 * @param {Array.<string>} An entry in a file list.
288 * @return {string} Type of the file.
290 function getFileType(fileListEntry) {
291 return fileListEntry[2];
295 * Namespace for test cases.
299 // Ensure the test cases are loaded.
300 window.addEventListener('load', function() {
302 // Check for the guest mode.
304 chrome.test.sendMessage(
305 JSON.stringify({name: 'isInGuestMode'}), steps.shift());
307 // Obtain the test case name.
309 if (JSON.parse(result) != chrome.extension.inIncognitoContext)
311 chrome.test.sendMessage(
312 JSON.stringify({name: 'getRootPaths'}), steps.shift());
314 // Obtain the root entry paths.
316 var roots = JSON.parse(result);
317 RootPath.DOWNLOADS = roots.downloads;
318 RootPath.DRIVE = roots.drive;
319 chrome.test.sendMessage(
320 JSON.stringify({name: 'getTestName'}), steps.shift());
322 // Run the test case.
323 function(testCaseName) {
324 var targetTest = testcase[testCaseName];
326 chrome.test.fail(testCaseName + ' is not found.');
329 // Specify the name of test to the test system.
330 targetTest.generatedName = testCaseName;
331 chrome.test.runTests([targetTest]);