зеркало из https://github.com/mozilla/gecko-dev.git
Bug 847863 - Part 7 of 8 - Convert Downloads Panel tests. r=enn
This commit is contained in:
Родитель
ebe4488a9b
Коммит
fb3d5df5a2
|
@ -7,39 +7,33 @@
|
|||
* Make sure the downloads panel can display items in the right order and
|
||||
* contains the expected data.
|
||||
*/
|
||||
function gen_test()
|
||||
function test_task()
|
||||
{
|
||||
// Display one of each download state.
|
||||
const DownloadData = [
|
||||
{ endTime: 1180493839859239, state: nsIDM.DOWNLOAD_NOTSTARTED },
|
||||
{ endTime: 1180493839859238, state: nsIDM.DOWNLOAD_DOWNLOADING },
|
||||
{ endTime: 1180493839859237, state: nsIDM.DOWNLOAD_PAUSED },
|
||||
{ endTime: 1180493839859236, state: nsIDM.DOWNLOAD_SCANNING },
|
||||
{ endTime: 1180493839859235, state: nsIDM.DOWNLOAD_QUEUED },
|
||||
{ endTime: 1180493839859234, state: nsIDM.DOWNLOAD_FINISHED },
|
||||
{ endTime: 1180493839859233, state: nsIDM.DOWNLOAD_FAILED },
|
||||
{ endTime: 1180493839859232, state: nsIDM.DOWNLOAD_CANCELED },
|
||||
{ endTime: 1180493839859231, state: nsIDM.DOWNLOAD_BLOCKED_PARENTAL },
|
||||
{ endTime: 1180493839859230, state: nsIDM.DOWNLOAD_DIRTY },
|
||||
{ endTime: 1180493839859229, state: nsIDM.DOWNLOAD_BLOCKED_POLICY },
|
||||
{ state: nsIDM.DOWNLOAD_NOTSTARTED },
|
||||
{ state: nsIDM.DOWNLOAD_PAUSED },
|
||||
{ state: nsIDM.DOWNLOAD_FINISHED },
|
||||
{ state: nsIDM.DOWNLOAD_FAILED },
|
||||
{ state: nsIDM.DOWNLOAD_CANCELED },
|
||||
];
|
||||
|
||||
// For testing purposes, show all the download items at once.
|
||||
var originalCountLimit = DownloadsView.kItemCountLimit;
|
||||
DownloadsView.kItemCountLimit = DownloadData.length;
|
||||
registerCleanupFunction(function () {
|
||||
DownloadsView.kItemCountLimit = originalCountLimit;
|
||||
});
|
||||
|
||||
try {
|
||||
// Ensure that state is reset in case previous tests didn't finish.
|
||||
for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
|
||||
yield task_resetState();
|
||||
|
||||
// For testing purposes, show all the download items at once.
|
||||
var originalCountLimit = DownloadsView.kItemCountLimit;
|
||||
DownloadsView.kItemCountLimit = DownloadData.length;
|
||||
registerCleanupFunction(function () {
|
||||
DownloadsView.kItemCountLimit = originalCountLimit;
|
||||
});
|
||||
|
||||
// Populate the downloads database with the data required by this test.
|
||||
for (let yy in gen_addDownloadRows(DownloadData)) yield undefined;
|
||||
yield task_addDownloads(DownloadData);
|
||||
|
||||
// Open the user interface and wait for data to be fully loaded.
|
||||
for (let yy in gen_openPanel(DownloadsCommon.getData(window))) yield undefined;
|
||||
yield task_openPanel();
|
||||
|
||||
// Test item data and count. This also tests the ordering of the display.
|
||||
let richlistbox = document.getElementById("downloadsListBox");
|
||||
|
@ -47,16 +41,14 @@ function gen_test()
|
|||
is(richlistbox.children.length, DownloadData.length,
|
||||
"There is the correct number of richlistitems");
|
||||
*/
|
||||
for (let i = 0; i < richlistbox.children.length; i++) {
|
||||
let element = richlistbox.children[i];
|
||||
let itemCount = richlistbox.children.length;
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
let element = richlistbox.children[itemCount - i - 1];
|
||||
let dataItem = new DownloadsViewItemController(element).dataItem;
|
||||
is(dataItem.target, DownloadData[i].name, "Download names match up");
|
||||
is(dataItem.state, DownloadData[i].state, "Download states match up");
|
||||
is(dataItem.file, DownloadData[i].target, "Download targets match up");
|
||||
is(dataItem.uri, DownloadData[i].source, "Download sources match up");
|
||||
}
|
||||
} finally {
|
||||
// Clean up when the test finishes.
|
||||
for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
|
||||
yield task_resetState();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
* download it notices. All subsequent downloads, even across sessions, should
|
||||
* not open the panel automatically.
|
||||
*/
|
||||
function gen_test()
|
||||
function test_task()
|
||||
{
|
||||
try {
|
||||
// Ensure that state is reset in case previous tests didn't finish.
|
||||
for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
|
||||
yield task_resetState();
|
||||
|
||||
// With this set to false, we should automatically open the panel
|
||||
// the first time a download is started.
|
||||
// With this set to false, we should automatically open the panel the first
|
||||
// time a download is started.
|
||||
DownloadsCommon.getData(window).panelHasShownBefore = false;
|
||||
|
||||
prepareForPanelOpen();
|
||||
let promise = promisePanelOpened();
|
||||
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
|
||||
yield undefined;
|
||||
yield promise;
|
||||
|
||||
// If we got here, that means the panel opened.
|
||||
DownloadsPanel.hidePanel();
|
||||
|
@ -28,29 +28,26 @@ function gen_test()
|
|||
ok(DownloadsCommon.getData(window).panelHasShownBefore,
|
||||
"Should have recorded that the panel was opened on a download.")
|
||||
|
||||
// Next, make sure that if we start another download, we don't open
|
||||
// the panel automatically.
|
||||
panelShouldNotOpen();
|
||||
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
|
||||
yield waitFor(2);
|
||||
} catch(e) {
|
||||
ok(false, e);
|
||||
// Next, make sure that if we start another download, we don't open the
|
||||
// panel automatically.
|
||||
let originalOnPopupShown = DownloadsPanel.onPopupShown;
|
||||
DownloadsPanel.onPopupShown = function () {
|
||||
originalOnPopupShown.apply(this, arguments);
|
||||
ok(false, "Should not have opened the downloads panel.");
|
||||
};
|
||||
|
||||
try {
|
||||
DownloadsCommon.getData(window)._notifyDownloadEvent("start");
|
||||
|
||||
// Wait 2 seconds to ensure that the panel does not open.
|
||||
let deferTimeout = Promise.defer();
|
||||
setTimeout(deferTimeout.resolve, 2000);
|
||||
yield deferTimeout.promise;
|
||||
} finally {
|
||||
DownloadsPanel.onPopupShown = originalOnPopupShown;
|
||||
}
|
||||
} finally {
|
||||
// Clean up when the test finishes.
|
||||
for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined;
|
||||
yield task_resetState();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to record a test failure for the next time the downloads panel
|
||||
* opens.
|
||||
*/
|
||||
function panelShouldNotOpen()
|
||||
{
|
||||
// Hook to wait until the test data has been loaded.
|
||||
let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
|
||||
DownloadsPanel.onViewLoadCompleted = function () {
|
||||
DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted;
|
||||
ok(false, "Should not have opened the downloads panel.");
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,10 +10,16 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Globals
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
|
||||
"resource:///modules/DownloadsCommon.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
||||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
const nsIDM = Ci.nsIDownloadManager;
|
||||
|
||||
let gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]);
|
||||
|
@ -22,253 +28,85 @@ registerCleanupFunction(function () {
|
|||
gTestTargetFile.remove(false);
|
||||
});
|
||||
|
||||
/**
|
||||
* This objects contains a property for each column in the downloads table.
|
||||
*/
|
||||
let gDownloadRowTemplate = {
|
||||
name: "test-download.txt",
|
||||
source: "http://www.example.com/test-download.txt",
|
||||
target: NetUtil.newURI(gTestTargetFile).spec,
|
||||
startTime: 1180493839859230,
|
||||
endTime: 1180493839859234,
|
||||
state: nsIDM.DOWNLOAD_FINISHED,
|
||||
currBytes: 0,
|
||||
maxBytes: -1,
|
||||
preferredAction: 0,
|
||||
autoResume: 0
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Infrastructure
|
||||
|
||||
// All test are run through the test runner.
|
||||
function test()
|
||||
{
|
||||
testRunner.runTest(this.gen_test);
|
||||
waitForExplicitFinish();
|
||||
Task.spawn(test_task).then(null, ex => ok(false, ex)).then(finish);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a browser-chrome test defined through a generator function.
|
||||
*
|
||||
* This object is a singleton, initialized automatically when this script is
|
||||
* included. Every browser-chrome test file includes a new copy of this object.
|
||||
*/
|
||||
var testRunner = {
|
||||
_testIterator: null,
|
||||
_lastEventResult: undefined,
|
||||
_testRunning: false,
|
||||
_eventRaised: false,
|
||||
|
||||
// --- Main test runner ---
|
||||
|
||||
/**
|
||||
* Runs the test described by the provided generator function asynchronously.
|
||||
*
|
||||
* Calling yield in the generator will cause it to wait until continueTest is
|
||||
* called. The parameter provided to continueTest will be the return value of
|
||||
* the yield operator.
|
||||
*
|
||||
* @param aGenerator
|
||||
* Test generator function. The function will be called with no
|
||||
* arguments to retrieve its iterator.
|
||||
*/
|
||||
runTest: function TR_runTest(aGenerator) {
|
||||
waitForExplicitFinish();
|
||||
testRunner._testIterator = aGenerator();
|
||||
testRunner.continueTest();
|
||||
},
|
||||
|
||||
/**
|
||||
* Continues the currently running test.
|
||||
*
|
||||
* @param aEventResult
|
||||
* This will be the return value of the yield operator in the test.
|
||||
*/
|
||||
continueTest: function TR_continueTest(aEventResult) {
|
||||
// Store the last event result, or set it to undefined.
|
||||
testRunner._lastEventResult = aEventResult;
|
||||
|
||||
// Never reenter the main loop, but notify that the event has been raised.
|
||||
if (testRunner._testRunning) {
|
||||
testRunner._eventRaised = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Enter the main iteration loop.
|
||||
testRunner._testRunning = true;
|
||||
try {
|
||||
do {
|
||||
// Call the iterator, but don't leave the loop if the expected event is
|
||||
// raised during the execution of the generator.
|
||||
testRunner._eventRaised = false;
|
||||
testRunner._testIterator.send(testRunner._lastEventResult);
|
||||
} while (testRunner._eventRaised);
|
||||
}
|
||||
catch (e) {
|
||||
// This block catches exceptions raised by the generator, including the
|
||||
// normal StopIteration exception. Unexpected exceptions are reported as
|
||||
// test failures.
|
||||
if (!(e instanceof StopIteration))
|
||||
ok(false, e);
|
||||
// In any case, stop the tests in this file.
|
||||
finish();
|
||||
}
|
||||
|
||||
// Wait for the next event or finish.
|
||||
testRunner._testRunning = false;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Asynchronous generator-based support subroutines
|
||||
//// Asynchronous support subroutines
|
||||
|
||||
//
|
||||
// The following functions are all generators that can be used inside the main
|
||||
// test generator to perform specific tasks asynchronously. To invoke these
|
||||
// subroutines correctly, an iteration syntax should be used:
|
||||
//
|
||||
// for (let yy in gen_example("Parameter")) yield undefined;
|
||||
//
|
||||
|
||||
function gen_resetState(aData)
|
||||
function promiseFocus()
|
||||
{
|
||||
let statement = Services.downloads.DBConnection.createAsyncStatement(
|
||||
"DELETE FROM moz_downloads");
|
||||
try {
|
||||
statement.executeAsync({
|
||||
handleResult: function(aResultSet) { },
|
||||
handleError: function(aError)
|
||||
{
|
||||
Cu.reportError(aError);
|
||||
},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
testRunner.continueTest();
|
||||
}
|
||||
});
|
||||
yield undefined;
|
||||
} finally {
|
||||
statement.finalize();
|
||||
let deferred = Promise.defer();
|
||||
waitForFocus(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function promisePanelOpened()
|
||||
{
|
||||
let deferred = Promise.defer();
|
||||
|
||||
// Hook to wait until the panel is shown.
|
||||
let originalOnPopupShown = DownloadsPanel.onPopupShown;
|
||||
DownloadsPanel.onPopupShown = function () {
|
||||
DownloadsPanel.onPopupShown = originalOnPopupShown;
|
||||
originalOnPopupShown.apply(this, arguments);
|
||||
|
||||
// Defer to the next tick of the event loop so that we don't continue
|
||||
// processing during the DOM event handler itself.
|
||||
setTimeout(deferred.resolve, 0);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function task_resetState()
|
||||
{
|
||||
// Remove all downloads.
|
||||
let publicList = yield Downloads.getPublicDownloadList();
|
||||
let downloads = yield publicList.getAll();
|
||||
for (let download of downloads) {
|
||||
publicList.remove(download);
|
||||
yield download.finalize(true);
|
||||
}
|
||||
|
||||
// Reset any prefs that might have been changed.
|
||||
Services.prefs.clearUserPref("browser.download.panel.shown");
|
||||
|
||||
// Ensure that the panel is closed and data is unloaded.
|
||||
aData.clear();
|
||||
aData._loadState = aData.kLoadNone;
|
||||
DownloadsPanel.hidePanel();
|
||||
|
||||
// Wait for focus on the main window.
|
||||
waitForFocus(testRunner.continueTest);
|
||||
yield undefined;
|
||||
yield promiseFocus();
|
||||
}
|
||||
|
||||
function gen_addDownloadRows(aDataRows)
|
||||
function task_addDownloads(aItems)
|
||||
{
|
||||
let columnNames = Object.keys(gDownloadRowTemplate).join(", ");
|
||||
let parameterNames = Object.keys(gDownloadRowTemplate)
|
||||
.map(function(n) ":" + n)
|
||||
.join(", ");
|
||||
let statement = Services.downloads.DBConnection.createAsyncStatement(
|
||||
"INSERT INTO moz_downloads (" + columnNames +
|
||||
", guid) VALUES(" + parameterNames + ", GENERATE_GUID())");
|
||||
try {
|
||||
// Execute the statement for each of the provided downloads in reverse.
|
||||
for (let i = aDataRows.length - 1; i >= 0; i--) {
|
||||
let dataRow = aDataRows[i];
|
||||
let startTimeMs = Date.now();
|
||||
|
||||
// Populate insert parameters from the provided data.
|
||||
for (let columnName in gDownloadRowTemplate) {
|
||||
if (!(columnName in dataRow)) {
|
||||
// Update the provided row object with data from the global template,
|
||||
// for columns whose value is not provided explicitly.
|
||||
dataRow[columnName] = gDownloadRowTemplate[columnName];
|
||||
}
|
||||
statement.params[columnName] = dataRow[columnName];
|
||||
}
|
||||
|
||||
// Run the statement asynchronously and wait.
|
||||
statement.executeAsync({
|
||||
handleResult: function(aResultSet) { },
|
||||
handleError: function(aError)
|
||||
{
|
||||
Cu.reportError(aError.message + " (Result = " + aError.result + ")");
|
||||
},
|
||||
handleCompletion: function(aReason)
|
||||
{
|
||||
testRunner.continueTest();
|
||||
}
|
||||
});
|
||||
yield undefined;
|
||||
|
||||
// At each iteration, ensure that the start and end time in the global
|
||||
// template is distinct, as these column are used to sort each download
|
||||
// in its category.
|
||||
gDownloadRowTemplate.startTime++;
|
||||
gDownloadRowTemplate.endTime++;
|
||||
}
|
||||
} finally {
|
||||
statement.finalize();
|
||||
let publicList = yield Downloads.getPublicDownloadList();
|
||||
for (let item of aItems) {
|
||||
publicList.add(yield Downloads.createDownload({
|
||||
source: "http://www.example.com/test-download.txt",
|
||||
target: gTestTargetFile,
|
||||
succeeded: item.state == nsIDM.DOWNLOAD_FINISHED,
|
||||
canceled: item.state == nsIDM.DOWNLOAD_CANCELED ||
|
||||
item.state == nsIDM.DOWNLOAD_PAUSED,
|
||||
error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null,
|
||||
hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED,
|
||||
startTime: new Date(startTimeMs++),
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function gen_openPanel(aData)
|
||||
function task_openPanel()
|
||||
{
|
||||
// Hook to wait until the test data has been loaded.
|
||||
let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted;
|
||||
DownloadsPanel.onViewLoadCompleted = function () {
|
||||
DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted;
|
||||
originalOnViewLoadCompleted.apply(this);
|
||||
testRunner.continueTest();
|
||||
};
|
||||
yield promiseFocus();
|
||||
|
||||
// Start loading all the downloads from the database asynchronously.
|
||||
aData.ensurePersistentDataLoaded(false);
|
||||
|
||||
// Wait for focus on the main window.
|
||||
waitForFocus(testRunner.continueTest);
|
||||
yield undefined;
|
||||
|
||||
// Open the downloads panel, waiting until loading is completed.
|
||||
let promise = promisePanelOpened();
|
||||
DownloadsPanel.showPanel();
|
||||
yield undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spin the event loop for aSeconds seconds, and then signal the test to
|
||||
* continue.
|
||||
*
|
||||
* @param aSeconds the number of seconds to wait.
|
||||
* @note This helper should _only_ be used when there's no valid event to
|
||||
* listen to and one can't be made.
|
||||
*/
|
||||
function waitFor(aSeconds)
|
||||
{
|
||||
setTimeout(function() {
|
||||
testRunner.continueTest();
|
||||
}, aSeconds * 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make it so that the next time the downloads panel opens, we signal to
|
||||
* continue the test. This function needs to be called each time you want
|
||||
* to wait for the panel to open.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* prepareForPanelOpen();
|
||||
* // Do something to open the panel
|
||||
* yield undefined;
|
||||
* // We can assume the panel is open now.
|
||||
*/
|
||||
function prepareForPanelOpen()
|
||||
{
|
||||
// Hook to wait until the test data has been loaded.
|
||||
let originalOnPopupShown = DownloadsPanel.onPopupShown;
|
||||
DownloadsPanel.onPopupShown = function (aEvent) {
|
||||
DownloadsPanel.onPopupShown = originalOnPopupShown;
|
||||
DownloadsPanel.onPopupShown.apply(this, [aEvent]);
|
||||
testRunner.continueTest();
|
||||
};
|
||||
yield promise;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче