Bug 1094312: Fix browser_bug553455.js:test_cancel_restart by pausing the download for long enough for the progress notification to show reliably. r=Gijs

test_cancel_restart needs the progress notification to show reliably so it can
cancel the pending install. To ensure this a sjs script is used to
asynchronously deliever the XPI data. It starts responding but sends no data
until a second request is made to tell it to complete. So the test can start
the install, then do what it likes with the progress dialog before finally
telling the server to complete the download for the install.

--HG--
extra : rebase_source : 9bd5c617a28ee4edaa8e18599ad8eca0b52f7133
This commit is contained in:
Dave Townsend 2014-12-26 14:06:43 -08:00
parent dd39072355
commit da3564ca03
3 changed files with 155 additions and 34 deletions

View File

@ -670,7 +670,12 @@ function test_renotify_installed() {
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
},
/*function test_cancel_restart() {
function test_cancel_restart() {
function complete_install(callback) {
let url = TESTROOT + "slowinstall.sjs?continue=true"
NetUtil.asyncFetch(url, callback || (() => {}));
}
// Wait for the progress notification
wait_for_notification(PROGRESS_NOTIFICATION, function(aPanel) {
let notification = aPanel.childNodes[0];
@ -687,55 +692,69 @@ function test_renotify_installed() {
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
let button = document.getAnonymousElementByAttribute(notification, "anonid", "cancel");
// Cancel the download
EventUtils.synthesizeMouse(button, 2, 2, {});
// Wait for the install to fully cancel
let install = notification.notification.options.installs[0];
install.addListener({
onDownloadCancelled: function() {
install.removeListener(this);
// Notification should have changed to cancelled
notification = aPanel.childNodes[0];
is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
executeSoon(function() {
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
isnot(notification, aPanel.childNodes[0], "Should have reconstructed the notification UI");
notification = aPanel.childNodes[0];
is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
wait_for_notification("addon-install-complete-notification", function(aPanel) {
let notification = aPanel.childNodes[0];
is(notification.button.label, "Restart Now", "Should have seen the right button");
is(notification.getAttribute("label"),
"XPI Test will be installed after you restart " + gApp + ".",
"Should have seen the right message");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
wait_for_notification("addon-install-complete-notification", function(aPanel) {
let notification = aPanel.childNodes[0];
is(notification.button.label, "Restart Now", "Should have seen the right button");
is(notification.getAttribute("label"),
"XPI Test will be installed after you restart " + gApp + ".",
"Should have seen the right message");
AddonManager.getAllInstalls(function(aInstalls) {
is(aInstalls.length, 1, "Should be one pending install");
aInstalls[0].cancel();
AddonManager.getAllInstalls(function(aInstalls) {
is(aInstalls.length, 1, "Should be one pending install");
aInstalls[0].cancel();
Services.perms.remove("example.com", "install");
wait_for_notification_close(runNextTest);
gBrowser.removeTab(gBrowser.selectedTab);
Services.perms.remove("example.com", "install");
wait_for_notification_close(runNextTest);
gBrowser.removeTab(gBrowser.selectedTab);
});
});
aWindow.document.documentElement.acceptDialog();
});
// Restart the download
EventUtils.synthesizeMouseAtCenter(notification.button, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
complete_install();
});
});
aWindow.document.documentElement.acceptDialog();
}
});
// Restart the download
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
// Cancel the download
EventUtils.synthesizeMouseAtCenter(button, {});
});
var pm = Services.perms;
pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
var triggers = encodeURIComponent(JSON.stringify({
"XPI": "unsigned.xpi"
"XPI": "slowinstall.sjs?file=unsigned.xpi"
}));
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
},*/
},
function test_failed_security() {
Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false);

View File

@ -24,6 +24,7 @@ support-files =
signed-untrusted.xpi
signed.xpi
signed2.xpi
slowinstall.sjs
startsoftwareupdate.html
theme.xpi
triggerredirect.html

View File

@ -0,0 +1,101 @@
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
const RELATIVE_PATH = "browser/toolkit/mozapps/extensions/test/xpinstall"
const NOTIFICATION_TOPIC = "slowinstall-complete";
/**
* Helper function to create a JS object representing the url parameters from
* the request's queryString.
*
* @param aQueryString
* The request's query string.
* @return A JS object representing the url parameters from the request's
* queryString.
*/
function parseQueryString(aQueryString) {
var paramArray = aQueryString.split("&");
var regex = /^([^=]+)=(.*)$/;
var params = {};
for (var i = 0, sz = paramArray.length; i < sz; i++) {
var match = regex.exec(paramArray[i]);
if (!match)
throw "Bad parameter in queryString! '" + paramArray[i] + "'";
params[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
}
return params;
}
function handleRequest(aRequest, aResponse) {
let id = +getState("ID");
setState("ID", "" + (id + 1));
function LOG(str) {
dump("slowinstall.sjs[" + id + "]: " + str + "\n");
}
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
var params = { };
if (aRequest.queryString)
params = parseQueryString(aRequest.queryString);
if (params.file) {
let xpiFile = "";
function complete_download() {
LOG("Completing download");
downloadPaused = false;
try {
// Doesn't seem to be a sane way to read using OS.File and write to an
// nsIOutputStream so here we are.
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(xpiFile);
let stream = Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(Ci.nsIFileInputStream);
stream.init(file, -1, -1, stream.DEFER_OPEN + stream.CLOSE_ON_EOF);
NetUtil.asyncCopy(stream, aResponse.bodyOutputStream, () => {
LOG("Download complete");
aResponse.finish();
});
}
catch (e) {
LOG("Exception " + e);
}
}
let waitForComplete = new Promise(resolve => {
function complete() {
Services.obs.removeObserver(complete, NOTIFICATION_TOPIC);
resolve();
}
Services.obs.addObserver(complete, NOTIFICATION_TOPIC, false);
});
aResponse.processAsync();
OS.File.getCurrentDirectory().then(dir => {
xpiFile = OS.Path.join(dir, ...RELATIVE_PATH.split("/"), params.file);
LOG("Starting slow download of " + xpiFile);
OS.File.stat(xpiFile).then(info => {
aResponse.setHeader("Content-Type", "binary/octet-stream");
aResponse.setHeader("Content-Length", info.size.toString());
LOG("Download paused");
waitForComplete.then(complete_download);
});
});
}
else if (params.continue) {
dump("slowinstall.sjs: Received signal to complete all current downloads.\n");
Services.obs.notifyObservers(null, NOTIFICATION_TOPIC, null);
}
}