Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / test / data / extensions / api_test / file_manager_browsertest / file_manager / background.js
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
5 'use strict';
6
7 /**
8  * Extension ID of Files.app.
9  * @type {string}
10  * @const
11  */
12 var FILE_MANAGER_EXTENSIONS_ID = 'hhaomjibdihmijegdhdafkllkbggdgoj';
13
14 var remoteCall = new RemoteCallFilesApp(FILE_MANAGER_EXTENSIONS_ID);
15
16 /**
17  * Extension ID of Audio Player.
18  * @type {string}
19  * @const
20  */
21 var AUDIO_PLAYER_APP_ID = 'cjbfomnbifhcdnihkgipgfcihmgjfhbf';
22
23 var audioPlayerApp = new RemoteCall(AUDIO_PLAYER_APP_ID);
24
25 /**
26  * Adds check of chrome.test to the end of the given promise.
27  * @param {Promise} promise Promise.
28  */
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.
35   }), function(error) {
36     chrome.test.fail(error.stack || error);
37   });
38 };
39
40 /**
41  * Executes a sequence of test steps.
42  * @constructor
43  */
44 function StepsRunner() {
45   /**
46    * List of steps.
47    * @type {Array.<function>}
48    * @private
49    */
50   this.steps_ = [];
51 }
52
53 /**
54  * Creates a StepsRunner instance and runs the passed steps.
55  */
56 StepsRunner.run = function(steps) {
57   var stepsRunner = new StepsRunner();
58   stepsRunner.run_(steps);
59 };
60
61 StepsRunner.prototype = {
62   /**
63    * @return {function} The next closure.
64    */
65   get next() {
66     return this.steps_[0];
67   }
68 };
69
70 /**
71  * Runs a sequence of the added test steps.
72  * @type {Array.<function>} List of the sequential steps.
73  */
74 StepsRunner.prototype.run_ = function(steps) {
75   this.steps_ = steps.slice(0);
76
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() {});
80
81   this.steps_ = this.steps_.map(function(f) {
82     return chrome.test.callbackPass(function() {
83       this.steps_.shift();
84       f.apply(this, arguments);
85     }.bind(this));
86   }.bind(this));
87
88   this.next();
89 };
90
91 /**
92  * Basic entry set for the local volume.
93  * @type {Array.<TestEntryInfo>}
94  * @const
95  */
96 var BASIC_LOCAL_ENTRY_SET = [
97   ENTRIES.hello,
98   ENTRIES.world,
99   ENTRIES.desktop,
100   ENTRIES.beautiful,
101   ENTRIES.photos
102 ];
103
104 /**
105  * Basic entry set for the drive volume.
106  *
107  * TODO(hirono): Add a case for an entry cached by FileCache. For testing
108  *               Drive, create more entries with Drive specific attributes.
109  *
110  * @type {Array.<TestEntryInfo>}
111  * @const
112  */
113 var BASIC_DRIVE_ENTRY_SET = [
114   ENTRIES.hello,
115   ENTRIES.world,
116   ENTRIES.desktop,
117   ENTRIES.beautiful,
118   ENTRIES.photos,
119   ENTRIES.unsupported,
120   ENTRIES.testDocument,
121   ENTRIES.testSharedDocument
122 ];
123
124 var NESTED_ENTRY_SET = [
125   ENTRIES.directoryA,
126   ENTRIES.directoryB,
127   ENTRIES.directoryC
128 ];
129
130 /**
131  * Expecetd list of preset entries in fake test volumes. This should be in sync
132  * with FakeTestVolume::PrepareTestEntries in the test harness.
133  *
134  * @type {Array.<TestEntryInfo>}
135  * @const
136  */
137 var BASIC_FAKE_ENTRY_SET = [
138   ENTRIES.hello,
139   ENTRIES.directoryA
140 ];
141
142 /**
143  * Expected files shown in "Recent". Directories (e.g. 'photos') are not in this
144  * list as they are not expected in "Recent".
145  *
146  * @type {Array.<TestEntryInfo>}
147  * @const
148  */
149 var RECENT_ENTRY_SET = [
150   ENTRIES.hello,
151   ENTRIES.world,
152   ENTRIES.desktop,
153   ENTRIES.beautiful,
154   ENTRIES.unsupported,
155   ENTRIES.testDocument,
156   ENTRIES.testSharedDocument
157 ];
158
159 /**
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".
163  *
164  * @type {Array.<TestEntryInfo>}
165  * @const
166  */
167 var OFFLINE_ENTRY_SET = [
168   ENTRIES.testDocument,
169   ENTRIES.testSharedDocument
170 ];
171
172 /**
173  * Expected files shown in "Shared with me", which should be the entries labeled
174  * with "shared-with-me".
175  *
176  * @type {Array.<TestEntryInfo>}
177  * @const
178  */
179 var SHARED_WITH_ME_ENTRY_SET = [
180   ENTRIES.testSharedDocument
181 ];
182
183 /**
184  * Opens a Files.app's main window.
185  *
186  * TODO(mtomasz): Pass a volumeId or an enum value instead of full paths.
187  *
188  * @param {Object} appState App state to be passed with on opening Files.app.
189  *     Can be null.
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.
194  */
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 || {};
200   if (initialRoot) {
201     processedAppState.currentDirectoryURL =
202         'filesystem:chrome-extension://' + FILE_MANAGER_EXTENSIONS_ID +
203         '/external' + initialRoot;
204   }
205
206   return remoteCall.callRemoteTestUtil('openMainWindow',
207                                        null,
208                                        [processedAppState],
209                                        opt_callback);
210 }
211
212 /**
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.
215  *
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.
218  *
219  * @param {Object} appState App state to be passed with on opening Files.app.
220  *     Can be null.
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.
226  */
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').
233       then(function() {
234         // Wait until the elements are loaded in the table.
235         return remoteCall.waitForFileListChange(windowId, 0);
236       });
237   });
238
239   if (opt_callback)
240     opt_callback = chrome.test.callbackPass(opt_callback);
241
242   return Promise.all([
243     windowPromise,
244     localEntriesPromise,
245     driveEntriesPromise,
246     detailedTablePromise
247   ]).then(function(results) {
248     if (opt_callback)
249       opt_callback(results[0], results[3]);
250     return results[0];
251   }).catch(function(e) {
252     chrome.test.fail(e.stack || e);
253   });
254 }
255
256 /**
257  * Verifies if there are no Javascript errors in any of the app windows.
258  * @param {function()} Completion callback.
259  */
260 function checkIfNoErrorsOccured(callback) {
261   remoteCall.callRemoteTestUtil('getErrorCount', null, [], function(count) {
262     chrome.test.assertEq(0, count, 'The error count is not 0.');
263     callback();
264   });
265 }
266
267 /**
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.
271  */
272 function getFileName(fileListEntry) {
273   return fileListEntry[0];
274 }
275
276 /**
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.
280  */
281 function getFileSize(fileListEntry) {
282   return fileListEntry[1];
283 }
284
285 /**
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.
289  */
290 function getFileType(fileListEntry) {
291   return fileListEntry[2];
292 }
293
294 /**
295  * Namespace for test cases.
296  */
297 var testcase = {};
298
299 // Ensure the test cases are loaded.
300 window.addEventListener('load', function() {
301   var steps = [
302     // Check for the guest mode.
303     function() {
304       chrome.test.sendMessage(
305           JSON.stringify({name: 'isInGuestMode'}), steps.shift());
306     },
307     // Obtain the test case name.
308     function(result) {
309       if (JSON.parse(result) != chrome.extension.inIncognitoContext)
310         return;
311       chrome.test.sendMessage(
312           JSON.stringify({name: 'getRootPaths'}), steps.shift());
313     },
314     // Obtain the root entry paths.
315     function(result) {
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());
321     },
322     // Run the test case.
323     function(testCaseName) {
324       var targetTest = testcase[testCaseName];
325       if (!targetTest) {
326         chrome.test.fail(testCaseName + ' is not found.');
327         return;
328       }
329       // Specify the name of test to the test system.
330       targetTest.generatedName = testCaseName;
331       chrome.test.runTests([targetTest]);
332     }
333   ];
334   steps.shift()();
335 });