- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / data / extensions / api_test / file_manager_browsertest / test_cases.js
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 'use strict';
6
7 /**
8  * @enum {string}
9  * @const
10  */
11 var EntryType = Object.freeze({
12   FILE: 'file',
13   DIRECTORY: 'directory'
14 });
15
16 /**
17  * @enum {string}
18  * @const
19  */
20 var SharedOption = Object.freeze({
21   NONE: 'none',
22   SHARED: 'shared'
23 });
24
25 /**
26  * File system entry information for tests.
27  *
28  * @param {EntryType} type Entry type.
29  * @param {string} sourceFileName Source file name that provides file contents.
30  * @param {string} targetName Name of entry on the test file system.
31  * @param {string} mimeType Mime type.
32  * @param {SharedOption} sharedOption Shared option.
33  * @param {string} lastModifiedTime Last modified time as a text to be shown in
34  *     the last modified column.
35  * @param {string} nameText File name to be shown in the name column.
36  * @param {string} sizeText Size text to be shown in the size column.
37  * @param {string} typeText Type name to be shown in the type column.
38  * @constructor
39  */
40 var TestEntryInfo = function(type,
41                              sourceFileName,
42                              targetPath,
43                              mimeType,
44                              sharedOption,
45                              lastModifiedTime,
46                              nameText,
47                              sizeText,
48                              typeText) {
49   this.type = type;
50   this.sourceFileName = sourceFileName || '';
51   this.targetPath = targetPath;
52   this.mimeType = mimeType || '';
53   this.sharedOption = sharedOption;
54   this.lastModifiedTime = lastModifiedTime;
55   this.nameText = nameText;
56   this.sizeText = sizeText;
57   this.typeText = typeText;
58   Object.freeze(this);
59 };
60
61 TestEntryInfo.getExpectedRows = function(entries) {
62   return entries.map(function(entry) { return entry.getExpectedRow(); });
63 };
64
65 /**
66  * Obtains a expected row contents of the file in the file list.
67  */
68 TestEntryInfo.prototype.getExpectedRow = function() {
69   return [this.nameText, this.sizeText, this.typeText, this.lastModifiedTime];
70 };
71
72 /**
73  * Filesystem entries used by the test cases.
74  * @type {Object.<string, TestEntryInfo>}
75  * @const
76  */
77 var ENTRIES = {
78   hello: new TestEntryInfo(
79       EntryType.FILE, 'text.txt', 'hello.txt',
80       'text/plain', SharedOption.NONE, 'Sep 4, 1998 12:34 PM',
81       'hello.txt', '51 bytes', 'Plain text'),
82
83   world: new TestEntryInfo(
84       EntryType.FILE, 'video.ogv', 'world.ogv',
85       'text/plain', SharedOption.NONE, 'Jul 4, 2012 10:35 AM',
86       'world.ogv', '59 KB', 'OGG video'),
87
88   unsupported: new TestEntryInfo(
89       EntryType.FILE, 'random.bin', 'unsupported.foo',
90       'application/x-foo', SharedOption.NONE, 'Jul 4, 2012 10:36 AM',
91       'unsupported.foo', '8 KB', 'FOO file'),
92
93   desktop: new TestEntryInfo(
94       EntryType.FILE, 'image.png', 'My Desktop Background.png',
95       'text/plain', SharedOption.NONE, 'Jan 18, 2038 1:02 AM',
96       'My Desktop Background.png', '272 bytes', 'PNG image'),
97
98   beautiful: new TestEntryInfo(
99       EntryType.FILE, 'music.ogg', 'Beautiful Song.ogg',
100       'text/plain', SharedOption.NONE, 'Nov 12, 2086 12:00 PM',
101       'Beautiful Song.ogg', '14 KB', 'OGG audio'),
102
103   photos: new TestEntryInfo(
104       EntryType.DIRECTORY, null, 'photos',
105       null, SharedOption.NONE, 'Jan 1, 1980 11:59 PM',
106       'photos', '--', 'Folder'),
107
108   testDocument: new TestEntryInfo(
109       EntryType.FILE, null, 'Test Document',
110       'application/vnd.google-apps.document',
111       SharedOption.NONE, 'Apr 10, 2013 4:20 PM',
112       'Test Document.gdoc', '--', 'Google document'),
113
114   testSharedDocument: new TestEntryInfo(
115       EntryType.FILE, null, 'Test Shared Document',
116       'application/vnd.google-apps.document',
117       SharedOption.SHARED, 'Mar 20, 2013 10:40 PM',
118       'Test Shared Document.gdoc', '--', 'Google document'),
119
120   newlyAdded: new TestEntryInfo(
121       EntryType.FILE, 'music.ogg', 'newly added file.ogg',
122       'audio/ogg', SharedOption.NONE, 'Sep 4, 1998 12:00 AM',
123       'newly added file.ogg', '14 KB', 'OGG audio'),
124
125   directoryA: new TestEntryInfo(
126       EntryType.DIRECTORY, null, 'A',
127       null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
128       'A', '--', 'Folder'),
129
130   directoryB: new TestEntryInfo(
131       EntryType.DIRECTORY, null, 'A/B',
132       null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
133       'B', '--', 'Folder'),
134
135   directoryC: new TestEntryInfo(
136       EntryType.DIRECTORY, null, 'A/B/C',
137       null, SharedOption.NONE, 'Jan 1, 2000 1:00 AM',
138       'C', '--', 'Folder')
139 };
140
141 /**
142  * Basic entry set for the local volume.
143  * @type {Array.<TestEntryInfo>}
144  * @const
145  */
146 var BASIC_LOCAL_ENTRY_SET = [
147   ENTRIES.hello,
148   ENTRIES.world,
149   ENTRIES.desktop,
150   ENTRIES.beautiful,
151   ENTRIES.photos
152 ];
153
154 /**
155  * Basic entry set for the drive volume.
156  *
157  * TODO(hirono): Add a case for an entry cached by FileCache. For testing
158  *               Drive, create more entries with Drive specific attributes.
159  *
160  * @type {Array.<TestEntryInfo>}
161  * @const
162  */
163 var BASIC_DRIVE_ENTRY_SET = [
164   ENTRIES.hello,
165   ENTRIES.world,
166   ENTRIES.desktop,
167   ENTRIES.beautiful,
168   ENTRIES.photos,
169   ENTRIES.unsupported,
170   ENTRIES.testDocument,
171   ENTRIES.testSharedDocument
172 ];
173
174 var NESTED_ENTRY_SET = [
175   ENTRIES.directoryA,
176   ENTRIES.directoryB,
177   ENTRIES.directoryC
178 ];
179
180 /**
181  * Expected files shown in "Recent". Directories (e.g. 'photos') are not in this
182  * list as they are not expected in "Recent".
183  *
184  * @type {Array.<TestEntryInfo>}
185  * @const
186  */
187 var RECENT_ENTRY_SET = [
188   ENTRIES.hello,
189   ENTRIES.world,
190   ENTRIES.desktop,
191   ENTRIES.beautiful,
192   ENTRIES.unsupported,
193   ENTRIES.testDocument,
194   ENTRIES.testSharedDocument
195 ];
196
197 /**
198  * Expected files shown in "Offline", which should have the files
199  * "available offline". Google Documents, Google Spreadsheets, and the files
200  * cached locally are "available offline".
201  *
202  * @type {Array.<TestEntryInfo>}
203  * @const
204  */
205 var OFFLINE_ENTRY_SET = [
206   ENTRIES.testDocument,
207   ENTRIES.testSharedDocument
208 ];
209
210 /**
211  * Expected files shown in "Shared with me", which should be the entries labeled
212  * with "shared-with-me".
213  *
214  * @type {Array.<TestEntryInfo>}
215  * @const
216  */
217 var SHARED_WITH_ME_ENTRY_SET = [
218   ENTRIES.testSharedDocument
219 ];
220
221 /**
222  * Opens a Files.app's main window and waits until it is initialized.
223  *
224  * TODO(hirono): Add parameters to specify the entry set to be prepared.
225  *
226  * @param {Object} appState App state to be passed with on opening Files.app.
227  * @param {function(string, Array.<Array.<string>>)} Callback with the app id
228  *     and with the file list.
229  */
230 function setupAndWaitUntilReady(appState, callback) {
231   var appId;
232   var steps = [
233     function() {
234       callRemoteTestUtil('openMainWindow', null, [appState], steps.shift());
235     },
236     function(inAppId) {
237       appId = inAppId;
238       addEntries(['local'], BASIC_LOCAL_ENTRY_SET, steps.shift());
239     },
240     function(success) {
241       chrome.test.assertTrue(success);
242       addEntries(['drive'], BASIC_DRIVE_ENTRY_SET, steps.shift());
243     },
244     function(success) {
245       chrome.test.assertTrue(success);
246       callRemoteTestUtil('waitForFileListChange', appId, [0], steps.shift());
247     },
248     function(fileList) {
249       callback(appId, fileList);
250     }
251   ];
252   steps.shift()();
253 }
254
255 /**
256  * Verifies if there are no Javascript errors in any of the app windows.
257  * @param {function()} Completion callback.
258  */
259 function checkIfNoErrorsOccured(callback) {
260   callRemoteTestUtil('getErrorCount', null, [], function(count) {
261     chrome.test.assertEq(0, count);
262     callback();
263   });
264 }
265
266
267
268 /**
269  * Returns the name of the given file list entry.
270  * @param {Array.<string>} file An entry in a file list.
271  * @return {string} Name of the file.
272  */
273 function getFileName(fileListEntry) {
274   return fileListEntry[0];
275 }
276
277 /**
278  * Returns the size of the given file list entry.
279  * @param {Array.<string>} An entry in a file list.
280  * @return {string} Size of the file.
281  */
282 function getFileSize(fileListEntry) {
283   return fileListEntry[1];
284 }
285
286 /**
287  * Returns the type of the given file list entry.
288  * @param {Array.<string>} An entry in a file list.
289  * @return {string} Type of the file.
290  */
291 function getFileType(fileListEntry) {
292   return fileListEntry[2];
293 }
294
295 /**
296  * Namespace for test cases.
297  */
298 var testcase = {};
299
300 /**
301  * Namespace for intermediate test cases.
302  * */
303 testcase.intermediate = {};
304
305 /**
306  * Tests if the files initially added by the C++ side are displayed, and
307  * that a subsequently added file shows up.
308  *
309  * @param {string} path Directory path to be tested.
310  */
311 testcase.intermediate.fileDisplay = function(path) {
312   var appId;
313
314   var expectedFilesBefore =
315       TestEntryInfo.getExpectedRows(path == '/drive/root' ?
316           BASIC_DRIVE_ENTRY_SET : BASIC_LOCAL_ENTRY_SET).sort();
317
318   var expectedFilesAfter =
319       expectedFilesBefore.concat([ENTRIES.newlyAdded.getExpectedRow()]).sort();
320
321   StepsRunner.run([
322     function() {
323       var appState = {defaultPath: path};
324       setupAndWaitUntilReady(appState, this.next);
325     },
326     // Notify that the list has been verified and a new file can be added
327     // in file_manager_browsertest.cc.
328     function(inAppId, actualFilesBefore) {
329       appId = inAppId;
330       chrome.test.assertEq(expectedFilesBefore, actualFilesBefore);
331       addEntries(['local', 'drive'], [ENTRIES.newlyAdded], this.next);
332     },
333     function(result) {
334       chrome.test.assertTrue(result);
335       callRemoteTestUtil(
336           'waitForFileListChange',
337           appId,
338           [expectedFilesBefore.length],
339           this.next);
340     },
341     // Confirm the file list.
342     function(actualFilesAfter) {
343       chrome.test.assertEq(expectedFilesAfter, actualFilesAfter);
344       checkIfNoErrorsOccured(this.next);
345     },
346   ]);
347 };
348
349 /**
350  * Tests if the gallery shows up for the selected image and that the image
351  * gets displayed.
352  *
353  * @param {string} path Directory path to be tested.
354  */
355 testcase.intermediate.galleryOpen = function(path) {
356   var appId;
357   StepsRunner.run([
358     function() {
359       var appState = {defaultPath: path};
360       setupAndWaitUntilReady(appState, this.next);
361     },
362     // Resize the window to desired dimensions to avoid flakyness.
363     function(inAppId) {
364       appId = inAppId;
365       callRemoteTestUtil('resizeWindow',
366                          appId,
367                          [320, 320],
368                          this.next);
369     },
370     // Select the image.
371     function(result) {
372       chrome.test.assertTrue(result);
373       callRemoteTestUtil('openFile',
374                          appId,
375                          ['My Desktop Background.png'],
376                          this.next);
377     },
378     // Wait for the image in the gallery's screen image.
379     function(result) {
380       chrome.test.assertTrue(result);
381       callRemoteTestUtil('waitForElement',
382                          appId,
383                          ['.gallery .content canvas.image',
384                           'iframe.overlay-pane'],
385                          this.next);
386     },
387     // Verify the gallery's screen image.
388     function(element) {
389       chrome.test.assertEq('320', element.attributes.width);
390       chrome.test.assertEq('240', element.attributes.height);
391       // Get the full-resolution image.
392       callRemoteTestUtil('waitForElement',
393                          appId,
394                          ['.gallery .content canvas.fullres',
395                           'iframe.overlay-pane'],
396                          this.next);
397     },
398     // Verify the gallery's full resolution image.
399     function(element) {
400       chrome.test.assertEq('800', element.attributes.width);
401       chrome.test.assertEq('600', element.attributes.height);
402       checkIfNoErrorsOccured(this.next);
403     }
404   ]);
405 };
406
407 /**
408  * Tests if the audio player shows up for the selected image and that the audio
409  * is loaded successfully.
410  *
411  * @param {string} path Directory path to be tested.
412  */
413 testcase.intermediate.audioOpen = function(path) {
414   var appId;
415   var audioAppId;
416   StepsRunner.run([
417     function() {
418       var appState = {defaultPath: path};
419       setupAndWaitUntilReady(appState, this.next);
420     },
421     // Select the song.
422     function(inAppId) {
423       appId = inAppId;
424       callRemoteTestUtil(
425           'openFile', appId, ['Beautiful Song.ogg'], this.next);
426     },
427     // Wait for the audio player.
428     function(result) {
429       chrome.test.assertTrue(result);
430       callRemoteTestUtil('waitForWindow',
431                          null,
432                          ['mediaplayer.html'],
433                          this.next);
434     },
435     // Wait for the audio tag and verify the source.
436     function(inAppId) {
437       audioAppId = inAppId;
438       callRemoteTestUtil('waitForElement',
439                          audioAppId,
440                          ['audio[src]'],
441                          this.next);
442     },
443     // Get the title tag.
444     function(element) {
445       chrome.test.assertEq(
446           'filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
447               'external' + path + '/Beautiful%20Song.ogg',
448           element.attributes.src);
449       callRemoteTestUtil('waitForElement',
450                          audioAppId,
451                          ['.data-title'],
452                          this.next);
453     },
454     // Get the artist tag.
455     function(element) {
456       chrome.test.assertEq('Beautiful Song', element.text);
457       callRemoteTestUtil('waitForElement',
458                          audioAppId,
459                          ['.data-artist'],
460                          this.next);
461     },
462     // Verify the artist and if there are no javascript errors.
463     function(element) {
464       chrome.test.assertEq('Unknown Artist', element.text);
465       checkIfNoErrorsOccured(this.next);
466     }
467   ]);
468 };
469
470 /**
471  * Tests if the video player shows up for the selected movie and that it is
472  * loaded successfully.
473  *
474  * @param {string} path Directory path to be tested.
475  */
476 testcase.intermediate.videoOpen = function(path) {
477   var appId;
478   var videoAppId;
479   StepsRunner.run([
480     function() {
481       var appState = {defaultPath: path};
482       setupAndWaitUntilReady(appState, this.next);
483     },
484     function(inAppId) {
485       appId = inAppId;
486       // Select the song.
487       callRemoteTestUtil(
488           'openFile', appId, ['world.ogv'], this.next);
489     },
490     function(result) {
491       chrome.test.assertTrue(result);
492       // Wait for the video player.
493       callRemoteTestUtil('waitForWindow',
494                          null,
495                          ['video_player.html'],
496                          this.next);
497     },
498     function(inAppId) {
499       videoAppId = inAppId;
500       // Wait for the video tag and verify the source.
501       callRemoteTestUtil('waitForElement',
502                          videoAppId,
503                          ['video[src]'],
504                          this.next);
505     },
506     function(element) {
507       chrome.test.assertEq(
508           'filesystem:chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
509               'external' + path + '/world.ogv',
510           element.attributes.src);
511       // Wait for the window's inner dimensions. Should be changed to the video
512       // size once the metadata is loaded.
513       callRemoteTestUtil('waitForWindowGeometry',
514                          videoAppId,
515                          [320, 192],
516                          this.next);
517     },
518     function(element) {
519       checkIfNoErrorsOccured(this.next);
520     }
521   ]);
522 };
523
524 /**
525  * Tests copying a file to the same directory and waits until the file lists
526  * changes.
527  *
528  * @param {string} path Directory path to be tested.
529  */
530 testcase.intermediate.keyboardCopy = function(path, callback) {
531   var filename = 'world.ogv';
532   var expectedFilesBefore =
533       TestEntryInfo.getExpectedRows(path == '/drive/root' ?
534           BASIC_DRIVE_ENTRY_SET : BASIC_LOCAL_ENTRY_SET).sort();
535   var expectedFilesAfter =
536       expectedFilesBefore.concat([['world (1).ogv', '59 KB', 'OGG video']]);
537
538   var appId, fileListBefore;
539   StepsRunner.run([
540     // Set up File Manager.
541     function() {
542       var appState = {defaultPath: path};
543       setupAndWaitUntilReady(appState, this.next);
544     },
545     // Copy the file.
546     function(inAppId, inFileListBefore) {
547       appId = inAppId;
548       fileListBefore = inFileListBefore;
549       chrome.test.assertEq(expectedFilesBefore, inFileListBefore);
550       callRemoteTestUtil('copyFile', appId, [filename], this.next);
551     },
552     // Wait for a file list change.
553     function(result) {
554       chrome.test.assertTrue(result);
555       callRemoteTestUtil('waitForFiles',
556                          appId,
557                          [expectedFilesAfter,
558                           {ignoreLastModifiedTime: true}],
559                          this.next);
560     },
561     // Verify the result.
562     function(fileList) {
563       checkIfNoErrorsOccured(this.next);
564     }
565   ]);
566 };
567
568 /**
569  * Tests deleting a file and and waits until the file lists changes.
570  * @param {string} path Directory path to be tested.
571  */
572 testcase.intermediate.keyboardDelete = function(path) {
573   // Returns true if |fileList| contains |filename|.
574   var isFilePresent = function(filename, fileList) {
575     for (var i = 0; i < fileList.length; i++) {
576       if (getFileName(fileList[i]) == filename)
577         return true;
578     }
579     return false;
580   };
581
582   var filename = 'world.ogv';
583   var directoryName = 'photos';
584   var appId, fileListBefore;
585   StepsRunner.run([
586     // Set up File Manager.
587     function() {
588       var appState = {defaultPath: path};
589       setupAndWaitUntilReady(appState, this.next);
590     },
591     // Delete the file.
592     function(inAppId, inFileListBefore) {
593       appId = inAppId;
594       fileListBefore = inFileListBefore;
595       chrome.test.assertTrue(isFilePresent(filename, fileListBefore));
596       callRemoteTestUtil(
597           'deleteFile', appId, [filename], this.next);
598     },
599     // Reply to a dialog.
600     function(result) {
601       chrome.test.assertTrue(result);
602       callRemoteTestUtil(
603           'waitAndAcceptDialog', appId, [], this.next);
604     },
605     // Wait for a file list change.
606     function() {
607       callRemoteTestUtil('waitForFileListChange',
608                          appId,
609                          [fileListBefore.length],
610                          this.next);
611     },
612     // Delete the directory.
613     function(fileList) {
614       fileListBefore = fileList;
615       chrome.test.assertFalse(isFilePresent(filename, fileList));
616       chrome.test.assertTrue(isFilePresent(directoryName, fileList));
617       callRemoteTestUtil('deleteFile', appId, [directoryName], this.next);
618     },
619     // Reply to a dialog.
620     function(result) {
621       chrome.test.assertTrue(result);
622       callRemoteTestUtil('waitAndAcceptDialog', appId, [], this.next);
623     },
624     // Wait for a file list change.
625     function() {
626       callRemoteTestUtil('waitForFileListChange', appId,
627                          [fileListBefore.length], this.next);
628     },
629     // Verify the result.
630     function(fileList) {
631       chrome.test.assertFalse(isFilePresent(directoryName, fileList));
632       checkIfNoErrorsOccured(this.next);
633     }
634   ]);
635 };
636
637 testcase.fileDisplayDownloads = function() {
638   testcase.intermediate.fileDisplay('/Downloads');
639 };
640
641 testcase.galleryOpenDownloads = function() {
642   testcase.intermediate.galleryOpen('/Downloads');
643 };
644
645 testcase.audioOpenDownloads = function() {
646   testcase.intermediate.audioOpen('/Downloads');
647 };
648
649 testcase.videoOpenDownloads = function() {
650   testcase.intermediate.videoOpen('/Downloads');
651 };
652
653 testcase.keyboardCopyDownloads = function() {
654   testcase.intermediate.keyboardCopy('/Downloads');
655 };
656
657 testcase.keyboardDeleteDownloads = function() {
658   testcase.intermediate.keyboardDelete('/Downloads');
659 };
660
661 testcase.fileDisplayDrive = function() {
662   testcase.intermediate.fileDisplay('/drive/root');
663 };
664
665 testcase.galleryOpenDrive = function() {
666   testcase.intermediate.galleryOpen('/drive/root');
667 };
668
669 testcase.audioOpenDrive = function() {
670   testcase.intermediate.audioOpen('/drive/root');
671 };
672
673 testcase.videoOpenDrive = function() {
674   testcase.intermediate.videoOpen('/drive/root');
675 };
676
677 testcase.keyboardCopyDrive = function() {
678   testcase.intermediate.keyboardCopy('/drive/root');
679 };
680
681 testcase.keyboardDeleteDrive = function() {
682   testcase.intermediate.keyboardDelete('/drive/root');
683 };
684
685 /**
686  * Tests opening the "Recent" on the sidebar navigation by clicking the icon,
687  * and verifies the directory contents. We test if there are only files, since
688  * directories are not allowed in "Recent". This test is only available for
689  * Drive.
690  */
691 testcase.openSidebarRecent = function() {
692   var appId;
693   StepsRunner.run([
694     function() {
695       var appState = {defaultPath: '/drive/root'};
696       setupAndWaitUntilReady(appState, this.next);
697     },
698     // Click the icon of the Recent volume.
699     function(inAppId) {
700       appId = inAppId;
701       callRemoteTestUtil(
702         'selectVolume', appId, ['drive_recent'], this.next);
703     },
704     // Wait until the file list is updated.
705     function(result) {
706       chrome.test.assertFalse(!result);
707       callRemoteTestUtil(
708           'waitForFileListChange',
709           appId,
710           [BASIC_DRIVE_ENTRY_SET.length],
711           this.next);
712     },
713     // Verify the file list.
714     function(actualFilesAfter) {
715       chrome.test.assertEq(
716           TestEntryInfo.getExpectedRows(RECENT_ENTRY_SET).sort(),
717           actualFilesAfter);
718       checkIfNoErrorsOccured(this.next);
719     }
720   ]);
721 };
722
723 /**
724  * Tests opening the "Offline" on the sidebar navigation by clicking the icon,
725  * and checks contenets of the file list. Only the entries "available offline"
726  * should be shown. "Available offline" entires are hosted documents and the
727  * entries cached by DriveCache.
728  */
729 testcase.openSidebarOffline = function() {
730   var appId;
731   StepsRunner.run([
732     function() {
733       var appState = {defaultPath: '/drive/root/'};
734       setupAndWaitUntilReady(appState, this.next);
735     },
736     // Click the icon of the Offline volume.
737     function(inAppId) {
738       appId = inAppId;
739       callRemoteTestUtil(
740         'selectVolume', appId, ['drive_offline'], this.next);
741     },
742     // Wait until the file list is updated.
743     function(result) {
744       chrome.test.assertFalse(!result);
745       callRemoteTestUtil(
746           'waitForFileListChange',
747           appId,
748           [BASIC_DRIVE_ENTRY_SET.length],
749           this.next);
750     },
751     // Verify the file list.
752     function(actualFilesAfter) {
753       chrome.test.assertEq(
754           TestEntryInfo.getExpectedRows(OFFLINE_ENTRY_SET).sort(),
755           actualFilesAfter);
756       checkIfNoErrorsOccured(this.next);
757     }
758   ]);
759 };
760
761 /**
762  * Tests opening the "Shared with me" on the sidebar navigation by clicking the
763  * icon, and checks contents of the file list. Only the entries labeled with
764  * "shared-with-me" should be shown.
765  */
766 testcase.openSidebarSharedWithMe = function() {
767   var appId;
768   StepsRunner.run([
769     function() {
770       var appState = {defaultPath: '/drive/root/'};
771       setupAndWaitUntilReady(appState, this.next);
772     },
773     // Click the icon of the Shared With Me volume.
774     function(inAppId) {
775       appId = inAppId;
776       // Use the icon for a click target.
777       callRemoteTestUtil('selectVolume',
778                          appId,
779                          ['drive_shared_with_me'], this.next);
780     },
781     // Wait until the file list is updated.
782     function(result) {
783       chrome.test.assertFalse(!result);
784       callRemoteTestUtil(
785           'waitForFileListChange',
786           appId,
787           [BASIC_DRIVE_ENTRY_SET.length],
788           this.next);
789     },
790     // Verify the file list.
791     function(actualFilesAfter) {
792       chrome.test.assertEq(
793           TestEntryInfo.getExpectedRows(SHARED_WITH_ME_ENTRY_SET).sort(),
794           actualFilesAfter);
795       checkIfNoErrorsOccured(this.next);
796     }
797   ]);
798 };
799
800 /**
801  * Tests autocomplete with a query 'hello'. This test is only available for
802  * Drive.
803  */
804 testcase.autocomplete = function() {
805   var EXPECTED_AUTOCOMPLETE_LIST = [
806     '\'hello\' - search Drive\n',
807     'hello.txt\n',
808   ];
809
810   StepsRunner.run([
811     function() {
812       var appState = {defaultPath: '/drive/root'};
813       setupAndWaitUntilReady(appState, this.next);
814     },
815     // Perform an auto complete test and wait until the list changes.
816     // TODO(mtomasz): Move the operation from test_util.js to tests_cases.js.
817     function(appId, list) {
818       callRemoteTestUtil('performAutocompleteAndWait',
819                          appId,
820                          ['hello', EXPECTED_AUTOCOMPLETE_LIST.length],
821                          this.next);
822     },
823     // Verify the list contents.
824     function(autocompleteList) {
825       chrome.test.assertEq(EXPECTED_AUTOCOMPLETE_LIST, autocompleteList);
826       checkIfNoErrorsOccured(this.next);
827     }
828   ]);
829 };
830
831 /**
832  * Test function to copy from the specified source to the specified destination.
833  * @param {string} targetFile Name of target file to be copied.
834  * @param {string} srcName Type of source volume. e.g. downloads, drive,
835  *     drive_recent, drive_shared_with_me, drive_offline.
836  * @param {Array.<TestEntryInfo>} srcEntries Expected initial contents in the
837  *     source volume.
838  * @param {string} dstName Type of destination volume.
839  * @param {Array.<TestEntryInfo>} dstEntries Expected initial contents in the
840  *     destination volume.
841  */
842 testcase.intermediate.copyBetweenVolumes = function(targetFile,
843                                                     srcName,
844                                                     srcEntries,
845                                                     dstName,
846                                                     dstEntries) {
847   var srcContents = TestEntryInfo.getExpectedRows(srcEntries).sort();
848   var dstContents = TestEntryInfo.getExpectedRows(dstEntries).sort();
849
850   var appId;
851   StepsRunner.run([
852     // Set up File Manager.
853     function() {
854       var appState = {defaultPath: '/Downloads'};
855       setupAndWaitUntilReady(appState, this.next);
856     },
857     // Select the source volume.
858     function(inAppId) {
859       appId = inAppId;
860       callRemoteTestUtil(
861           'selectVolume', appId, [srcName], this.next);
862     },
863     // Wait for the expected files to appear in the file list.
864     function(result) {
865       chrome.test.assertTrue(result);
866       callRemoteTestUtil(
867           'waitForFiles', appId, [srcContents], this.next);
868     },
869     // Select the source file.
870     function() {
871       callRemoteTestUtil(
872           'selectFile', appId, [targetFile], this.next);
873     },
874     // Copy the file.
875     function(result) {
876       chrome.test.assertTrue(result);
877       callRemoteTestUtil('execCommand', appId, ['copy'], this.next);
878     },
879     // Select the destination volume.
880     function(result) {
881       chrome.test.assertTrue(result);
882       callRemoteTestUtil(
883           'selectVolume', appId, [dstName], this.next);
884     },
885     // Wait for the expected files to appear in the file list.
886     function(result) {
887       chrome.test.assertTrue(result);
888       callRemoteTestUtil(
889           'waitForFiles', appId, [dstContents], this.next);
890     },
891     // Paste the file.
892     function() {
893       callRemoteTestUtil(
894           'execCommand', appId, ['paste'], this.next);
895     },
896     // Wait for the file list to change.
897     function(result) {
898       chrome.test.assertTrue(result);
899       callRemoteTestUtil('waitForFileListChange',
900                          appId,
901                          [dstContents.length],
902                          this.next);
903     },
904     // Check the last contents of file list.
905     function(actualFilesAfter) {
906       chrome.test.assertEq(dstContents.length + 1,
907                            actualFilesAfter.length);
908       var copiedItem = null;
909       for (var i = 0; i < srcContents.length; i++) {
910         if (srcContents[i][0] == targetFile) {
911           copiedItem = srcContents[i];
912           break;
913         }
914       }
915       chrome.test.assertTrue(copiedItem != null);
916       for (var i = 0; i < dstContents.length; i++) {
917         if (dstContents[i][0] == targetFile) {
918           // Replace the last '.' in filename with ' (1).'.
919           // e.g. 'my.note.txt' -> 'my.note (1).txt'
920           copiedItem[0] = copiedItem[0].replace(/\.(?=[^\.]+$)/, ' (1).');
921           break;
922         }
923       }
924       // File size can not be obtained on drive_shared_with_me volume and
925       // drive_offline.
926       var ignoreSize = srcName == 'drive_shared_with_me' ||
927                        dstName == 'drive_shared_with_me' ||
928                        srcName == 'drive_offline' ||
929                        dstName == 'drive_offline';
930       for (var i = 0; i < actualFilesAfter.length; i++) {
931         if (actualFilesAfter[i][0] == copiedItem[0] &&
932             (ignoreSize || actualFilesAfter[i][1] == copiedItem[1]) &&
933             actualFilesAfter[i][2] == copiedItem[2]) {
934           checkIfNoErrorsOccured(this.next);
935           return;
936         }
937       }
938       chrome.test.fail();
939     }
940   ]);
941 };
942
943 /**
944  * Test sharing dialog for a file or directory on Drive
945  * @param {string} path Path for a file or a directory to be shared.
946  */
947 testcase.intermediate.share = function(path) {
948   var appId;
949   StepsRunner.run([
950     // Set up File Manager.
951     function() {
952       var appState = {defaultPath: '/drive/root/'};
953       setupAndWaitUntilReady(appState, this.next);
954     },
955     // Select the source file.
956     function(inAppId) {
957       appId = inAppId;
958       callRemoteTestUtil(
959           'selectFile', appId, [path], this.next);
960     },
961     // Wait for the share button.
962     function(result) {
963       chrome.test.assertTrue(result);
964       callRemoteTestUtil('waitForElement',
965                          appId,
966                          ['#share-button:not([disabled])'],
967                          this.next);
968     },
969     // Invoke the share dialog.
970     function(result) {
971       callRemoteTestUtil('fakeMouseClick',
972                          appId,
973                          ['#share-button'],
974                          this.next);
975     },
976     // Wait until the share dialog's contents are shown.
977     function(result) {
978       chrome.test.assertTrue(result);
979       callRemoteTestUtil('waitForElement',
980                          appId,
981                          ['.share-dialog-webview-wrapper.loaded'],
982                          this.next);
983     },
984     function(result) {
985       callRemoteTestUtil('waitForStyles',
986                          appId,
987                          [{
988                             query: '.share-dialog-webview-wrapper.loaded',
989                             styles: {
990                               width: '350px',
991                               height: '250px'
992                             }
993                           }],
994                          this.next);
995     },
996     // Wait until the share dialog's contents are shown.
997     function(result) {
998       callRemoteTestUtil('executeScriptInWebView',
999                          appId,
1000                          ['.share-dialog-webview-wrapper.loaded webview',
1001                           'document.querySelector("button").click()'],
1002                          this.next);
1003     },
1004     // Wait until the share dialog's contents are hidden.
1005     function(result) {
1006       callRemoteTestUtil('waitForElement',
1007                          appId,
1008                          ['.share-dialog-webview-wrapper.loaded',
1009                           null,   // iframeQuery
1010                           true],  // inverse
1011                          this.next);
1012     },
1013     // Check for Javascript errros.
1014     function() {
1015       checkIfNoErrorsOccured(this.next);
1016     }
1017   ]);
1018 };
1019
1020 /**
1021  * Test utility for traverse tests.
1022  */
1023 testcase.intermediate.traverseDirectories = function(root) {
1024   var appId;
1025   StepsRunner.run([
1026     // Set up File Manager.
1027     function() {
1028       var appState = {defaultPath: root};
1029       callRemoteTestUtil('openMainWindow', null, [appState], this.next);
1030     },
1031     // Check the initial view.
1032     function(inAppId) {
1033       appId = inAppId;
1034       addEntries(['local', 'drive'], NESTED_ENTRY_SET, this.next);
1035     },
1036     function(result) {
1037       chrome.test.assertTrue(result);
1038       callRemoteTestUtil('waitForFiles',
1039                          appId,
1040                          [[ENTRIES.directoryA.getExpectedRow()]],
1041                          this.next);
1042     },
1043     // Open the directory
1044     function() {
1045       callRemoteTestUtil('openFile', appId, ['A'], this.next);
1046     },
1047     // Check the contents of current directory.
1048     function(result) {
1049       chrome.test.assertTrue(result);
1050       callRemoteTestUtil('waitForFiles',
1051                          appId,
1052                          [[ENTRIES.directoryB.getExpectedRow()]],
1053                          this.next);
1054     },
1055     // Open the directory
1056     function() {
1057       callRemoteTestUtil('openFile', appId, ['B'], this.next);
1058     },
1059     // Check the contents of current directory.
1060     function(result) {
1061       chrome.test.assertTrue(result);
1062       callRemoteTestUtil('waitForFiles',
1063                          appId,
1064                          [[ENTRIES.directoryC.getExpectedRow()]],
1065                          this.next);
1066     },
1067     // Check the error.
1068     function() {
1069       checkIfNoErrorsOccured(this.next);
1070     }
1071   ]);
1072 };
1073
1074 /**
1075  * Tests copy from drive's root to local's downloads.
1076  */
1077 testcase.transferFromDriveToDownloads = function() {
1078   testcase.intermediate.copyBetweenVolumes('hello.txt',
1079                                            'drive',
1080                                            BASIC_DRIVE_ENTRY_SET,
1081                                            'downloads',
1082                                            BASIC_LOCAL_ENTRY_SET);
1083 };
1084
1085 /**
1086  * Tests copy from local's downloads to drive's root.
1087  */
1088 testcase.transferFromDownloadsToDrive = function() {
1089   testcase.intermediate.copyBetweenVolumes('hello.txt',
1090                                            'downloads',
1091                                            BASIC_LOCAL_ENTRY_SET,
1092                                            'drive',
1093                                            BASIC_DRIVE_ENTRY_SET);
1094 };
1095
1096 /**
1097  * Tests copy from drive's shared_with_me to local's downloads.
1098  */
1099 testcase.transferFromSharedToDownloads = function() {
1100   testcase.intermediate.copyBetweenVolumes('Test Shared Document.gdoc',
1101                                            'drive_shared_with_me',
1102                                            SHARED_WITH_ME_ENTRY_SET,
1103                                            'downloads',
1104                                            BASIC_LOCAL_ENTRY_SET);
1105 };
1106
1107 /**
1108  * Tests copy from drive's shared_with_me to drive's root.
1109  */
1110 testcase.transferFromSharedToDrive = function() {
1111   testcase.intermediate.copyBetweenVolumes('Test Shared Document.gdoc',
1112                                            'drive_shared_with_me',
1113                                            SHARED_WITH_ME_ENTRY_SET,
1114                                            'drive',
1115                                            BASIC_DRIVE_ENTRY_SET);
1116 };
1117
1118 /**
1119  * Tests copy from drive's recent to local's downloads.
1120  */
1121 testcase.transferFromRecentToDownloads = function() {
1122   testcase.intermediate.copyBetweenVolumes('hello.txt',
1123                                            'drive_recent',
1124                                            RECENT_ENTRY_SET,
1125                                            'downloads',
1126                                            BASIC_LOCAL_ENTRY_SET);
1127 };
1128
1129 /**
1130  * Tests copy from drive's recent to drive's root.
1131  */
1132 testcase.transferFromRecentToDrive = function() {
1133   testcase.intermediate.copyBetweenVolumes('hello.txt',
1134                                            'drive_recent',
1135                                            RECENT_ENTRY_SET,
1136                                            'drive',
1137                                            BASIC_DRIVE_ENTRY_SET);
1138 };
1139
1140 /**
1141  * Tests copy from drive's offline to local's downloads.
1142  */
1143 testcase.transferFromOfflineToDownloads = function() {
1144   testcase.intermediate.copyBetweenVolumes('Test Document.gdoc',
1145                                            'drive_offline',
1146                                            OFFLINE_ENTRY_SET,
1147                                            'downloads',
1148                                            BASIC_LOCAL_ENTRY_SET);
1149 };
1150
1151 /**
1152  * Tests copy from drive's offline to drive's root.
1153  */
1154 testcase.transferFromOfflineToDrive = function() {
1155   testcase.intermediate.copyBetweenVolumes('Test Document.gdoc',
1156                                            'drive_offline',
1157                                            OFFLINE_ENTRY_SET,
1158                                            'drive',
1159                                            BASIC_DRIVE_ENTRY_SET);
1160 };
1161
1162 /**
1163  * Tests sharing a file on Drive
1164  */
1165 testcase.shareFile = function() {
1166   testcase.intermediate.share('world.ogv');
1167 };
1168
1169 /**
1170  * Tests sharing a directory on Drive
1171  */
1172 testcase.shareDirectory = function() {
1173   testcase.intermediate.share('photos');
1174 };
1175
1176 /**
1177  * Tests sharing a file on Drive
1178  */
1179 testcase.suggestAppDialog = function() {
1180   var appId;
1181   StepsRunner.run([
1182     // Set up File Manager.
1183     function() {
1184       chrome.test.sendMessage(
1185           JSON.stringify({name: 'getCwsWidgetContainerMockUrl'}),
1186           this.next);
1187     },
1188     // Override the container URL with the mock.
1189     function(json) {
1190       var data = JSON.parse(json);
1191
1192       var appState = {
1193         defaultPath: '/drive/root',
1194         suggestAppsDialogState: {
1195           overrideCwsContainerUrlForTest: data.url,
1196           overrideCwsContainerOriginForTest: data.origin
1197         }
1198       };
1199       setupAndWaitUntilReady(appState, this.next);
1200     },
1201     function(inAppId, inFileListBefore) {
1202       appId = inAppId;
1203
1204       callRemoteTestUtil(
1205           'selectFile', appId, ['unsupported.foo'], this.next);
1206     },
1207     // Double-click the file.
1208     function(result) {
1209       chrome.test.assertTrue(result);
1210       callRemoteTestUtil(
1211           'fakeMouseDoubleClick',
1212           appId,
1213           ['#file-list li.table-row[selected] .filename-label span'],
1214           this.next);
1215     },
1216     // Wait for the widget is loaded.
1217     function(result) {
1218       chrome.test.assertTrue(result);
1219       callRemoteTestUtil(
1220           'waitForElement',
1221           appId,
1222           ['#suggest-app-dialog webview[src]'],
1223           this.next);
1224     },
1225     // Wait for the widget is initialized.
1226     function(result) {
1227       chrome.test.assertTrue(!!result);
1228       callRemoteTestUtil(
1229           'waitForElement',
1230           appId,
1231           ['#suggest-app-dialog:not(.show-spinner)'],
1232           this.next);
1233     },
1234     // Initiate an installation from the widget.
1235     function(result) {
1236       chrome.test.assertTrue(!!result);
1237       callRemoteTestUtil(
1238           'executeScriptInWebView',
1239           appId,
1240           ['#suggest-app-dialog webview',
1241            'document.querySelector("button").click()'],
1242           this.next);
1243     },
1244     // Wait until the installation is finished and the dialog is closed.
1245     function(result) {
1246       chrome.test.assertTrue(!!result);
1247       callRemoteTestUtil('waitForElement',
1248                          appId,
1249                          ['#suggest-app-dialog',
1250                           null,   // iframeQuery
1251                           true],  // inverse
1252                          this.next);
1253     },
1254     // Check the styles
1255     function(result) {
1256       chrome.test.assertTrue(!!result);
1257       checkIfNoErrorsOccured(this.next);
1258     }
1259   ]);
1260 };
1261
1262 /**
1263  * Tests hiding the search box.
1264  */
1265 testcase.hideSearchBox = function() {
1266   var appId;
1267   StepsRunner.run([
1268     // Set up File Manager.
1269     function() {
1270       var appState = {defaultPath: '/Downloads'};
1271       setupAndWaitUntilReady(appState, this.next);
1272     },
1273     // Resize the window.
1274     function(inAppId, inFileListBefore) {
1275       appId = inAppId;
1276       callRemoteTestUtil('resizeWindow', appId, [100, 100], this.next);
1277     },
1278     // Wait for the style change.
1279     function(result) {
1280       chrome.test.assertTrue(result);
1281       callRemoteTestUtil('waitForStyles',
1282                          appId,
1283                          [{
1284                             query: '#search-box',
1285                             styles: {visibility: 'hidden'}
1286                           }],
1287                          this.next);
1288     },
1289     // Check the styles
1290     function() {
1291       checkIfNoErrorsOccured(this.next);
1292     }
1293   ]);
1294 };
1295
1296 /**
1297  * Tests restoring the sorting order.
1298  */
1299 testcase.restoreSortColumn = function() {
1300   var appId;
1301   var EXPECTED_FILES = TestEntryInfo.getExpectedRows([
1302     ENTRIES.world,
1303     ENTRIES.photos,
1304     ENTRIES.desktop,
1305     ENTRIES.hello,
1306     ENTRIES.beautiful
1307   ]);
1308   StepsRunner.run([
1309     // Set up File Manager.
1310     function() {
1311       var appState = {defaultPath: '/Downloads'};
1312       setupAndWaitUntilReady(appState, this.next);
1313     },
1314     // Sort by name.
1315     function(inAppId) {
1316       appId = inAppId;
1317       callRemoteTestUtil('fakeMouseClick',
1318                          appId,
1319                          ['.table-header-cell:nth-of-type(1)'],
1320                          this.next);
1321     },
1322     // Check the sorted style of the header.
1323     function() {
1324       callRemoteTestUtil('waitForElement',
1325                          appId,
1326                          ['.table-header-sort-image-asc'],
1327                          this.next);
1328     },
1329     // Sort by name.
1330     function() {
1331       callRemoteTestUtil('fakeMouseClick',
1332                          appId,
1333                          ['.table-header-cell:nth-of-type(1)'],
1334                          this.next);
1335     },
1336     // Check the sorted style of the header.
1337     function() {
1338       callRemoteTestUtil('waitForElement',
1339                          appId,
1340                          ['.table-header-sort-image-desc'],
1341                          this.next);
1342     },
1343     // Check the sorted files.
1344     function() {
1345       callRemoteTestUtil('waitForFiles',
1346                          appId,
1347                          [EXPECTED_FILES, {orderCheck: true}],
1348                          this.next);
1349     },
1350     // Open another window, where the sorted column should be restored.
1351     function() {
1352       var appState = {defaultPath: '/Downloads'};
1353       setupAndWaitUntilReady(appState, this.next);
1354     },
1355     // Check the sorted style of the header.
1356     function(inAppId) {
1357       appId = inAppId;
1358       callRemoteTestUtil('waitForElement',
1359                          appId,
1360                          ['.table-header-sort-image-desc'],
1361                          this.next);
1362     },
1363     // Check the sorted files.
1364     function() {
1365       callRemoteTestUtil('waitForFiles',
1366                          appId,
1367                          [EXPECTED_FILES, {orderCheck: true}],
1368                          this.next);
1369     },
1370     // Check the error.
1371     function() {
1372       checkIfNoErrorsOccured(this.next);
1373     }
1374   ]);
1375 };
1376
1377 /**
1378  * Tests restoring the current view (the file list or the thumbnail grid).
1379  */
1380 testcase.restoreCurrentView = function() {
1381   var appId;
1382   StepsRunner.run([
1383     // Set up File Manager.
1384     function() {
1385       var appState = {defaultPath: '/Downloads'};
1386       setupAndWaitUntilReady(appState, this.next);
1387     },
1388     // Check the initial view.
1389     function(inAppId) {
1390       appId = inAppId;
1391       callRemoteTestUtil('waitForElement',
1392                          appId,
1393                          ['.thumbnail-grid[hidden]'],
1394                          this.next);
1395     },
1396     // Change the current view.
1397     function() {
1398       callRemoteTestUtil('fakeMouseClick',
1399                          appId,
1400                          ['#thumbnail-view'],
1401                          this.next);
1402     },
1403     // Check the new current view.
1404     function(result) {
1405       chrome.test.assertTrue(result);
1406       callRemoteTestUtil('waitForElement',
1407                          appId,
1408                          ['.detail-table[hidden]'],
1409                          this.next);
1410     },
1411     // Open another window, where the current view is restored.
1412     function() {
1413       var appState = {defaultPath: '/Downloads'};
1414       callRemoteTestUtil('openMainWindow', null, [appState], this.next);
1415     },
1416     // Check the current view.
1417     function(inAppId) {
1418       appId = inAppId;
1419       callRemoteTestUtil('waitForElement',
1420                          appId,
1421                          ['.detail-table[hidden]'],
1422                          this.next);
1423     },
1424     // Check the error.
1425     function() {
1426       checkIfNoErrorsOccured(this.next);
1427     }
1428   ]);
1429 };
1430
1431 /**
1432  * Tests keyboard operations of the navigation list.
1433  */
1434 testcase.traverseNavigationList = function() {
1435   var appId;
1436   StepsRunner.run([
1437     // Set up File Manager.
1438     function() {
1439       var appState = {defaultPath: '/drive/root'};
1440       setupAndWaitUntilReady(appState, this.next);
1441     },
1442     // Wait for the navigation list.
1443     function(inAppId) {
1444       appId = inAppId;
1445       callRemoteTestUtil(
1446           'waitForElement',
1447           appId,
1448           ['#navigation-list > .root-item > ' +
1449                '.volume-icon[volume-type-icon="drive"]'],
1450           this.next);
1451     },
1452     // Ensure that the 'Gogole Drive' is selected.
1453     function() {
1454       callRemoteTestUtil('checkSelectedVolume',
1455                          appId,
1456                          ['Google Drive', '/drive/root'],
1457                          this.next);
1458     },
1459     // Ensure that the current directory is changed to 'Gogole Drive'.
1460     function(result) {
1461       chrome.test.assertTrue(result);
1462       callRemoteTestUtil('waitForFiles',
1463                          appId,
1464                          [TestEntryInfo.getExpectedRows(BASIC_DRIVE_ENTRY_SET),
1465                           {ignoreLastModifiedTime: true}],
1466                          this.next);
1467     },
1468     // Press the UP key.
1469     function(result) {
1470       chrome.test.assertTrue(result);
1471       callRemoteTestUtil('fakeKeyDown',
1472                          appId,
1473                          ['#navigation-list', 'Up', true],
1474                          this.next);
1475     },
1476     // Ensure that the 'Gogole Drive' is still selected since it is the first
1477     // item.
1478     function(result) {
1479       chrome.test.assertTrue(result);
1480       callRemoteTestUtil('checkSelectedVolume',
1481                          appId,
1482                          ['Google Drive', '/drive/root'],
1483                          this.next);
1484     },
1485     // Press the DOWN key.
1486     function(result) {
1487       chrome.test.assertTrue(result);
1488       callRemoteTestUtil('fakeKeyDown',
1489                          appId,
1490                          ['#navigation-list', 'Down', true],
1491                          this.next);
1492     },
1493     // Ensure that the 'Download' is selected.
1494     function(result) {
1495       chrome.test.assertTrue(result);
1496       callRemoteTestUtil('checkSelectedVolume',
1497                          appId,
1498                          ['Downloads', '/Downloads'],
1499                          this.next);
1500     },
1501     // Ensure that the current directory is changed to 'Downloads'.
1502     function(result) {
1503       chrome.test.assertTrue(result);
1504       callRemoteTestUtil('waitForFiles',
1505                          appId,
1506                          [TestEntryInfo.getExpectedRows(BASIC_LOCAL_ENTRY_SET),
1507                           {ignoreLastModifiedTime: true}],
1508                          this.next);
1509     },
1510     // Press the DOWN key again.
1511     function(result) {
1512       chrome.test.assertTrue(result);
1513       callRemoteTestUtil('fakeKeyDown',
1514                          appId,
1515                          ['#navigation-list', 'Down', true],
1516                          this.next);
1517     },
1518     // Ensure that the 'Downloads' is still selected since it is the last item.
1519     function(result) {
1520       chrome.test.assertTrue(result);
1521       callRemoteTestUtil('checkSelectedVolume',
1522                          appId,
1523                          ['Downloads', '/Downloads'],
1524                          this.next);
1525     },
1526     // Check for errors.
1527     function(result) {
1528       chrome.test.assertTrue(result);
1529       checkIfNoErrorsOccured(this.next);
1530     }
1531   ]);
1532 };
1533
1534 /**
1535  * Tests restoring geometry of the Files app.
1536  */
1537 testcase.restoreGeometry = function() {
1538   var appId;
1539   var appId2;
1540   StepsRunner.run([
1541     // Set up File Manager.
1542     function() {
1543       var appState = {defaultPath: '/Downloads'};
1544       setupAndWaitUntilReady(appState, this.next);
1545     },
1546     // Resize the window to minimal dimensions.
1547     function(inAppId) {
1548       appId = inAppId;
1549       callRemoteTestUtil(
1550           'resizeWindow', appId, [640, 480], this.next);
1551     },
1552     // Check the current window's size.
1553     function(inAppId) {
1554       callRemoteTestUtil('waitForWindowGeometry',
1555                          appId,
1556                          [640, 480],
1557                          this.next);
1558     },
1559     // Enlarge the window by 10 pixels.
1560     function(result) {
1561       callRemoteTestUtil(
1562           'resizeWindow', appId, [650, 490], this.next);
1563     },
1564     // Check the current window's size.
1565     function() {
1566       callRemoteTestUtil('waitForWindowGeometry',
1567                          appId,
1568                          [650, 490],
1569                          this.next);
1570     },
1571     // Open another window, where the current view is restored.
1572     function() {
1573       var appState = {defaultPath: '/Downloads'};
1574       setupAndWaitUntilReady(appState, this.next);
1575     },
1576     // Check the next window's size.
1577     function(inAppId) {
1578       appId2 = inAppId;
1579       callRemoteTestUtil('waitForWindowGeometry',
1580                          appId2,
1581                          [650, 490],
1582                          this.next);
1583     },
1584     // Check for errors.
1585     function() {
1586       checkIfNoErrorsOccured(this.next);
1587     }
1588   ]);
1589 };
1590
1591 /**
1592  * Tests to traverse local directories.
1593  */
1594 testcase.traverseDownloads =
1595     testcase.intermediate.traverseDirectories.bind(null, '/Downloads');
1596
1597 /**
1598  * Tests to traverse drive directories.
1599  */
1600 testcase.traverseDrive =
1601     testcase.intermediate.traverseDirectories.bind(null, '/drive/root');
1602
1603 /**
1604  * Tests the focus behavior of the search box.
1605  */
1606 testcase.searchBoxFocus = function() {
1607   var appId;
1608   StepsRunner.run([
1609     // Set up File Manager.
1610     function() {
1611       var appState = {defaultPath: '/drive/root'};
1612       setupAndWaitUntilReady(appState, this.next);
1613     },
1614     // Check that the file list has the focus on launch.
1615     function(inAppId) {
1616       appId = inAppId;
1617       callRemoteTestUtil(
1618           'waitForElement', appId, ['#file-list:focus'], this.next);
1619     },
1620     // Press the Ctrl-F key.
1621     function(element) {
1622       callRemoteTestUtil('fakeKeyDown',
1623                          appId,
1624                          ['body', 'U+0046', true],
1625                          this.next);
1626     },
1627     // Check that the search box has the focus.
1628     function(result) {
1629       chrome.test.assertTrue(result);
1630       callRemoteTestUtil(
1631           'waitForElement', appId, ['#search-box input:focus'], this.next);
1632     },
1633     // Press the Tab key.
1634     function(element) {
1635       callRemoteTestUtil('fakeKeyDown',
1636                          appId,
1637                          ['body', 'U+0009', false],
1638                          this.next);
1639     },
1640     // Check that the file list has the focus.
1641     function(result) {
1642       chrome.test.assertTrue(result);
1643       callRemoteTestUtil(
1644           'waitForElement', appId, ['#file-list:focus'], this.next);
1645     },
1646     // Check for errors.
1647     function(element) {
1648       checkIfNoErrorsOccured(this.next);
1649     }
1650   ]);
1651 };