Commit 52a31949 authored by Joel Hockey's avatar Joel Hockey Committed by Commit Bot

Run integration tests using test/main.html

Converted integration_tests/delete.js to test/js/delete.js

Copied the parts of integration_tests/test_util.js required
for delete.js to test/js/test_util.js and got TestEntryInfo
integrated with MockVolumeManager.

Added extra API implementations required:
- chrome.i18n
- chrome.mediaGalleries
- window.domAutomationController

Added webui_resource_test.js and test_util.js to create script.

Bug: 813477
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: Ie6704f98f8d8c2116c72c2d7a2c22cda246eb0a0
Reviewed-on: https://chromium-review.googlesource.com/961986
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarSasha Morrissey <sashab@chromium.org>
Cr-Commit-Position: refs/heads/master@{#543564}
parent 823c476a
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
action("create_test_main") {
script = "//ui/file_manager/file_manager/test/scripts/create_test_main.py"
output = "$target_gen_dir/main.html"
args = [ "--output=" + rebase_path(output, root_build_dir) ]
outputs = [
output,
]
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function testDeleteMenuItemIsDisabledWhenNoItemIsSelected(done) {
setupAndWaitUntilReady()
.then(detailTable => {
return waitForElement('list.list');
})
.then(emptySpace => {
assertTrue(test.util.sync.fakeMouseRightClick(window, 'list.list'));
return waitForElement('#file-context-menu:not([hidden])');
})
.then(result => {
return waitForElement(
'cr-menu-item[command="#delete"][disabled="disabled"]');
})
.then(result => {
done();
})
.catch(err => {
console.error(err);
done(true);
});
}
function testDeleteOneItemFromToolbar(done) {
var beforeDeletion = TestEntryInfo.getExpectedRows([
ENTRIES.photos,
ENTRIES.hello,
ENTRIES.world,
ENTRIES.desktop,
ENTRIES.beautiful
]);
var afterDeletion = TestEntryInfo.getExpectedRows([
ENTRIES.photos,
ENTRIES.hello,
ENTRIES.world,
ENTRIES.beautiful
]);
setupAndWaitUntilReady()
.then(detailTable => {
return waitForFiles(beforeDeletion);
})
.then(result => {
return test.util.sync.selectFile(window, 'My Desktop Background.png');
})
.then(result => {
assertTrue(result);
return test.util.sync.fakeMouseClick(window, 'button#delete-button');
})
.then(result => {
assertTrue(result);
return waitForElement('.cr-dialog-container.shown');
})
.then(result => {
return test.util.sync.fakeMouseClick(window, 'button.cr-dialog-ok');
})
.then(result => {
assertTrue(result);
return waitForFiles(afterDeletion);
})
.then(result => {
done();
})
.catch(err => {
console.error(err);
done(err);
});
}
...@@ -26,7 +26,6 @@ chrome = { ...@@ -26,7 +26,6 @@ chrome = {
commandLinePrivate: { commandLinePrivate: {
switches_: {}, switches_: {},
hasSwitch: (name, callback) => { hasSwitch: (name, callback) => {
console.debug('chrome.commandLinePrivate.hasSwitch called', name);
setTimeout(callback, 0, chrome.commandLinePrivate.switches_[name]); setTimeout(callback, 0, chrome.commandLinePrivate.switches_[name]);
}, },
}, },
...@@ -40,7 +39,6 @@ chrome = { ...@@ -40,7 +39,6 @@ chrome = {
echoPrivate: { echoPrivate: {
getOfferInfo: (id, callback) => { getOfferInfo: (id, callback) => {
console.debug('chrome.echoPrivate.getOfferInfo called', id);
setTimeout(() => { setTimeout(() => {
// checkSpaceAndMaybeShowWelcomeBanner_ relies on lastError being set. // checkSpaceAndMaybeShowWelcomeBanner_ relies on lastError being set.
chrome.runtime.lastError = {message: 'Not found'}; chrome.runtime.lastError = {message: 'Not found'};
...@@ -52,7 +50,6 @@ chrome = { ...@@ -52,7 +50,6 @@ chrome = {
extension: { extension: {
getViews: (fetchProperties) => { getViews: (fetchProperties) => {
console.debug('chrome.extension.getViews called', fetchProperties);
// Returns Window[]. // Returns Window[].
return [window]; return [window];
}, },
...@@ -65,11 +62,18 @@ chrome = { ...@@ -65,11 +62,18 @@ chrome = {
}, },
}, },
i18n: {
getMessage: (messageName, opt_substitutions) => {
return messageName;
},
},
metricsPrivate: { metricsPrivate: {
MetricTypeType: { MetricTypeType: {
HISTOGRAM_LINEAR: 'histogram-linear', HISTOGRAM_LINEAR: 'histogram-linear',
}, },
recordMediumCount: () => {}, recordMediumCount: () => {},
recordPercentage: () => {},
recordSmallCount: () => {}, recordSmallCount: () => {},
recordTime: () => {}, recordTime: () => {},
recordUserAction: () => {}, recordUserAction: () => {},
...@@ -97,19 +101,31 @@ chrome = { ...@@ -97,19 +101,31 @@ chrome = {
onMessageExternal: { onMessageExternal: {
addListener: () => {}, addListener: () => {},
}, },
sendMessage: (extensionId, message, options, opt_callback) => {
// Returns JSON.
if (opt_callback)
setTimeout(opt_callback(''), 0);
},
}, },
storage: { storage: {
state: {},
local: { local: {
get: (keys, callback) => { get: (keys, callback) => {
console.debug('chrome.storage.local.get', keys); var keys = keys instanceof Array ? keys : [keys];
setTimeout(callback, 0, {}); var result = {};
}, keys.forEach(function(key) {
set: (items, callback) => { if (key in chrome.storage.state)
console.debug('chrome.storage.local.set', items); result[key] = chrome.storage.state[key];
if (callback) { });
setTimeout(callback, 0); setTimeout(callback, 0, result);
},
set: (items, opt_callback) => {
for (var key in items) {
chrome.storage.state[key] = items[key];
} }
if (opt_callback)
setTimeout(opt_callback, 0);
}, },
}, },
onChanged: { onChanged: {
...@@ -117,7 +133,6 @@ chrome = { ...@@ -117,7 +133,6 @@ chrome = {
}, },
sync: { sync: {
get: (keys, callback) => { get: (keys, callback) => {
console.debug('chrome.storage.sync.get', keys);
setTimeout(callback, 0, {}); setTimeout(callback, 0, {});
} }
}, },
...@@ -128,14 +143,17 @@ chrome = { ...@@ -128,14 +143,17 @@ chrome = {
// a WebView. It calls WebView.request.onBeforeSendHeaders. // a WebView. It calls WebView.request.onBeforeSendHeaders.
HTMLElement.prototype.request = { HTMLElement.prototype.request = {
onBeforeSendHeaders: { onBeforeSendHeaders: {
addListener: () => { addListener: () => {},
console.debug(
'HTMLElement.request.onBeforeSendHeaders.addListener called');
},
}, },
}; };
// cws_widget_container.js also calls WebView.stop. // cws_widget_container.js also calls WebView.stop.
HTMLElement.prototype.stop = () => { HTMLElement.prototype.stop = () => {};
console.debug('HTMLElement.stop called');
// domAutomationController is provided in tests, but is
// useful for debugging tests in browser.
window.domAutomationController = window.domAutomationController || {
send: msg => {
console.debug('domAutomationController.send', msg);
},
}; };
...@@ -7,17 +7,19 @@ ...@@ -7,17 +7,19 @@
// running as a regular web page, we must provide test implementations. // running as a regular web page, we must provide test implementations.
mockVolumeManager = new MockVolumeManager(); mockVolumeManager = new MockVolumeManager();
mockVolumeManager
.getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DOWNLOADS) // Create drive /root/ immediately.
.fileSystem.populate(
['/New Folder/', '/a.txt', '/kittens.jpg', '/unknown.ext']);
mockVolumeManager mockVolumeManager
.getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DRIVE) .getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DRIVE)
.fileSystem.populate( .fileSystem.populate(['/root/']);
['/root/New Folder/', '/root/a.txt', '/root/kittens.jpg']);
chrome.fileManagerPrivate = { chrome.fileManagerPrivate = {
currentId_: 'test@example.com', currentId_: 'test@example.com',
dispatchEvent_: function(listenerType, event) {
setTimeout(() => {
this[listenerType].listeners_.forEach(l => l.call(null, event));
}, 0);
},
displayedId_: 'test@example.com', displayedId_: 'test@example.com',
preferences_: { preferences_: {
allowRedeemOffers: true, allowRedeemOffers: true,
...@@ -28,6 +30,9 @@ chrome.fileManagerPrivate = { ...@@ -28,6 +30,9 @@ chrome.fileManagerPrivate = {
timezone: 'Australia/Sydney', timezone: 'Australia/Sydney',
use24hourClock: false, use24hourClock: false,
}, },
listeners_: {
'onDirectoryChanged': [],
},
profiles_: [{ profiles_: [{
displayName: 'Test User', displayName: 'Test User',
isCurrentProfile: true, isCurrentProfile: true,
...@@ -40,67 +45,60 @@ chrome.fileManagerPrivate = { ...@@ -40,67 +45,60 @@ chrome.fileManagerPrivate = {
NATIVE_SOURCE: 'native_source', NATIVE_SOURCE: 'native_source',
}, },
addFileWatch: (entry, callback) => { addFileWatch: (entry, callback) => {
console.debug('c.fmp.addFileWatch called', entry); // Returns success.
setTimeout(callback, 0, true); setTimeout(callback, 0, true);
}, },
enableExternalFileScheme: () => { enableExternalFileScheme: () => {},
console.debug('c.fmp.enableExternalFileScheme called');
},
executeTask: (taskId, entries, callback) => { executeTask: (taskId, entries, callback) => {
console.debug('c.fmp.executeTask called', taskId, entries);
// Returns opened|message_sent|failed|empty. // Returns opened|message_sent|failed|empty.
setTimeout(callback, 0, 'failed'); setTimeout(callback, 0, 'failed');
}, },
getDriveConnectionState: (callback) => { getDriveConnectionState: (callback) => {
console.debug('c.fmp.getDriveConnectionState called');
setTimeout(callback, 0, mockVolumeManager.getDriveConnectionState()); setTimeout(callback, 0, mockVolumeManager.getDriveConnectionState());
}, },
getEntryProperties: (entries, names, callback) => { getEntryProperties: (entries, names, callback) => {
console.debug('c.fmp.getEntryProperties called', entries, names);
// Returns EntryProperties[]. // Returns EntryProperties[].
var results = []; var results = [];
for (var i = 0; i < entries.length; i++) { entries.forEach(entry => {
results.push({}); var props = {};
} names.forEach(name => {
props[name] = entry.metadata[name];
});
results.push(props);
});
setTimeout(callback, 0, results); setTimeout(callback, 0, results);
}, },
getFileTasks: (entries, callback) => { getFileTasks: (entries, callback) => {
console.debug('c.fmp.getFileTasks called', entries);
// Returns FileTask[]. // Returns FileTask[].
setTimeout(callback, 0, []); setTimeout(callback, 0, []);
}, },
getPreferences: (callback) => { getPreferences: (callback) => {
console.debug('c.fmp.getPreferences called');
setTimeout(callback, 0, chrome.fileManagerPrivate.preferences_); setTimeout(callback, 0, chrome.fileManagerPrivate.preferences_);
}, },
getProfiles: (callback) => { getProfiles: (callback) => {
console.debug('c.fmp.getProfiles called'); // Returns profiles, currentId, displayedId
setTimeout( setTimeout(
callback, 0, chrome.fileManagerPrivate.profiles_, callback, 0, chrome.fileManagerPrivate.profiles_,
chrome.fileManagerPrivate.currentId_, chrome.fileManagerPrivate.currentId_,
chrome.fileManagerPrivate.displayedId_); chrome.fileManagerPrivate.displayedId_);
}, },
getProviders: (callback) => { getProviders: (callback) => {
console.debug('c.fmp.getProviders called');
// Returns Provider[]. // Returns Provider[].
setTimeout(callback, 0, []); setTimeout(callback, 0, []);
}, },
getRecentFiles: (restriction, callback) => { getRecentFiles: (restriction, callback) => {
console.debug('c.fmp.getRecentFiles called', restriction);
// Returns Entry[]. // Returns Entry[].
setTimeout(callback, 0, []); setTimeout(callback, 0, []);
}, },
getSizeStats: (volumeId, callback) => { getSizeStats: (volumeId, callback) => {
console.debug('c.fmp.getSizeStats called', volumeId);
// MountPointSizeStats { totalSize: double, remainingSize: double } // MountPointSizeStats { totalSize: double, remainingSize: double }
setTimeout(callback, 0, {totalSize: 16e9, remainingSize: 8e9}); setTimeout(callback, 0, {totalSize: 16e9, remainingSize: 8e9});
}, },
getStrings: (callback) => { getStrings: (callback) => {
console.debug('c.fmp.getStrings called'); // Returns map of strings.
setTimeout(callback, 0, loadTimeData.data_); setTimeout(callback, 0, loadTimeData.data_);
}, },
getVolumeMetadataList: (callback) => { getVolumeMetadataList: (callback) => {
console.debug('c.fmp.getVolumeMetadatalist called');
var list = []; var list = [];
for (var i = 0; i < mockVolumeManager.volumeInfoList.length; i++) { for (var i = 0; i < mockVolumeManager.volumeInfoList.length; i++) {
list.push(mockVolumeManager.volumeInfoList.item(i)); list.push(mockVolumeManager.volumeInfoList.item(i));
...@@ -108,80 +106,70 @@ chrome.fileManagerPrivate = { ...@@ -108,80 +106,70 @@ chrome.fileManagerPrivate = {
setTimeout(callback, 0, list); setTimeout(callback, 0, list);
}, },
grantAccess: (entryUrls, callback) => { grantAccess: (entryUrls, callback) => {
console.debug('c.fmp.grantAccess called', entryUrls);
setTimeout(callback, 0); setTimeout(callback, 0);
}, },
isUMAEnabled: (callback) => { isUMAEnabled: (callback) => {
console.debug('c.fmp.isUMAEnabled called');
setTimeout(callback, 0, false); setTimeout(callback, 0, false);
}, },
onAppsUpdated: { onAppsUpdated: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onAppsUpdated.addListener called');
},
}, },
onDeviceChanged: { onDeviceChanged: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onDeviceChanged.addListener called');
},
}, },
onDirectoryChanged: { onDirectoryChanged: {
addListener: () => { listeners_: [],
console.debug('c.fmp.onDirectoryChanged.addListener called'); addListener: function(l) {
this.listeners_.push(l);
}, },
}, },
onDriveConnectionStatusChanged: { onDriveConnectionStatusChanged: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onDriveConnectionStatusChanged.addListener called');
},
}, },
onDriveSyncError: { onDriveSyncError: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onDriveSyncError.addListener called');
},
}, },
onFileTransfersUpdated: { onFileTransfersUpdated: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onFileTransfersUpdated.addListener called');
},
}, },
onMountCompleted: { onMountCompleted: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onMountCompleted.addListener called');
},
}, },
onPreferencesChanged: { onPreferencesChanged: {
addListener: () => { addListener: () => {},
console.debug('c.fmp.onPreferencesChanged.addListener called');
},
}, },
removeFileWatch: (entry, callback) => { removeFileWatch: (entry, callback) => {
console.debug('c.fmp.removeFileWatch called', entry);
setTimeout(callback, 0, true); setTimeout(callback, 0, true);
}, },
requestWebStoreAccessToken: (callback) => { requestWebStoreAccessToken: (callback) => {
console.debug('c.fmp.requestWebStoreAccessToken called');
setTimeout(callback, 0, chrome.fileManagerPrivate.token_); setTimeout(callback, 0, chrome.fileManagerPrivate.token_);
}, },
resolveIsolatedEntries: (entries, callback) => { resolveIsolatedEntries: (entries, callback) => {
console.debug('c.fmp.resolveIsolatedEntries called', entries);
setTimeout(callback, 0, entries); setTimeout(callback, 0, entries);
}, },
searchDriveMetadata: (searchParams, callback) => { searchDriveMetadata: (searchParams, callback) => {
console.debug('c.fmp.searchDriveMetadata called', searchParams);
// Returns SearchResult[]. // Returns SearchResult[].
// SearchResult { entry: Entry, highlightedBaseName: string } // SearchResult { entry: Entry, highlightedBaseName: string }
setTimeout(callback, 0, []); setTimeout(callback, 0, []);
}, },
validatePathNameLength: (parentEntry, name, callback) => { validatePathNameLength: (parentEntry, name, callback) => {
console.debug('c.fmp.validatePathNameLength called', parentEntry, name);
setTimeout(callback, 0, true); setTimeout(callback, 0, true);
}, },
}; };
chrome.mediaGalleries = {
getMetadata: (mediaFile, options, callback) => {
// Returns metdata {mimeType: ..., ...}.
setTimeout(() => {
webkitResolveLocalFileSystemURL(mediaFile.name, entry => {
callback({mimeType: entry.metadata.contentMimeType});
}, 0);
});
},
};
chrome.fileSystem = { chrome.fileSystem = {
requestFileSystem: (options, callback) => { requestFileSystem: (options, callback) => {
console.debug('chrome.fileSystem.requestFileSystem called', options);
var volume = var volume =
mockVolumeManager.volumeInfoList.findByVolumeId(options.volumeId); mockVolumeManager.volumeInfoList.findByVolumeId(options.volumeId);
setTimeout(callback, 0, volume ? volume.fileSystem : null); setTimeout(callback, 0, volume ? volume.fileSystem : null);
...@@ -195,13 +183,14 @@ chrome.fileSystem = { ...@@ -195,13 +183,14 @@ chrome.fileSystem = {
* @param {function(!DOMException)} errorCallback Error callback. * @param {function(!DOMException)} errorCallback Error callback.
*/ */
webkitResolveLocalFileSystemURL = (url, successCallback, errorCallback) => { webkitResolveLocalFileSystemURL = (url, successCallback, errorCallback) => {
console.debug('webkitResolveLocalFileSystemURL', url);
var match = url.match(/^filesystem:(\w+)(\/.*)/); var match = url.match(/^filesystem:(\w+)(\/.*)/);
if (match) { if (match) {
var volumeType = match[1]; var volumeType = match[1];
var path = match[2]; var path = match[2];
var volume = mockVolumeManager.getCurrentProfileVolumeInfo(volumeType); var volume = mockVolumeManager.getCurrentProfileVolumeInfo(volumeType);
if (volume) { if (volume) {
// Decode URI in file paths.
path = path.split('/').map(decodeURIComponent).join('/');
var entry = volume.fileSystem.entries[path]; var entry = volume.fileSystem.entries[path];
if (entry) { if (entry) {
setTimeout(successCallback, 0, entry); setTimeout(successCallback, 0, entry);
......
...@@ -9,12 +9,14 @@ ...@@ -9,12 +9,14 @@
loadTimeData.data = new Proxy( loadTimeData.data = new Proxy(
{ {
AUDIO_FILE_TYPE: '$1 audio',
CANCEL_LABEL: 'Cancel', CANCEL_LABEL: 'Cancel',
CHROMEOS_RELEASE_BOARD: 'unknown', CHROMEOS_RELEASE_BOARD: 'unknown',
COPY_ITEMS_REMAINING: 'Copying $1 items...', COPY_ITEMS_REMAINING: 'Copying $1 items...',
DEFAULT_NEW_FOLDER_NAME: 'New Folder', DEFAULT_NEW_FOLDER_NAME: 'New Folder',
DELETE_FILE_NAME: 'Deleting "$1"...', DELETE_FILE_NAME: 'Deleting "$1"...',
DOWNLOADS_DIRECTORY_LABEL: 'Downloads', DOWNLOADS_DIRECTORY_LABEL: 'Downloads',
DATE_COLUMN_LABEL: 'Date modified',
DRIVE_BUY_MORE_SPACE: 'Buy more storage...', DRIVE_BUY_MORE_SPACE: 'Buy more storage...',
DRIVE_DIRECTORY_LABEL: 'Google Drive', DRIVE_DIRECTORY_LABEL: 'Google Drive',
DRIVE_MENU_HELP: 'Help', DRIVE_MENU_HELP: 'Help',
...@@ -40,22 +42,34 @@ loadTimeData.data = new Proxy( ...@@ -40,22 +42,34 @@ loadTimeData.data = new Proxy(
EMPTY_FOLDER: 'Nothing to see here...', EMPTY_FOLDER: 'Nothing to see here...',
FILENAME_LABEL: 'File name', FILENAME_LABEL: 'File name',
GALLERY_CONFIRM_DELETE_ONE: 'Are you sure you want to delete "$1"?', GALLERY_CONFIRM_DELETE_ONE: 'Are you sure you want to delete "$1"?',
GDOC_DOCUMENT_FILE_TYPE: 'Google document',
GENERIC_FILE_TYPE: '$1 file',
GOOGLE_DRIVE_REDEEM_URL: 'http://www.google.com/intl/en/chrome/' + GOOGLE_DRIVE_REDEEM_URL: 'http://www.google.com/intl/en/chrome/' +
'devices/goodies.html?utm_source=filesapp&utm_medium=banner&' + 'devices/goodies.html?utm_source=filesapp&utm_medium=banner&' +
'utm_campaign=gsg', 'utm_campaign=gsg',
IMAGE_FILE_TYPE: '$1 image', IMAGE_FILE_TYPE: '$1 image',
INSTALL_NEW_EXTENSION_LABEL: 'Install new from the webstore', INSTALL_NEW_EXTENSION_LABEL: 'Install new from the webstore',
MANY_ENTRIES_SELECTED: '$1 items selected',
MANY_FILES_SELECTED: '$1 files selected', MANY_FILES_SELECTED: '$1 files selected',
NAME_COLUMN_LABEL: 'Name',
OFFLINE_COLUMN_LABEL: 'Available offline',
OK_LABEL: 'OK', OK_LABEL: 'OK',
ONE_DIRECTORY_SELECTED: '1 folder selected',
ONE_FILE_SELECTED: '1 file selected', ONE_FILE_SELECTED: '1 file selected',
OPEN_LABEL: 'Open', OPEN_LABEL: 'Open',
PLAIN_TEXT_FILE_TYPE: 'Plain text',
PREPARING_LABEL: 'Preparing', PREPARING_LABEL: 'Preparing',
SIZE_COLUMN_LABEL: 'Size',
SPACE_AVAILABLE: '$1 available', SPACE_AVAILABLE: '$1 available',
STATUS_COLUMN_LABEL: 'Status',
TYPE_COLUMN_LABEL: 'Type',
UI_LOCALE: 'en_US', UI_LOCALE: 'en_US',
RECENT_ROOT_LABEL: 'Recent', RECENT_ROOT_LABEL: 'Recent',
SEARCH_TEXT_LABEL: 'Search', SEARCH_TEXT_LABEL: 'Search',
SIZE_BYTES: '$1 bytes', SIZE_BYTES: '$1 bytes',
SIZE_GB: '$1 GB', SIZE_GB: '$1 GB',
SIZE_KB: '$1 KB',
SIZE_PB: '$1 PB',
SUGGEST_DIALOG_INSTALLATION_FAILED: 'Installation failed.', SUGGEST_DIALOG_INSTALLATION_FAILED: 'Installation failed.',
SUGGEST_DIALOG_INSTALLING_SPINNER_ALT: 'Installing', SUGGEST_DIALOG_INSTALLING_SPINNER_ALT: 'Installing',
SUGGEST_DIALOG_LINK_TO_WEBSTORE: 'See more...', SUGGEST_DIALOG_LINK_TO_WEBSTORE: 'See more...',
...@@ -63,6 +77,7 @@ loadTimeData.data = new Proxy( ...@@ -63,6 +77,7 @@ loadTimeData.data = new Proxy(
SUGGEST_DIALOG_TITLE: 'Select an app to open this file', SUGGEST_DIALOG_TITLE: 'Select an app to open this file',
TASK_OPEN: 'Open', TASK_OPEN: 'Open',
TOGGLE_HIDDEN_FILES_COMMAND_LABEL: 'Show hidden files', TOGGLE_HIDDEN_FILES_COMMAND_LABEL: 'Show hidden files',
VIDEO_FILE_TYPE: '$1 video',
WAITING_FOR_SPACE_INFO: 'Waiting for space info...', WAITING_FOR_SPACE_INFO: 'Waiting for space info...',
language: 'en', language: 'en',
textdirection: 'ltr', textdirection: 'ltr',
...@@ -84,8 +99,6 @@ loadTimeData.data = new Proxy( ...@@ -84,8 +99,6 @@ loadTimeData.data = new Proxy(
/^SHORTCUT_/, /^SHORTCUT_/,
/_BUTTON_LABEL$/, /_BUTTON_LABEL$/,
/_BUTTON_TOOLTIP$/, /_BUTTON_TOOLTIP$/,
/_COLUMN_LABEL$/,
/_FILE_TYPE$/,
]; ];
for (var i = 0; i < autoConvert.length; i++) { for (var i = 0; i < autoConvert.length; i++) {
if (prop.match(autoConvert[i])) { if (prop.match(autoConvert[i])) {
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
'use strict';
// Stores Blobs loaded from src/chrome/test/data/chromeos/file_manager.
var DATA = {
'archive.zip': null,
'image.png': null,
'image2.png': null,
'image3.jpg': null,
'music.ogg': null,
'random.bin': null,
'text.txt': null,
'video.ogv': null,
};
// Load DATA from local filesystem.
function loadData() {
return Promise.all(Object.keys(DATA).map(filename => {
return new Promise(resolve => {
var req = new XMLHttpRequest();
req.responseType = 'blob';
req.onload = () => {
DATA[filename] = req.response;
resolve();
};
req.open(
'GET',
'../../../../chrome/test/data/chromeos/file_manager/' + filename);
req.send();
});
}));
}
/**
* @enum {string}
* @const
*/
var EntryType = Object.freeze({
FILE: 'file',
DIRECTORY: 'directory'
});
/**
* @enum {string}
* @const
*/
var SharedOption = Object.freeze({
NONE: 'none',
SHARED: 'shared'
});
/**
* File system entry information for tests.
*
* @param {EntryType} type Entry type.
* @param {string} sourceFileName Source file name that provides file contents.
* @param {string} targetName Name of entry on the test file system.
* @param {string} mimeType Mime type.
* @param {SharedOption} sharedOption Shared option.
* @param {string} lastModifiedTime Last modified time as a text to be shown in
* the last modified column.
* @param {string} nameText File name to be shown in the name column.
* @param {string} sizeText Size text to be shown in the size column.
* @param {string} typeText Type name to be shown in the type column.
* @constructor
*/
function TestEntryInfo(type,
sourceFileName,
targetPath,
mimeType,
sharedOption,
lastModifiedTime,
nameText,
sizeText,
typeText) {
this.type = type;
this.sourceFileName = sourceFileName || '';
this.targetPath = targetPath;
this.mimeType = mimeType || '';
this.sharedOption = sharedOption;
this.lastModifiedTime = lastModifiedTime;
this.nameText = nameText;
this.sizeText = sizeText;
this.typeText = typeText;
Object.freeze(this);
}
TestEntryInfo.getExpectedRows = function(entries) {
return entries.map(function(entry) { return entry.getExpectedRow(); });
};
/**
* Returns 4-typle name, size, type, date as shown in file list.
*/
TestEntryInfo.prototype.getExpectedRow = function() {
return [this.nameText, this.sizeText, this.typeText, this.lastModifiedTime];
};
TestEntryInfo.getMockFileSystemPopulateRows = function(entries, prefix) {
return entries.map(function(entry) {
return entry.getMockFileSystemPopulateRow(prefix);
});
};
/**
* Returns object {fullPath: ..., metadata: {...}, content: ...} as used in
* MockFileSystem.populate.
*/
TestEntryInfo.prototype.getMockFileSystemPopulateRow = function(prefix) {
var suffix = this.type == EntryType.DIRECTORY ? '/' : '';
var content = DATA[this.sourceFileName];
var size = content && content.size || 0;
return {
fullPath: prefix + this.nameText + suffix,
metadata: {
size: size,
modificationTime: new Date(Date.parse(this.lastModifiedTime)),
contentMimeType: this.mimeType,
},
content: content
};
};
/**
* Filesystem entries used by the test cases.
* @type {Object<TestEntryInfo>}
* @const
*/
var ENTRIES = {
hello: new TestEntryInfo(
EntryType.FILE, 'text.txt', 'hello.txt',
'text/plain', SharedOption.NONE, 'Sep 4, 1998, 12:34 PM',
'hello.txt', '51 bytes', 'Plain text'),
world: new TestEntryInfo(
EntryType.FILE, 'video.ogv', 'world.ogv',
'video/ogg', SharedOption.NONE, 'Jul 4, 2012, 10:35 AM',
'world.ogv', '59 KB', 'OGG video'),
unsupported: new TestEntryInfo(
EntryType.FILE, 'random.bin', 'unsupported.foo',
'application/x-foo', SharedOption.NONE, 'Jul 4, 2012, 10:36 AM',
'unsupported.foo', '8 KB', 'FOO file'),
desktop: new TestEntryInfo(
EntryType.FILE, 'image.png', 'My Desktop Background.png',
'image/png', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
'My Desktop Background.png', '272 bytes', 'PNG image'),
// An image file without an extension, to confirm that file type detection
// using mime types works fine.
image2: new TestEntryInfo(
EntryType.FILE, 'image2.png', 'image2',
'image/png', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
'image2', '4 KB', 'PNG image'),
image3: new TestEntryInfo(
EntryType.FILE, 'image3.jpg', 'image3.jpg',
'image/jpeg', SharedOption.NONE, 'Jan 18, 2038, 1:02 AM',
'image3.jpg', '3 KB', 'JPEG image'),
// An ogg file without a mime type, to confirm that file type detection using
// file extensions works fine.
beautiful: new TestEntryInfo(
EntryType.FILE, 'music.ogg', 'Beautiful Song.ogg',
null, SharedOption.NONE, 'Nov 12, 2086, 12:00 PM',
'Beautiful Song.ogg', '14 KB', 'OGG audio'),
photos: new TestEntryInfo(
EntryType.DIRECTORY, null, 'photos',
null, SharedOption.NONE, 'Jan 1, 1980, 11:59 PM',
'photos', '--', 'Folder'),
testDocument: new TestEntryInfo(
EntryType.FILE, null, 'Test Document',
'application/vnd.google-apps.document',
SharedOption.NONE, 'Apr 10, 2013, 4:20 PM',
'Test Document.gdoc', '--', 'Google document'),
testSharedDocument: new TestEntryInfo(
EntryType.FILE, null, 'Test Shared Document',
'application/vnd.google-apps.document',
SharedOption.SHARED, 'Mar 20, 2013, 10:40 PM',
'Test Shared Document.gdoc', '--', 'Google document'),
newlyAdded: new TestEntryInfo(
EntryType.FILE, 'music.ogg', 'newly added file.ogg',
'audio/ogg', SharedOption.NONE, 'Sep 4, 1998, 12:00 AM',
'newly added file.ogg', '14 KB', 'OGG audio'),
directoryA: new TestEntryInfo(
EntryType.DIRECTORY, null, 'A',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'A', '--', 'Folder'),
directoryB: new TestEntryInfo(
EntryType.DIRECTORY, null, 'A/B',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'B', '--', 'Folder'),
directoryC: new TestEntryInfo(
EntryType.DIRECTORY, null, 'A/B/C',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'C', '--', 'Folder'),
directoryD: new TestEntryInfo(
EntryType.DIRECTORY, null, 'D',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'D', '--', 'Folder'),
directoryE: new TestEntryInfo(
EntryType.DIRECTORY, null, 'D/E',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'E', '--', 'Folder'),
directoryF: new TestEntryInfo(
EntryType.DIRECTORY, null, 'D/E/F',
null, SharedOption.NONE, 'Jan 1, 2000, 1:00 AM',
'F', '--', 'Folder'),
zipArchive: new TestEntryInfo(
EntryType.FILE, 'archive.zip', 'archive.zip',
'application/x-zip', SharedOption.NONE, 'Jan 1, 2014, 1:00 AM',
'archive.zip', '533 bytes', 'Zip archive'),
hiddenFile: new TestEntryInfo(
EntryType.FILE, 'text.txt', '.hiddenfile.txt',
'text/plain', SharedOption.NONE, 'Sep 30, 2014, 3:30 PM',
'.hiddenfile.txt', '51 bytes', 'Plain text')
};
/**
* Basic entry set for the local volume.
* @type {Array<TestEntryInfo>}
* @const
*/
var BASIC_LOCAL_ENTRY_SET = [
ENTRIES.hello,
ENTRIES.world,
ENTRIES.desktop,
ENTRIES.beautiful,
ENTRIES.photos
];
/**
* Basic entry set for the drive volume.
*
* TODO(hirono): Add a case for an entry cached by FileCache. For testing
* Drive, create more entries with Drive specific attributes.
*
* @type {Array<TestEntryInfo>}
* @const
*/
var BASIC_DRIVE_ENTRY_SET = [
ENTRIES.hello,
ENTRIES.world,
ENTRIES.desktop,
ENTRIES.beautiful,
ENTRIES.photos,
ENTRIES.unsupported,
ENTRIES.testDocument,
ENTRIES.testSharedDocument
];
var INTERVAL_FOR_WAIT_UNTIL = 100; // ms
var INTERVAL_FOR_WAIT_LOGGING = 10000; // 10s
/**
* Waits until testFunction becomes true.
* @param {function(): Object} testFunction A function which is tested.
* @return {!Promise} A promise which is fullfilled when the testFunction
* becomes true.
*/
function waitUntil(testFunction) {
return new Promise(function(resolve) {
var tryTestFunction = function() {
var result = testFunction();
if (result) {
resolve(result);
} else {
setTimeout(tryTestFunction, INTERVAL_FOR_WAIT_UNTIL);
}
};
tryTestFunction();
});
}
/**
* Waits until specified element exists.
*/
function waitForElement(selectors) {
return waitUntil(() => {
return document.querySelector(selectors);
});
}
/**
* Adds specified TestEntryInfos to downloads and drive.
*
* @param {!Array<TestEntryInfo} downloads Entries for downloads.
* @param {!Array<TestEntryInfo} drive Entries for drive.
*/
function addEntries(downloads, drive) {
var fsDownloads =
mockVolumeManager
.getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DOWNLOADS)
.fileSystem;
fsDownloads.populate(
TestEntryInfo.getMockFileSystemPopulateRows(downloads, '/'), true);
var fsDrive =
mockVolumeManager
.getCurrentProfileVolumeInfo(VolumeManagerCommon.VolumeType.DRIVE)
.fileSystem;
fsDrive.populate(
TestEntryInfo.getMockFileSystemPopulateRows(drive, '/root/'), true);
// Send onDirectoryChanged events.
chrome.fileManagerPrivate.dispatchEvent_(
'onDirectoryChanged', {eventType: 'changed', entry: fsDownloads.root});
chrome.fileManagerPrivate.dispatchEvent_(
'onDirectoryChanged',
{eventType: 'changed', entry: fsDrive.entries['/root']});
}
/**
* Waits for the file list turns to the given contents.
* @param {Array<Array<string>>} expected Expected contents of file list.
* @param {{orderCheck:boolean=, ignoreName:boolean=, ignoreSize:boolean=,
* ignoreType:boolean=,ignoreDate:boolean=}=} opt_options
* Options of the comparison. If orderCheck is true, it also compares the
* order of files. If ignore[Name|Size|Type|Date] is true, it compares
* the file without considering that field.
* @return {Promise} Promise to be fulfilled when the file list turns to the
* given contents.
*/
function waitForFiles(expected, opt_options) {
var options = opt_options || {};
var nextLog = Date.now() + INTERVAL_FOR_WAIT_LOGGING;
return waitUntil(function() {
var files = test.util.sync.getFileList(window);
if (Date.now() > nextLog) {
console.debug('waitForFiles', expected, files);
nextLog = Date.now() + INTERVAL_FOR_WAIT_LOGGING;
}
if (!options.orderCheck) {
files.sort();
expected.sort();
}
if (files.length != expected.length)
return false;
for (var i = 0; i < files.length; i++) {
// Each row is [name, size, type, date].
if ((!options.ignoreName && files[i][0] != expected[i][0]) ||
(!options.ignoreSize && files[i][1] != expected[i][1]) ||
(!options.ignoreType && files[i][2] != expected[i][2]) ||
(!options.ignoreDate && files[i][3] != expected[i][3]))
return false;
}
return true;
});
}
/**
* Opens a Files app's main window and waits until it is initialized. Fills
* the window with initial files. Should be called for the first window only.
*
* @return {Promise} Promise to be fulfilled with the result object, which
* contains the file list.
*/
function setupAndWaitUntilReady() {
return loadData()
.then(result => {
addEntries(BASIC_LOCAL_ENTRY_SET, BASIC_DRIVE_ENTRY_SET);
return waitForElement('#directory-tree [volume-type-icon="downloads"]');
})
.then(() => {
return test.util.sync.fakeMouseClick(
window, '#directory-tree [volume-type-icon="downloads"]');
})
.then(result => {
assertTrue(result);
return waitForFiles(
TestEntryInfo.getExpectedRows(BASIC_LOCAL_ENTRY_SET));
});
}
// Shortcut for endTests with success.
function doneTests(opt_failed) {
endTests(!opt_failed);
}
...@@ -11,11 +11,22 @@ as a regular webapp. ...@@ -11,11 +11,22 @@ as a regular webapp.
""" """
import argparse
import os import os
import sys import sys
assert __name__ == '__main__' assert __name__ == '__main__'
# If --output is provided, create specified empty file.
parser = argparse.ArgumentParser()
parser.add_argument('--output')
args = parser.parse_args()
if args.output:
with open(args.output, 'w') as output:
output.write('')
root = os.path.abspath(os.path.join(sys.path[0], '../..')) root = os.path.abspath(os.path.join(sys.path[0], '../..'))
scripts = [] scripts = []
GENERATED_HTML = ('<!-- Generated by:\n -- ui/file_manager/file_manager/' GENERATED_HTML = ('<!-- Generated by:\n -- ui/file_manager/file_manager/'
...@@ -25,14 +36,16 @@ GENERATED_JS = ('// Generated by:\n// ui/file_manager/file_manager/' ...@@ -25,14 +36,16 @@ GENERATED_JS = ('// Generated by:\n// ui/file_manager/file_manager/'
def read(path): def read(path):
return open(os.path.join(root, path)).read() with open(os.path.join(root, path)) as f:
return f.read()
def write(path, content): def write(path, content):
fullpath = os.path.join(root, path) fullpath = os.path.join(root, path)
if not os.path.exists(os.path.dirname(fullpath)): if not os.path.exists(os.path.dirname(fullpath)):
os.makedirs(os.path.dirname(fullpath)) os.makedirs(os.path.dirname(fullpath))
open(fullpath, 'w').write(content) with open(fullpath, 'w') as f:
f.write(content)
def insertbeforeline(f, match, lines): def insertbeforeline(f, match, lines):
...@@ -118,24 +131,26 @@ main_html = replaceline( ...@@ -118,24 +131,26 @@ main_html = replaceline(
]) ])
# Add scripts for testing. # Add scripts for testing.
scripts += [ scripts += ['<script src="%s"></script>' % s for s in (
'<script src="js/chrome_api_test_impl.js"></script>', 'js/chrome_api_test_impl.js',
'<script src="../../../webui/resources/js/assert.js"></script>', '../../../webui/resources/js/assert.js',
'<script src="../../../webui/resources/js/cr.js"></script>', '../../../webui/resources/js/cr.js',
'<script src="../../../webui/resources/js/cr/event_target.js"></script>', '../../../webui/resources/js/cr/event_target.js',
('<script src="../../../webui/resources/js/cr/ui/array_data_model.js">' '../../../webui/resources/js/cr/ui/array_data_model.js">',
'</script>'), '../../../webui/resources/js/load_time_data.js',
'<script src="../../../webui/resources/js/load_time_data.js"></script>', '../../../webui/resources/js/webui_resource_test.js">',
'<script src="js/strings.js"></script>', 'js/strings.js',
'<script src="../common/js/util.js"></script>', '../common/js/util.js',
'<script src="../common/js/mock_entry.js"></script>', '../common/js/mock_entry.js',
'<script src="../common/js/volume_manager_common.js"></script>', '../common/js/volume_manager_common.js',
'<script src="../background/js/volume_info_impl.js"></script>', '../background/js/volume_info_impl.js',
'<script src="../background/js/volume_info_list_impl.js"></script>', '../background/js/volume_info_list_impl.js',
'<script src="../background/js/volume_manager_impl.js"></script>', '../background/js/volume_manager_impl.js',
'<script src="../background/js/mock_volume_manager.js"></script>', '../background/js/mock_volume_manager.js',
'<script src="js/chrome_file_manager.js"></script>', 'js/chrome_file_manager.js',
] 'js/test_util.js',
'delete.js',
)]
# Convert all includes from: # Convert all includes from:
# * foreground/js/main_scripts.js # * foreground/js/main_scripts.js
...@@ -158,5 +173,3 @@ main_html = replaceline(main_html, 'foreground/js/ui/banners.js', ...@@ -158,5 +173,3 @@ main_html = replaceline(main_html, 'foreground/js/ui/banners.js',
['<script src="js/ui/banners.js"></script>']) ['<script src="js/ui/banners.js"></script>'])
write('test/main.html', GENERATED_HTML + '\n'.join(main_html)) write('test/main.html', GENERATED_HTML + '\n'.join(main_html))
print 'done'
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment