Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: chrome/test/data/extensions/api_test/file_manager_browsertest/background.js

Issue 304683002: Add the browser test for the new gallery. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 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 /**
15 * Calls a remote test util in Files.app's extension. See: test_util.js.
16 *
17 * @param {string} func Function name.
18 * @param {?string} appId Target window's App ID or null for functions
19 * not requiring a window.
20 * @param {Array.<*>} args Array of arguments.
21 * @param {function(*)=} opt_callback Callback handling the function's result.
22 * @return {Promise} Promise to be fulfilled with the result of the remote
23 * utility.
24 */
25 function callRemoteTestUtil(func, appId, args, opt_callback) {
26 return new Promise(function(onFulfilled) {
27 chrome.runtime.sendMessage(
28 FILE_MANAGER_EXTENSIONS_ID, {
29 func: func,
30 appId: appId,
31 args: args
32 },
33 function() {
34 if (opt_callback)
35 opt_callback.apply(null, arguments);
36 onFulfilled(arguments[0]);
37 });
38 });
39 }
40
41 /**
42 * Returns promise to be fulfilled after the given milliseconds.
43 * @param {number} time Time in milliseconds.
44 */
45 function wait(time) {
46 return new Promise(function(callback) {
47 setTimeout(callback, time);
48 });
49 }
50
51 /**
52 * Interval milliseconds between checks of repeatUntil.
53 * @type {number}
54 * @const
55 */
56 var REPEAT_UNTIL_INTERVAL = 200;
57
58 /**
59 * Interval milliseconds between log output of repeatUntil.
60 * @type {number}
61 * @const
62 */
63 var LOG_INTERVAL = 3000;
64
65 /**
66 * Returns a pending marker. See also the repeatUntil function.
67 * @param {string} message Pending reason including %s, %d, or %j markers. %j
68 * format an object as JSON.
69 * @param {Array.<*>} var_args Values to be assigined to %x markers.
70 * @return {Object} Object which returns true for the expression: obj instanceof
71 * pending.
72 */
73 function pending(message, var_args) {
74 var index = 1;
75 var args = arguments;
76 var formattedMessage = message.replace(/%[sdj]/g, function(pattern) {
77 var arg = args[index++];
78 switch(pattern) {
79 case '%s': return String(arg);
80 case '%d': return Number(arg);
81 case '%j': return JSON.stringify(arg);
82 default: return pattern;
83 }
84 });
85 var pendingMarker = Object.create(pending.prototype);
86 pendingMarker.message = formattedMessage;
87 return pendingMarker;
88 };
89
90 /**
91 * Waits until the checkFunction returns a value but a pending marker.
92 * @param {function():*} checkFunction Function to check a condition. It can
93 * return a pending marker created by a pending function.
94 * @return {Promise} Promise to be fulfilled with the return value of
95 * checkFunction when the checkFunction reutrns a value but a pending
96 * marker.
97 */
98 function repeatUntil(checkFunction) {
99 var logTime = Date.now() + LOG_INTERVAL;
100 var step = function() {
101 return checkFunction().then(function(result) {
102 if (result instanceof pending) {
103 if (Date.now() > logTime) {
104 console.log(result.message);
105 logTime += LOG_INTERVAL;
106 }
107 return wait(REPEAT_UNTIL_INTERVAL).then(step);
108 } else {
109 return result;
110 }
111 });
112 };
113 return step();
114 };
115
116 /**
117 * Waits until a window having the given ID prefix appears.
118 * @param {string} windowIdPrefix ID prefix of the requested window.
119 * @return {Promise} promise Promise to be fulfilled with a found window's ID.
120 */
121 function waitForWindow(windowIdPrefix) {
122 return repeatUntil(function() {
123 return callRemoteTestUtil('getWindows', null, []).then(function(windows) {
124 for (var id in windows) {
125 if (id.indexOf(windowIdPrefix) === 0)
126 return id;
127 }
128 return pending('Window with the prefix %s is not found.', windowIdPrefix);
129 });
130 });
131 }
132
133 /**
134 * Closes a window and waits until the window is closed.
135 *
136 * @param {string} windowId ID of the window to close.
137 * @return {Promise} promise Promise to be fulfilled with the result (true:
138 * success, false: failed).
139 */
140 function closeWindowAndWait(windowId) {
141 // Closes the window.
142 return callRemoteTestUtil('closeWindow', null, [windowId]).then(
143 function(result) {
144 // Returns false when the closing is failed.
145 if (!result)
146 return false;
147
148 return repeatUntil(function() {
149 return callRemoteTestUtil('getWindows', null, []).then(
150 function(windows) {
151 for (var id in windows) {
152 if (id === windowId) {
153 // Window is still available. Continues waiting.
154 return pending('Window with the prefix %s is not found.',
155 windowId);
156 }
157 }
158 // Window is not available. Closing is done successfully.
159 return true;
160 }
161 );
162 });
163 }
164 );
165 }
166
167 /**
168 * Waits until the window turns to the given size.
169 * @param {string} windowId Target window ID.
170 * @param {number} width Requested width in pixels.
171 * @param {number} height Requested height in pixels.
172 */
173 function waitForWindowGeometry(windowId, width, height) {
174 return repeatUntil(function() {
175 return callRemoteTestUtil('getWindows', null, []).then(function(windows) {
176 if (!windows[windowId])
177 return pending('Window %s is not found.', windowId);
178 if (windows[windowId].innerWidth !== width ||
179 windows[windowId].innerHeight !== height) {
180 return pending('Expected window size is %j, but it is %j',
181 {width: width, height: height},
182 windows[windowId]);
183 }
184 });
185 });
186 }
187
188 /**
189 * Waits for the specified element appearing in the DOM.
190 * @param {string} windowId Target window ID.
191 * @param {string} query Query string for the element.
192 * @param {string=} opt_iframeQuery Query string for the iframe containing the
193 * element.
194 * @return {Promise} Promise to be fulfilled when the element appears.
195 */
196 function waitForElement(windowId, query, opt_iframeQuery) {
197 return repeatUntil(function() {
198 return callRemoteTestUtil(
199 'queryAllElements',
200 windowId,
201 [query, opt_iframeQuery]
202 ).then(function(elements) {
203 if (elements.length > 0)
204 return elements[0];
205 else
206 return pending(
207 'Element %s (maybe in iframe %s) is not found.',
208 query,
209 opt_iframeQuery);
210 });
211 });
212 }
213
214 /**
215 * Waits for the specified element leaving from the DOM.
216 * @param {string} windowId Target window ID.
217 * @param {string} query Query string for the element.
218 * @param {string=} opt_iframeQuery Query string for the iframe containing the
219 * element.
220 * @return {Promise} Promise to be fulfilled when the element is lost.
221 */
222 function waitForElementLost(windowId, query, opt_iframeQuery) {
223 return repeatUntil(function() {
224 return callRemoteTestUtil(
225 'queryAllElements',
226 windowId,
227 [query, opt_iframeQuery]
228 ).then(function(elements) {
229 if (elements.length > 0)
230 return pending('Elements %j is still exists.', elements);
231 return true;
232 });
233 });
234 }
235
236 /**
237 /**
238 * Waits for the file list turns to the given contents.
239 * @param {string} windowId Target window ID.
240 * @param {Array.<Array.<string>>} expected Expected contents of file list.
241 * @param {{orderCheck:boolean=, ignoreLastModifiedTime:boolean=}=} opt_options
242 * Options of the comparison. If orderCheck is true, it also compares the
243 * order of files. If ignoreLastModifiedTime is true, it compares the file
244 * without its last modified time.
245 * @return {Promise} Promise to be fulfilled when the file list turns to the
246 * given contents.
247 */
248 function waitForFiles(windowId, expected, opt_options) {
249 var options = opt_options || {};
250 return repeatUntil(function() {
251 return callRemoteTestUtil(
252 'getFileList', windowId, []).then(function(files) {
253 if (!options.orderCheck) {
254 files.sort();
255 expected.sort();
256 }
257 for (var i = 0; i < Math.min(files.length, expected.length); i++) {
258 if (options.ignoreFileSize) {
259 files[i][1] = '';
260 expected[i][1] = '';
261 }
262 if (options.ignoreLastModifiedTime) {
263 files[i][3] = '';
264 expected[i][3] = '';
265 }
266 }
267 if (!chrome.test.checkDeepEq(expected, files)) {
268 return pending('waitForFiles: expected: %j actual %j.',
269 expected,
270 files);
271 }
272 });
273 });
274 }
275
276 /**
277 * Waits until the number of files in the file list is changed from the given
278 * number.
279 * TODO(hirono): Remove the function.
280 *
281 * @param {string} windowId Target window ID.
282 * @param {number} lengthBefore Number of items visible before.
283 * @return {Promise} Promise to be fulfilled with the contents of files.
284 */
285 function waitForFileListChange(windowId, lengthBefore) {
286 return repeatUntil(function() {
287 return callRemoteTestUtil(
288 'getFileList', windowId, []).then(function(files) {
289 files.sort();
290 var notReadyRows = files.filter(function(row) {
291 return row.filter(function(cell) { return cell == '...'; }).length;
292 });
293 if (notReadyRows.length === 0 &&
294 files.length !== lengthBefore &&
295 files.length !== 0) {
296 return files;
297 } else {
298 return pending('The number of file is %d. Not changed.', lengthBefore);
299 }
300 });
301 });
302 };
303
304 /**
305 * Waits until the given taskId appears in the executed task list.
306 * @param {string} windowId Target window ID.
307 * @param {string} taskId Task ID to watch.
308 * @return {Promise} Promise to be fulfilled when the task appears in the
309 * executed task list.
310 */
311 function waitUntilTaskExecutes(windowId, taskId) {
312 return repeatUntil(function() {
313 return callRemoteTestUtil('getExecutedTasks', windowId, []).
314 then(function(executedTasks) {
315 if (executedTasks.indexOf(taskId) === -1)
316 return pending('Executed task is %j', executedTasks);
317 });
318 });
319 }
320
321 /**
322 * Adds check of chrome.test to the end of the given promise.
323 * @param {Promise} promise Promise.
324 */
325 function testPromise(promise) {
326 promise.then(function() {
327 return new Promise(checkIfNoErrorsOccured);
328 }).then(chrome.test.callbackPass(function() {
329 // The callbacPass is necessary to avoid prematurely finishing tests.
330 // Don't put chrome.test.succeed() here to avoid doubled success log.
331 }), function(error) {
332 chrome.test.fail(error.stack || error);
333 });
334 };
335
336 /**
337 * Sends a fake key down event.
338 * @param {string} windowId Window ID.
339 * @param {string} query Query for the target element.
340 * @param {string} keyIdentifer Key identifier.
341 * @param {boolean} ctrlKey Control key flag.
342 * @return {Promise} Promise to be fulfilled or rejected depending on the
343 * result.
344 */
345 function fakeKeyDown(windowId, query, keyIdentifer, ctrlKey) {
346 return new Promise(function(fulfill, reject) {
347 callRemoteTestUtil('fakeKeyDown',
348 windowId,
349 [query, keyIdentifer, ctrlKey],
350 function(result) {
351 if (result)
352 fulfill();
353 else
354 reject(new Error('Fail to fake key down.'));
355 });
356 });
357 }
358
359 /**
360 * Executes a sequence of test steps.
361 * @constructor
362 */
363 function StepsRunner() {
364 /**
365 * List of steps.
366 * @type {Array.<function>}
367 * @private
368 */
369 this.steps_ = [];
370 }
371
372 /**
373 * Creates a StepsRunner instance and runs the passed steps.
374 */
375 StepsRunner.run = function(steps) {
376 var stepsRunner = new StepsRunner();
377 stepsRunner.run_(steps);
378 };
379
380 StepsRunner.prototype = {
381 /**
382 * @return {function} The next closure.
383 */
384 get next() {
385 return this.steps_[0];
386 }
387 };
388
389 /**
390 * Runs a sequence of the added test steps.
391 * @type {Array.<function>} List of the sequential steps.
392 */
393 StepsRunner.prototype.run_ = function(steps) {
394 this.steps_ = steps.slice(0);
395
396 // An extra step which acts as an empty callback for optional asynchronous
397 // calls in the last provided step.
398 this.steps_.push(function() {});
399
400 this.steps_ = this.steps_.map(function(f) {
401 return chrome.test.callbackPass(function() {
402 this.steps_.shift();
403 f.apply(this, arguments);
404 }.bind(this));
405 }.bind(this));
406
407 this.next();
408 };
409
410 /**
411 * Adds the givin entries to the target volume(s).
412 * @param {Array.<string>} volumeNames Names of target volumes.
413 * @param {Array.<TestEntryInfo>} entries List of entries to be added.
414 * @param {function(boolean)} callback Callback function to be passed the result
415 * of function. The argument is true on success.
416 */
417 function addEntries(volumeNames, entries, callback) {
418 if (volumeNames.length == 0) {
419 callback(true);
420 return;
421 }
422 chrome.test.sendMessage(JSON.stringify({
423 name: 'addEntries',
424 volume: volumeNames.shift(),
425 entries: entries
426 }), chrome.test.callbackPass(function(result) {
427 if (result == "onEntryAdded")
428 addEntries(volumeNames, entries, callback);
429 else
430 callback(false);
431 }));
432 };
433
434 /**
435 * @enum {string}
436 * @const
437 */
438 var EntryType = Object.freeze({
439 FILE: 'file',
440 DIRECTORY: 'directory'
441 });
442
443 /**
444 * @enum {string}
445 * @const
446 */
447 var SharedOption = Object.freeze({
448 NONE: 'none',
449 SHARED: 'shared'
450 });
451
452 /**
453 * @enum {string}
454 */
455 var RootPath = Object.seal({
456 DOWNLOADS: '/must-be-filled-in-test-setup',
457 DRIVE: '/must-be-filled-in-test-setup',
458 });
459
460 /**
461 * File system entry information for tests.
462 *
463 * @param {EntryType} type Entry type.
464 * @param {string} sourceFileName Source file name that provides file contents.
465 * @param {string} targetName Name of entry on the test file system.
466 * @param {string} mimeType Mime type.
467 * @param {SharedOption} sharedOption Shared option.
468 * @param {string} lastModifiedTime Last modified time as a text to be shown in
469 * the last modified column.
470 * @param {string} nameText File name to be shown in the name column.
471 * @param {string} sizeText Size text to be shown in the size column.
472 * @param {string} typeText Type name to be shown in the type column.
473 * @constructor
474 */
475 function TestEntryInfo(type,
476 sourceFileName,
477 targetPath,
478 mimeType,
479 sharedOption,
480 lastModifiedTime,
481 nameText,
482 sizeText,
483 typeText) {
484 this.type = type;
485 this.sourceFileName = sourceFileName || '';
486 this.targetPath = targetPath;
487 this.mimeType = mimeType || '';
488 this.sharedOption = sharedOption;
489 this.lastModifiedTime = lastModifiedTime;
490 this.nameText = nameText;
491 this.sizeText = sizeText;
492 this.typeText = typeText;
493 Object.freeze(this);
494 };
495
496 TestEntryInfo.getExpectedRows = function(entries) {
497 return entries.map(function(entry) { return entry.getExpectedRow(); });
498 };
499
500 /**
501 * Obtains a expected row contents of the file in the file list.
502 */
503 TestEntryInfo.prototype.getExpectedRow = function() {
504 return [this.nameText, this.sizeText, this.typeText, this.lastModifiedTime];
505 };
506
507 /**
508 * Filesystem entries used by the test cases.
509 * @type {Object.<string, TestEntryInfo>}
510 * @const
511 */
512 var ENTRIES = {
513 hello: new TestEntryInfo(
514 EntryType.FILE, 'text.txt', 'hello.txt',
515 'text/plain', SharedOption.NONE, 'Sep 4, 1998 12:34 PM',
516 'hello.txt', '51 bytes', 'Plain text'),
517
518 world: new TestEntryInfo(
519 EntryType.FILE, 'video.ogv', 'world.ogv',
520 'text/plain', SharedOption.NONE, 'Jul 4, 2012 10:35 AM',
521 'world.ogv', '59 KB', 'OGG video'),
522
523 unsupported: new TestEntryInfo(
524 EntryType.FILE, 'random.bin', 'unsupported.foo',
525 'application/x-foo', SharedOption.NONE, 'Jul 4, 2012 10:36 AM',
526 'unsupported.foo', '8 KB', 'FOO file'),
527
528 desktop: new TestEntryInfo(
529 EntryType.FILE, 'image.png', 'My Desktop Background.png',
530 'text/plain', SharedOption.NONE, 'Jan 18, 2038 1:02 AM',
531 'My Desktop Background.png', '272 bytes', 'PNG image'),
532
533 beautiful: new TestEntryInfo(
534 EntryType.FILE, 'music.ogg', 'Beautiful Song.ogg',
535 'text/plain', SharedOption.NONE, 'Nov 12, 2086 12:00 PM',
536 'Beautiful Song.ogg', '14 KB', 'OGG audio'),
537
538 photos: new TestEntryInfo(
539 EntryType.DIRECTORY, null, 'photos',
540 null, SharedOption.NONE, 'Jan 1, 1980 11:59 PM',
541 'photos', '--', 'Folder'),
542
543 testDocument: new TestEntryInfo(
544 EntryType.FILE, null, 'Test Document',
545 'application/vnd.google-apps.document',
546 SharedOption.NONE, 'Apr 10, 2013 4:20 PM',
547 'Test Document.gdoc', '--', 'Google document'),
548
549 testSharedDocument: new TestEntryInfo(
550 EntryType.FILE, null, 'Test Shared Document',
551 'application/vnd.google-apps.document',
552 SharedOption.SHARED, 'Mar 20, 2013 10:40 PM',
553 'Test Shared Document.gdoc', '--', 'Google document'),
554
555 newlyAdded: new TestEntryInfo(
556 EntryType.FILE, 'music.ogg', 'newly added file.ogg',
557 'audio/ogg', SharedOption.NONE, 'Sep 4, 1998 12:00 AM',
558 'newly added file.ogg', '14 KB', 'OGG audio'),
559
560 directoryA: new TestEntryInfo(
561 EntryType.DIRECTORY, null, 'A',
562 null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
563 'A', '--', 'Folder'),
564
565 directoryB: new TestEntryInfo(
566 EntryType.DIRECTORY, null, 'A/B',
567 null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
568 'B', '--', 'Folder'),
569
570 directoryC: new TestEntryInfo(
571 EntryType.DIRECTORY, null, 'A/B/C',
572 null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
573 'C', '--', 'Folder'),
574
575 zipArchive: new TestEntryInfo(
576 EntryType.FILE, 'archive.zip', 'archive.zip',
577 'application/x-zip', SharedOption.NONE, 'Jan 1, 2014 1:00 AM',
578 'archive.zip', '533 bytes', 'Zip archive')
579 };
580
581 /**
582 * Basic entry set for the local volume.
583 * @type {Array.<TestEntryInfo>}
584 * @const
585 */
586 var BASIC_LOCAL_ENTRY_SET = [
587 ENTRIES.hello,
588 ENTRIES.world,
589 ENTRIES.desktop,
590 ENTRIES.beautiful,
591 ENTRIES.photos
592 ];
593
594 /**
595 * Basic entry set for the drive volume.
596 *
597 * TODO(hirono): Add a case for an entry cached by FileCache. For testing
598 * Drive, create more entries with Drive specific attributes.
599 *
600 * @type {Array.<TestEntryInfo>}
601 * @const
602 */
603 var BASIC_DRIVE_ENTRY_SET = [
604 ENTRIES.hello,
605 ENTRIES.world,
606 ENTRIES.desktop,
607 ENTRIES.beautiful,
608 ENTRIES.photos,
609 ENTRIES.unsupported,
610 ENTRIES.testDocument,
611 ENTRIES.testSharedDocument
612 ];
613
614 var NESTED_ENTRY_SET = [
615 ENTRIES.directoryA,
616 ENTRIES.directoryB,
617 ENTRIES.directoryC
618 ];
619
620 /**
621 * Expected files shown in "Recent". Directories (e.g. 'photos') are not in this
622 * list as they are not expected in "Recent".
623 *
624 * @type {Array.<TestEntryInfo>}
625 * @const
626 */
627 var RECENT_ENTRY_SET = [
628 ENTRIES.hello,
629 ENTRIES.world,
630 ENTRIES.desktop,
631 ENTRIES.beautiful,
632 ENTRIES.unsupported,
633 ENTRIES.testDocument,
634 ENTRIES.testSharedDocument
635 ];
636
637 /**
638 * Expected files shown in "Offline", which should have the files
639 * "available offline". Google Documents, Google Spreadsheets, and the files
640 * cached locally are "available offline".
641 *
642 * @type {Array.<TestEntryInfo>}
643 * @const
644 */
645 var OFFLINE_ENTRY_SET = [
646 ENTRIES.testDocument,
647 ENTRIES.testSharedDocument
648 ];
649
650 /**
651 * Expected files shown in "Shared with me", which should be the entries labeled
652 * with "shared-with-me".
653 *
654 * @type {Array.<TestEntryInfo>}
655 * @const
656 */
657 var SHARED_WITH_ME_ENTRY_SET = [
658 ENTRIES.testSharedDocument
659 ];
660
661 /**
662 * Opens a Files.app's main window.
663 *
664 * TODO(mtomasz): Pass a volumeId or an enum value instead of full paths.
665 *
666 * @param {Object} appState App state to be passed with on opening Files.app.
667 * Can be null.
668 * @param {?string} initialRoot Root path to be used as a default current
669 * directory during initialization. Can be null, for no default path.
670 * @param {function(string)} Callback with the app id.
671 * @return {Promise} Promise to be fulfilled after window creating.
672 */
673 function openNewWindow(appState, initialRoot, callback) {
674 var appId;
675
676 // TODO(mtomasz): Migrate from full paths to a pair of a volumeId and a
677 // relative path. To compose the URL communicate via messages with
678 // file_manager_browser_test.cc.
679 var processedAppState = appState || {};
680 if (initialRoot) {
681 processedAppState.currentDirectoryURL =
682 'filesystem:chrome-extension://' + FILE_MANAGER_EXTENSIONS_ID +
683 '/external' + initialRoot;
684 }
685
686 return callRemoteTestUtil('openMainWindow',
687 null,
688 [processedAppState],
689 callback);
690 }
691
692 /**
693 * Opens a Files.app's main window and waits until it is initialized. Fills
694 * the window with initial files. Should be called for the first window only.
695 *
696 * TODO(hirono): Add parameters to specify the entry set to be prepared.
697 * TODO(mtomasz): Pass a volumeId or an enum value instead of full paths.
698 *
699 * @param {Object} appState App state to be passed with on opening Files.app.
700 * Can be null.
701 * @param {?string} initialRoot Root path to be used as a default current
702 * directory during initialization. Can be null, for no default path.
703 * @param {function(string, Array.<Array.<string>>)} Callback with the app id
704 * and with the file list.
705 */
706 function setupAndWaitUntilReady(appState, initialRoot, callback) {
707 var appId;
708
709 StepsRunner.run([
710 function() {
711 openNewWindow(appState, initialRoot, this.next);
712 },
713 function(inAppId) {
714 appId = inAppId;
715 addEntries(['local'], BASIC_LOCAL_ENTRY_SET, this.next);
716 },
717 function(success) {
718 chrome.test.assertTrue(success);
719 addEntries(['drive'], BASIC_DRIVE_ENTRY_SET, this.next);
720 },
721 function(success) {
722 chrome.test.assertTrue(success);
723 waitForElement(appId, '#detail-table').then(this.next);
724 },
725 function(success) {
726 waitForFileListChange(appId, 0).then(this.next);
727 },
728 function(fileList) {
729 callback(appId, fileList);
730 this.next();
731 }
732 ]);
733 }
734
735 /**
736 * Verifies if there are no Javascript errors in any of the app windows.
737 * @param {function()} Completion callback.
738 */
739 function checkIfNoErrorsOccured(callback) {
740 callRemoteTestUtil('getErrorCount', null, [], function(count) {
741 chrome.test.assertEq(0, count, 'The error count is not 0.');
742 callback();
743 });
744 }
745
746 /**
747 * Returns the name of the given file list entry.
748 * @param {Array.<string>} file An entry in a file list.
749 * @return {string} Name of the file.
750 */
751 function getFileName(fileListEntry) {
752 return fileListEntry[0];
753 }
754
755 /**
756 * Returns the size of the given file list entry.
757 * @param {Array.<string>} An entry in a file list.
758 * @return {string} Size of the file.
759 */
760 function getFileSize(fileListEntry) {
761 return fileListEntry[1];
762 }
763
764 /**
765 * Returns the type of the given file list entry.
766 * @param {Array.<string>} An entry in a file list.
767 * @return {string} Type of the file.
768 */
769 function getFileType(fileListEntry) {
770 return fileListEntry[2];
771 }
772
773 /**
774 * Namespace for test cases.
775 */
776 var testcase = {};
777
778 // Ensure the test cases are loaded.
779 window.addEventListener('load', function() {
780 var steps = [
781 // Check for the guest mode.
782 function() {
783 chrome.test.sendMessage(
784 JSON.stringify({name: 'isInGuestMode'}), steps.shift());
785 },
786 // Obtain the test case name.
787 function(result) {
788 if (JSON.parse(result) != chrome.extension.inIncognitoContext)
789 return;
790 chrome.test.sendMessage(
791 JSON.stringify({name: 'getRootPaths'}), steps.shift());
792 },
793 // Obtain the root entry paths.
794 function(result) {
795 var roots = JSON.parse(result);
796 RootPath.DOWNLOADS = roots.downloads;
797 RootPath.DRIVE = roots.drive;
798 chrome.test.sendMessage(
799 JSON.stringify({name: 'getTestName'}), steps.shift());
800 },
801 // Run the test case.
802 function(testCaseName) {
803 var targetTest = testcase[testCaseName];
804 if (!targetTest) {
805 chrome.test.fail(testCaseName + ' is not found.');
806 return;
807 }
808 // Specify the name of test to the test system.
809 targetTest.generatedName = testCaseName;
810 chrome.test.runTests([targetTest]);
811 }
812 ];
813 steps.shift()();
814 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698