Bug 1000315 - Part 7: App tests automatically confirm uninstallation. r=myk
authorTed Clancy (:tedders1) <tclancy@mozilla.com>
Wed, 11 Jun 2014 14:33:02 -0700
changeset 223015 cb0704cad10289feb423bc5a91c01936af63c5e4
parent 223014 28284ab9811bb3633caebf1970ff70e9953293e8
child 223016 dd7d21806888b0aff1646e7ff6ac55e6ee8040ad
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmyk
bugs1000315
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1000315 - Part 7: App tests automatically confirm uninstallation. r=myk
dom/apps/tests/test_app_update.html
dom/apps/tests/test_bug_795164.html
dom/apps/tests/test_bug_945152.html
dom/apps/tests/test_install_multiple_apps_origin.html
dom/apps/tests/test_install_receipts.html
dom/apps/tests/test_marketplace_pkg_install.html
dom/apps/tests/test_packaged_app_asmjs.html
dom/apps/tests/test_packaged_app_install.html
dom/apps/tests/test_receipt_operations.html
dom/apps/tests/test_signed_pkg_install.html
dom/apps/tests/test_uninstall_errors.html
dom/apps/tests/test_widget.html
dom/tests/mochitest/webapps/cross_origin.html
dom/tests/mochitest/webapps/head.js
dom/tests/mochitest/webapps/test_bug_765063.xul
dom/tests/mochitest/webapps/test_cross_origin.xul
dom/tests/mochitest/webapps/test_getNotInstalled.xul
dom/tests/mochitest/webapps/test_install_app.xul
dom/tests/mochitest/webapps/test_install_errors.xul
dom/tests/mochitest/webapps/test_install_utf8.xul
dom/tests/mochitest/webapps/test_launch_paths.xul
toolkit/webapps/tests/head.js
toolkit/webapps/tests/test_custom_origin.xul
toolkit/webapps/tests/test_custom_origin_uninstall_install.xul
toolkit/webapps/tests/test_hosted_checkforupdates_from_webapp_runtime.xul
toolkit/webapps/tests/test_install_appcache.xul
toolkit/webapps/tests/test_packaged_checkforupdates_from_webapp_runtime.xul
--- a/dom/apps/tests/test_app_update.html
+++ b/dom/apps/tests/test_app_update.html
@@ -67,16 +67,18 @@ https://bugzilla.mozilla.org/show_bug.cg
     };
     request.onsuccess = mozAppsError;
     yield undefined;
 
     setAppVersion(1, continueTest);
     yield undefined;
     SpecialPowers.autoConfirmAppInstall(continueTest);
     yield undefined;
+    SpecialPowers.autoConfirmAppUninstall(continueTest);
+    yield undefined;
 
     // Load the app, uninstalled.
     checkAppState(null, false, 1, continueTest);
     yield undefined;
 
     // Bump the version and install the app.
     setAppVersion(2, continueTest);
     yield undefined;
--- a/dom/apps/tests/test_bug_795164.html
+++ b/dom/apps/tests/test_bug_795164.html
@@ -39,16 +39,19 @@ https://bugzilla.mozilla.org/show_bug.cg
   }
 
   function runTest() {
     // Set up.
     SpecialPowers.setAllAppsLaunchable(true);
     SpecialPowers.autoConfirmAppInstall(continueTest);
     yield undefined;
 
+    SpecialPowers.autoConfirmAppUninstall(continueTest);
+    yield undefined;
+
     // Keeping track of the number of times `mozApps.mgmt.onuninstall` gets triggered
     let uninstallCount = 0;
 
     navigator.mozApps.mgmt.onuninstall = function() {
       uninstallCount++;
     };
 
     let request = navigator.mozApps.install(url1);
--- a/dom/apps/tests/test_bug_945152.html
+++ b/dom/apps/tests/test_bug_945152.html
@@ -66,16 +66,19 @@ https://bugzilla.mozilla.org/show_bug.cg
         ["dom.mapped_arraybuffer.enabled", true]
       ]
     }, continueTest);
     yield undefined;
 
     SpecialPowers.autoConfirmAppInstall(continueTest);
     yield undefined;
 
+    SpecialPowers.autoConfirmAppUninstall(continueTest);
+    yield undefined;
+
     // Create app on server side.
     createApp(continueTest);
     yield undefined;
 
     // Install app.
     var app;
     navigator.mozApps.mgmt.oninstall = function(e) {
       ok(true, "Got oninstall event");
--- a/dom/apps/tests/test_install_multiple_apps_origin.html
+++ b/dom/apps/tests/test_install_multiple_apps_origin.html
@@ -55,16 +55,19 @@ function runTest() {
   SpecialPowers.setAllAppsLaunchable(true);
 
   var manifestURL1 = gManifestURL + "&app=1";
   var manifestURL2 = gManifestURL + "&app=2";
 
   SpecialPowers.autoConfirmAppInstall(continueTest);
   yield undefined;
 
+  SpecialPowers.autoConfirmAppUninstall(continueTest);
+  yield undefined;
+
   request = navigator.mozApps.mgmt.getAll();
   request.onerror = cbError;
   request.onsuccess = continueTest;
   yield undefined;
   var initialAppsCount = request.result.length;
   info("Starting with " + initialAppsCount + " apps installed.");
 
   var request = navigator.mozApps.install(manifestURL1, { });
--- a/dom/apps/tests/test_install_receipts.html
+++ b/dom/apps/tests/test_install_receipts.html
@@ -52,16 +52,19 @@ function cbError(aError) {
 SimpleTest.waitForExplicitFinish();
 
 function runTest() {
   SpecialPowers.setAllAppsLaunchable(true);
 
   SpecialPowers.autoConfirmAppInstall(continueTest);
   yield undefined;
 
+  SpecialPowers.autoConfirmAppUninstall(continueTest);
+  yield undefined;
+
   // Test install with three valid receipts
   let valid_receipt1 = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJwcm9kdWN0IjogeyJ1cmwiOiAiaHR0cHM6Ly93d3cubW96aWxsYS5vcmciLCAic3RvcmVkYXRhIjogIjUxNjkzMTQzNTYifSwgInJlaXNzdWUiOiAiaHR0cDovL21vY2hpLnRlc3Q6ODg4OC9yZWlzc3VlLzUxNjkzMTQzNTYiLCAidXNlciI6IHsidHlwZSI6ICJkaXJlY3RlZC1pZGVudGlmaWVyIiwgInZhbHVlIjogIjRmYjM1MTUxLTJiOWItNGJhMi04MjgzLWM0OWQzODE2NDBiZCJ9LCAidmVyaWZ5IjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgvdmVyaWZ5LzUxNjkzMTQzNTYiLCAiaXNzIjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgiLCAiaWF0IjogMTMxMzYwMTg4LCAidHlwIjogInB1cmNoYXNlLXJlY2VpcHQiLCAibmJmIjogMTMxMzYwMTg1LCAiZGV0YWlsIjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgvcmVjZWlwdC81MTY5MzE0MzU2In0.eZpTEnCLUR3iP3rm9WyJOqx1k66mQaAxqcrvX11r5E0';
 
   let valid_receipt2 = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJwcm9kdWN0IjogeyJ1cmwiOiAiaHR0cHM6Ly93d3cubW96aWxsYS5vcmciLCAic3RvcmVkYXRhIjogIjUxNjkzMTQzNTcifSwgInJlaXNzdWUiOiAiaHR0cDovL21vY2hpLnRlc3Q6ODg4OC9yZWlzc3VlLzUxNjkzMTQzNTYiLCAidXNlciI6IHsidHlwZSI6ICJkaXJlY3RlZC1pZGVudGlmaWVyIiwgInZhbHVlIjogIjRmYjM1MTUxLTJiOWItNGJhMi04MjgzLWM0OWQzODE2NDBiZCJ9LCAidmVyaWZ5IjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgvdmVyaWZ5LzUxNjkzMTQzNTYiLCAiaXNzIjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgiLCAiaWF0IjogMTMxMzYwMTg4LCAidHlwIjogInB1cmNoYXNlLXJlY2VpcHQiLCAibmJmIjogMTMxMzYwMTg1LCAiZGV0YWlsIjogImh0dHA6Ly9tb2NoaS50ZXN0Ojg4ODgvcmVjZWlwdC81MTY5MzE0MzU2In0.k7tI0PTaMJf0w0keAHJR6couypGY-EtA38q2xOtSv6k';
 
   let valid_receipt3 = 'eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCIsICJqa3UiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5jZG4ubW96aWxsYS5uZXQvcHVibGljX2tleXMvbWFya2V0cGxhY2Utcm9vdC1wdWIta2V5Lmp3ayJ9.eyJpc3MiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5jZG4ubW96aWxsYS5uZXQvcHVibGljX2tleXMvbWFya2V0cGxhY2Utcm9vdC1wdWIta2V5Lmp3ayIsICJwcmljZV9saW1pdCI6IDEwMCwgImp3ayI6IFt7ImFsZyI6ICJSU0EiLCAibW9kIjogIkFMYkszek5VQ0lFTEJRZ1QycGUzTEkwdC1sR0w5OElFTnBWOUtuX0F4VGxjLXZzX0ZFMlVyNzU2Z012bHA3a3BWVmFEWVNCdnVCQjgtZEZpU3VJbHdCUFB2bWFIaTFhd0xJMjRRY2JOMVJrN3pZS01SclVfSzdkVEN6MEh6VHoza01YVXp1ci1ySTIxS3BKb0NSZFNxeUl4bHpnUWFna1dUUWxIYUI2VzkzUjBacUxlQk9lUzhjbzNOUlczdjFfY0h4VTE1d0k4T0JHY0tRSXB3VHpONUVfRFdNZ0F1MGFQMHlWY3EzT0FwXy1fa1pjYXBtQnpSTmVMOHBxMjZXN01jMUpJZVBnZVZ5SXExcFBLMU9ldGhmdF9KeTk5R19EWWxQNW15YjFEY1VpbHE3RVNKc1UyeUZPUjJhWmkyYU1lTkRZekwyUmdZSGt2RWxyNDRMM2NZM0UiLCAiZXhwIjogIkFRQUIiLCAia2lkIjogImFwcHN0b3JlLm1vemlsbGEuY29tLTIwMTMtMTEtMjcifV0sICJleHAiOiAxMzg2Nzg4NDAxLCAiaWF0IjogMTM4NTU3ODgwMSwgInR5cCI6ICJjZXJ0aWZpZWQta2V5IiwgIm5iZiI6IDEzODU1Nzg4MDF9.Ne5AffwNIjbQmwY_dSKVXR0R0wdB92sW_BWQWbN2WKa_Ep6V0Fwr2pfcv0KenZcYKdxhhSPBrs5R38EcIqTYYrgIeeJyM_gGzv-ESsUsqbFejAbVH2xfwATZ1lXNPh0VSt33Drf2RY5jeU5PD3usXgOPr8RYAGkMxz_0SUay5WCBVRLkrgtrCUNyIKBwuHlxKK1JkncVXsN0mr_gwbm0EpBgIOEZQj75TE0KcviMUvYn8uhVYEwYMLzMQmUbI5quxH2z5mcK2DDNQGgT6ABJljKWCY-PPuMo9tsgXe6L7MTafulBuSIjs1ztAl4ZnwZjKmxWmhdeiaT41tCFlr4K8Q~eyJqa3UiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5jZG4ubW96aWxsYS5uZXQvcHVibGljX2tleXMvbWFya2V0cGxhY2Utcm9vdC1wdWIta2V5Lmp3ayIsICJ0eXAiOiAiSldUIiwgImFsZyI6ICJSUzI1NiJ9.eyJwcm9kdWN0IjogeyJ1cmwiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5maXJlZm94LmNvbSIsICJzdG9yZWRhdGEiOiAiaWQ9NDM4OTc4In0sICJpc3MiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5maXJlZm94LmNvbSIsICJ2ZXJpZnkiOiAiaHR0cHM6Ly9yZWNlaXB0Y2hlY2subWFya2V0cGxhY2UuZmlyZWZveC5jb20vdmVyaWZ5LyIsICJkZXRhaWwiOiAiaHR0cHM6Ly9tYXJrZXRwbGFjZS5maXJlZm94LmNvbS9hcGkvdjEvcmVjZWlwdHMvcmVpc3N1ZS8iLCAicmVpc3N1ZSI6ICJodHRwczovL21hcmtldHBsYWNlLmZpcmVmb3guY29tL2FwaS92MS9yZWNlaXB0cy9yZWlzc3VlLyIsICJ1c2VyIjogeyJ0eXBlIjogImRpcmVjdGVkLWlkZW50aWZpZXIiLCAidmFsdWUiOiAiMTkzMzI2LTVjMTUzNmQ1LWUxMDQtNDAzYy04NDBlLTQ5YjMyMmQ5Yjg4NSJ9LCAiZXhwIjogMTQwMTgyNTEyOCwgImlhdCI6IDEzODYxMDAzMjgsICJ0eXAiOiAicHVyY2hhc2UtcmVjZWlwdCIsICJuYmYiOiAxMzg2MTAwMzI4fQ.r2DVUpouRDJYqZe61LJBcIwmeF2mI8FmbGMRlfNFcinKAIs8nMVVNX8xSWJ6jXXgZ62VfHJCLHapADX8rCg6NgxFV_FdP7j2H_2Ufo0E0TREifTN6V4v1dCnzDulNhZmO8G-nQJUVOAtNfNC95PY7tVa8WC7dYXnKZsD6NhIxxVEtBGuiiySpWArI-g3pcl41rXNHHpJbRfrOD4QgVNrsV83TWILYRr6PWr3aqOM2XT_x2SzEfhBNvdG8AJmR0MKQytvfcgz3Vt1hMak88nFrzTLiKkuuPAXpwB5q83LZIl4EYG3UAnte4-XWlLb-NJ78vgXa64myy-3fPr7EO6LaQ';
 
   var request = navigator.mozApps.install(gManifestURL, { receipts: [ valid_receipt1, valid_receipt2, valid_receipt3 ]});
--- a/dom/apps/tests/test_marketplace_pkg_install.html
+++ b/dom/apps/tests/test_marketplace_pkg_install.html
@@ -126,18 +126,20 @@ function installApp(installOrigin, manif
 }
 
 PackagedTestHelper.setSteps([
   function() {
     SpecialPowers.setAllAppsLaunchable(true);
     SpecialPowers.addPermission("webapps-manage", true, document);
     SpecialPowers.addPermission("browser", true, document);
     SpecialPowers.autoConfirmAppInstall(() =>
-      SpecialPowers.pushPrefEnv({set: [["dom.mozBrowserFramesEnabled", true]]},
-                                PackagedTestHelper.next));
+      SpecialPowers.autoConfirmAppUninstall(() =>
+        SpecialPowers.pushPrefEnv({set: [["dom.mozBrowserFramesEnabled",
+                                          true]]},
+                                  PackagedTestHelper.next)));
   },
   function() {
     info("== TEST == Marketplace packaged app from https://marketplace.firefox.com/");
     let miniManifestURL = gMarketplaceAppsPath + "marketplace_app.webapp"
     let expected = {
       name: "Flashlight (Linterna)",
       manifestURL: miniManifestURL,
       installOrigin: gMarketplaceInstallOrigin.slice(0, -1),
--- a/dom/apps/tests/test_packaged_app_asmjs.html
+++ b/dom/apps/tests/test_packaged_app_asmjs.html
@@ -135,16 +135,19 @@ function runTest() {
   SpecialPowers.setAllAppsLaunchable(true);
   SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true]]},
                             continueTest);
   yield undefined;
 
   SpecialPowers.autoConfirmAppInstall(continueTest);
   yield undefined;
 
+  SpecialPowers.autoConfirmAppUninstall(continueTest);
+  yield undefined;
+
   setState("setVersion", 1, continueTest);
   yield undefined;
 
   // Test apps with wrong precompile fields
   info("Test with an empty array");
   testNoPrecompile('[]', continueTest);
   yield undefined;
   info("Test with an object");
--- a/dom/apps/tests/test_packaged_app_install.html
+++ b/dom/apps/tests/test_packaged_app_install.html
@@ -86,16 +86,20 @@ var steps = [
     info("Set up");
     PackagedTestHelper.next();
   },
   function() {
     info("autoConfirmAppInstall");
     SpecialPowers.autoConfirmAppInstall(PackagedTestHelper.next);
   },
   function() {
+    ok(true, "autoConfirmAppUninstall");
+    SpecialPowers.autoConfirmAppUninstall(PackagedTestHelper.next);
+  },
+  function() {
     PackagedTestHelper.setAppVersion(0, PackagedTestHelper.next);
   },
   function() {
     // Bug 927699 - navigator.mozApps.install(url) lets NS_ERROR_FAILURE onto
     //              the web.
     info("== TEST == INVALID_URL");
     checkAppInstallError("", "INVALID_URL");
   },
--- a/dom/apps/tests/test_receipt_operations.html
+++ b/dom/apps/tests/test_receipt_operations.html
@@ -52,16 +52,19 @@ function cbError(aEvent) {
 SimpleTest.waitForExplicitFinish();
 
 function runTest() {
   SpecialPowers.setAllAppsLaunchable(true);
 
   SpecialPowers.autoConfirmAppInstall(continueTest);
   yield undefined;
 
+  SpecialPowers.autoConfirmAppUninstall(continueTest);
+  yield undefined;
+
   var request = navigator.mozApps.install(gManifestURL);
   request.onerror = cbError;
   request.onsuccess = continueTest;
   yield undefined;
 
   var app = request.result;
   ok(app, "App is non-null");
   info("receipts are " + app.receipts);
--- a/dom/apps/tests/test_signed_pkg_install.html
+++ b/dom/apps/tests/test_signed_pkg_install.html
@@ -102,16 +102,20 @@ var steps = [
       });
     });
   },
   function() {
     info("autoConfirmAppInstall");
     SpecialPowers.autoConfirmAppInstall(PackagedTestHelper.next);
   },
   function() {
+    info("autoConfirmAppUninstall");
+    SpecialPowers.autoConfirmAppUninstall(PackagedTestHelper.next);
+  },
+  function() {
     info("== TEST == Install packaged app");
     var miniManifestURL = gSJS + "?" + "app=valid&" + "version=1";
 
     navigator.mozApps.mgmt.oninstall = function(evt) {
       info("Got oninstall event");
       gApp = evt.application;
       gApp.ondownloaderror = function() {
         ok(false, "Download should succeed (got error: " +
--- a/dom/apps/tests/test_uninstall_errors.html
+++ b/dom/apps/tests/test_uninstall_errors.html
@@ -39,16 +39,19 @@ https://bugzilla.mozilla.org/show_bug.cg
   }
 
   function runTest() {
     // Set up.
     SpecialPowers.setAllAppsLaunchable(true);
     SpecialPowers.autoConfirmAppInstall(continueTest);
     yield undefined;
 
+    SpecialPowers.autoConfirmAppUninstall(continueTest);
+    yield undefined;
+
     let request = navigator.mozApps.install(url1);
     request.onerror = mozAppsError;
     request.onsuccess = continueTest;
     yield undefined;
     let app1 = request.result;
     ok(app1, "App1 is non-null");
 
     request = navigator.mozApps.install(url2);
--- a/dom/apps/tests/test_widget.html
+++ b/dom/apps/tests/test_widget.html
@@ -185,17 +185,19 @@
       }
 
       SpecialPowers.setAllAppsLaunchable(true);
       runTest();
     },
 
     // No confirmation needed when an app is installed
     function() {
-      SpecialPowers.autoConfirmAppInstall(runTest);
+      SpecialPowers.autoConfirmAppInstall(() => {
+        SpecialPowers.autoConfirmAppUninstall(runTest);
+      });
     },
 
     // Installing the app
     ()=>installApp(gWidgetManifestURL),
 
     // Run tests in app
     ()=>testApp(true),
 
--- a/dom/tests/mochitest/webapps/cross_origin.html
+++ b/dom/tests/mochitest/webapps/cross_origin.html
@@ -14,17 +14,17 @@
  *
  * This page loads on a different origin than the one for the test page,
  * which enables that page to check the behavior of various API calls when apps
  * have been installed from multiple origins.
  */
 
 var parent = SpecialPowers.wrap(window).parent;
 
-confirmNextInstall();
+confirmNextPopup();
 navigator.mozApps.install(parent.url2, null).onsuccess = function onInstall() {
   // Give the test page a reference to the installed app, so it can uninstall it
   // after it finishes the tests.
   parent.app2 = this.result;
 
   navigator.mozApps.getSelf().onsuccess = function onGetSelf() {
     parent.ok(this.result == null, "getSelf() from app's origin returns null if called from a browser");
 
--- a/dom/tests/mochitest/webapps/head.js
+++ b/dom/tests/mochitest/webapps/head.js
@@ -29,29 +29,32 @@ function runAll(steps) {
     }
     else {
       SimpleTest.finish();
     }
   }
   next();
 }
 
-function confirmNextInstall() {
+function confirmNextPopup() {
   var Ci = SpecialPowers.Ci;
 
-  var popupPanel = SpecialPowers.wrap(window).top.
-                   QueryInterface(Ci.nsIInterfaceRequestor).
-                   getInterface(Ci.nsIWebNavigation).
-                   QueryInterface(Ci.nsIDocShell).
-                   chromeEventHandler.ownerDocument.defaultView.
-                   PopupNotifications.panel;
+  var popupNotifications = SpecialPowers.wrap(window).top.
+                           QueryInterface(Ci.nsIInterfaceRequestor).
+                           getInterface(Ci.nsIWebNavigation).
+                           QueryInterface(Ci.nsIDocShell).
+                           chromeEventHandler.ownerDocument.defaultView.
+                           PopupNotifications;
+
+  var popupPanel = popupNotifications.panel;
 
   function onPopupShown() {
     popupPanel.removeEventListener("popupshown", onPopupShown, false);
     SpecialPowers.wrap(this).childNodes[0].button.doCommand();
+    popupNotifications._dismiss();
   }
   popupPanel.addEventListener("popupshown", onPopupShown, false);
 }
 
 // We need to mock the Alerts service, otherwise the alert that is shown
 // at the end of an installation makes the test leak the app's icon.
 
 const CID = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID();
--- a/dom/tests/mochitest/webapps/test_bug_765063.xul
+++ b/dom/tests/mochitest/webapps/test_bug_765063.xul
@@ -38,17 +38,17 @@ var mmListener = {
 
 var ppmm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"]
                              .getService(Components.interfaces.nsIMessageBroadcaster);
 ppmm.addMessageListener("Webapps:Install", mmListener);
 
 // We call this here, even though the app is installed by the helper page,
 // because the helper page redirect would cause its install listener to unload
 // before it can confirm the install.
-confirmNextInstall();
+confirmNextPopup();
 
 </script> 
 
   <!-- Load a page that initiates an app installation and then immediately
      - redirects to a page at a different origin.  We can't do this directly
      - inside this test page, because that would cause the test to hang. -->
   <iframe src="http://test/chrome/dom/tests/mochitest/webapps/install_and_redirect_helper.xul"/>
 
--- a/dom/tests/mochitest/webapps/test_cross_origin.xul
+++ b/dom/tests/mochitest/webapps/test_cross_origin.xul
@@ -38,17 +38,17 @@ var steps = [
 
 runAll(steps);
 
 /**
  * Install the first app from our own origin (chrome://mochitests).  Note that
  * the app itself is from a different origin (http://test1.example.com).
  */
 function installAppFromOwnOrigin(next) {
-  confirmNextInstall();
+  confirmNextPopup();
   navigator.mozApps.install(url1, null).onsuccess = function onInstall() {
     app1 = this.result;
     next();
   };
 }
 
 /**
  * Install the second app from another origin (http://test2.example.com) using
@@ -88,17 +88,19 @@ function getAll(next) {
     var app2 = [a for (a of this.result) if (a.manifestURL == url2)][0];
     ok(app2, "mgmt.getAll() includes app installed from other origin");
 
     next();
   };
 }
 
 function uninstall(next) {
+  confirmNextPopup();
   navigator.mozApps.mgmt.uninstall(app1).onsuccess = function onUninstallApp1() {
+    confirmNextPopup();
     navigator.mozApps.mgmt.uninstall(app2).onsuccess = function onUninstallApp2() {
       next();
     };
   };
 }
 
 </script> 
 </window>
--- a/dom/tests/mochitest/webapps/test_getNotInstalled.xul
+++ b/dom/tests/mochitest/webapps/test_getNotInstalled.xul
@@ -71,21 +71,21 @@ function getNotInstalled(next) {
   function onGetNotInstalled() {
     notInstalled = this.result.length;
     next();
   };
 }
 
 // Add an app to the appregistry
 function installApp(next) {
-  confirmNextInstall();
+  confirmNextPopup();
   navigator.mozApps.install(url, null).onsuccess = function onInstall() {
     app = this.result;
     next();
-  }
+  };
 }
 
 // Call navigator.mozApps.mgmt.getNotInstalled and make sure there is one more.
 function compareNotInstalled(next) {
   let results;
   function getNotInstalledError() {
     ok(false, "window.mozApps.mgmt.getNotInstalled onerror called");
     next();
@@ -123,16 +123,17 @@ function unmonkeyPatchDOMApplicationRegi
   } else {
     ok(false, "can't restore DOMApplicationRegistry._isLaunchable");
   }
   next();
 }
 
 // Remove the app from the appregistry
 function uninstallApp(next) {
+  confirmNextPopup();
   window.navigator.mozApps.mgmt.uninstall(app).onsuccess = function onUninstall() {
     app = null;
     next();
   }
 }
 
 </script>
 </window>
--- a/dom/tests/mochitest/webapps/test_install_app.xul
+++ b/dom/tests/mochitest/webapps/test_install_app.xul
@@ -40,17 +40,17 @@ function getInstalledReturnsNothing(next
     next();
   };
 }
 
 function install(next) {
   var beforehand = Date.now();
   const fuzzySpan = 250;
 
-  confirmNextInstall();
+  confirmNextPopup();
   navigator.mozApps.install(url, null).onsuccess = function onInstall() {
     app = this.result;
 
     is(app.origin, "http://test", "origin");
     is(app.installOrigin, "chrome://mochitests", "install origin");
     ok(app.installTime + fuzzySpan >= beforehand, "install time is after install() call");
     ok(app.installTime <= Date.now() + fuzzySpan, "install time is before install success");
     is(app.manifestURL, url, "manifest URL");
@@ -79,16 +79,17 @@ function getSelf(next) {
   navigator.mozApps.getSelf().onsuccess = function onGetSelf() {
     is(this.result, null, "getSelf() returns nothing (different origin)");
 
     next();
   };
 }
 
 function uninstall(next) {
+  confirmNextPopup();
   navigator.mozApps.mgmt.uninstall(app).onsuccess = function onUninstall() {
     // Try to retrieve the app we just uninstalled, to make sure it no longer
     // exists in the registry.
     navigator.mozApps.getInstalled().onsuccess = function onGetInstalled() {
       var a = [a for (a of this.result) if (a.manifestURL == url)][0];
       is(a, undefined, "getInstalled() returns nothing again after uninstall");
 
       next();
--- a/dom/tests/mochitest/webapps/test_install_errors.xul
+++ b/dom/tests/mochitest/webapps/test_install_errors.xul
@@ -64,26 +64,27 @@ function invalidManifest(next) {
     is(this.error.name, "INVALID_MANIFEST", "manifest missing required field");
     next();
   };
 }
 
 function permissionDenied(next) {
   var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/no_delegated_install.webapp";
 
-  confirmNextInstall();
+  confirmNextPopup();
   var request = navigator.mozApps.install(url, null);
 
   request.onerror = function onInstallError() {
     is(this.error.name, "DENIED", "manifest without installs_allowed_from");
     next();
   };
 
   request.onsuccess = function onInstall() {
     todo(false, "manifest without installs_allowed_from fails");
+    confirmNextPopup();
     navigator.mozApps.mgmt.uninstall(this.result).onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
 function invalidContent(next) {
   var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/bad_content_type.webapp";
@@ -92,16 +93,17 @@ function invalidContent(next) {
 
   request.onerror = function onInstallError() {
     is(this.error.name, "INVALID_MANIFEST_CONTENT_TYPE", "manifest with bad content type");
     next();
   };
 
   request.onsuccess = function onInstall() {
     ok(false, "manifest with bad content type should fail");
+    confirmNextPopup();
     navigator.mozApps.mgmt.uninstall(this.result).onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
 function invalidLaunchPath(next) {
   var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/invalid_launch_path.webapp";
@@ -201,35 +203,37 @@ function originNotAllowed(next) {
 
   request.onerror = function onInstallError() {
     is(this.error.name, "INSTALL_FROM_DENIED", "origin is not in installs_allowed_from");
     next();
   };
 
   request.onsuccess = function onInstall() {
     ok(false, "test should fail because of installs_allowed_from");
+    confirmNextPopup();
     navigator.mozApps.mgmt.uninstall(this.result).onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
 function originAllowed(next) {
   var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/installs_allowed_from_chrome_mochitests.webapp";
 
-  confirmNextInstall();
+  confirmNextPopup();
   var request = navigator.mozApps.install(url, null);
 
   request.onerror = function onInstallError() {
     ok(false, "installation error: " + this.error.name);
     next();
   };
 
   request.onsuccess = function onInstall() {
     ok(true, "test origin is in installs_allowed_from");
+    confirmNextPopup();
     navigator.mozApps.mgmt.uninstall(this.result).onsuccess = function onUninstall() {
       next();
     };
   };
 }
 
 </script>
 </window>
--- a/dom/tests/mochitest/webapps/test_install_utf8.xul
+++ b/dom/tests/mochitest/webapps/test_install_utf8.xul
@@ -17,21 +17,22 @@
   </body>
 
 <script>
 
 SimpleTest.waitForExplicitFinish();
 
 var url = "http://test/chrome/dom/tests/mochitest/webapps/apps/utf8.webapp";
 
-confirmNextInstall();
+confirmNextPopup();
 navigator.mozApps.install(url, null).onsuccess = function onInstall() {
   is(this.result.manifest.name, "TheBOM ゲゴケ゚セニツ゚ヅヂチ", "manifest.name");
   is(this.result.manifest.description, "This App is THE BOM, yo. ヅヂチ",
      "manifest.description");
 
+  confirmNextPopup();
   navigator.mozApps.mgmt.uninstall(this.result).onsuccess = function onUninstall() {
     SimpleTest.finish();
   }
 };
 
 </script>
 </window>
--- a/dom/tests/mochitest/webapps/test_launch_paths.xul
+++ b/dom/tests/mochitest/webapps/test_launch_paths.xul
@@ -40,17 +40,17 @@ function getInstalledReturnsNothing(next
     next();
   };
 }
 
 function install(next) {
   var beforehand = Date.now();
   const fuzzySpan = 250;
 
-  confirmNextInstall();
+  confirmNextPopup();
   navigator.mozApps.install(url, null).onsuccess = function onInstall() {
     app = this.result;
 
     is(app.origin, "http://test", "origin");
     is(app.installOrigin, "chrome://mochitests", "install origin");
     ok(app.installTime + fuzzySpan >= beforehand, "install time is after install() call");
     ok(app.installTime <= Date.now() + fuzzySpan, "install time is before install success");
     is(app.manifestURL, url, "manifest URL");
@@ -79,16 +79,17 @@ function getSelf(next) {
   navigator.mozApps.getSelf().onsuccess = function onGetSelf() {
     is(this.result, null, "getSelf() returns nothing (different origin)");
 
     next();
   };
 }
 
 function uninstall(next) {
+  confirmNextPopup();
   navigator.mozApps.mgmt.uninstall(app).onsuccess = function onUninstall() {
     // Try to retrieve the app we just uninstalled, to make sure it no longer
     // exists in the registry.
     navigator.mozApps.getInstalled().onsuccess = function onGetInstalled() {
       var a = [a for (a of this.result) if (a.manifestURL == url)][0];
       is(a, undefined, "getInstalled() returns nothing again after uninstall");
 
       next();
--- a/toolkit/webapps/tests/head.js
+++ b/toolkit/webapps/tests/head.js
@@ -497,17 +497,17 @@ function generateDataURI(aFile) {
   var stream = Cc["@mozilla.org/binaryinputstream;1"].
                createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
 
   return "data:" + contentType + ";base64," +
          btoa(stream.readBytes(stream.available()));
 }
 
-function confirmNextInstall() {
+function confirmNextPopup() {
   let popupPanel = window.top.QueryInterface(Ci.nsIInterfaceRequestor).
                               getInterface(Ci.nsIWebNavigation).
                               QueryInterface(Ci.nsIDocShell).
                               chromeEventHandler.ownerDocument.defaultView.
                               PopupNotifications.panel;
 
   popupPanel.addEventListener("popupshown", function onPopupShown() {
     popupPanel.removeEventListener("popupshown", onPopupShown, false);
--- a/toolkit/webapps/tests/test_custom_origin.xul
+++ b/toolkit/webapps/tests/test_custom_origin.xul
@@ -73,17 +73,17 @@ let runTest = Task.async(function*() {
   });
 
   // On Mac build servers, we don't have enough privileges to write to /Applications,
   // so we install apps in a user-owned directory.
   if (MAC) {
     yield setMacRootInstallDir(OS.Path.join(OS.Constants.Path.homeDir, "Applications"));
   }
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   let request = navigator.mozApps.installPackage(app.manifestURL);
 
   let (deferred = Promise.defer()) {
     request.onerror = function() {
       deferred.reject(this.error.name);
     };
     request.onsuccess = deferred.resolve;
--- a/toolkit/webapps/tests/test_custom_origin_uninstall_install.xul
+++ b/toolkit/webapps/tests/test_custom_origin_uninstall_install.xul
@@ -73,17 +73,17 @@ let runTest = Task.async(function*() {
   });
 
   // On Mac build servers, we don't have enough privileges to write to /Applications,
   // so we install apps in a user-owned directory.
   if (MAC) {
     yield setMacRootInstallDir(OS.Path.join(OS.Constants.Path.homeDir, "Applications"));
   }
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   let (request = navigator.mozApps.installPackage(app.manifestURL)) {
     let (deferred = Promise.defer()) {
       request.onerror = function() {
         deferred.reject(this.error.name);
       };
       request.onsuccess = deferred.resolve;
       yield deferred.promise;
@@ -105,17 +105,17 @@ let runTest = Task.async(function*() {
     yield wait(1000);
   }
   ok(true, "App launchable");
 
   yield WebappOSUtils.uninstall(app)
 
   is(WebappOSUtils.launch(app), false, "Launch fails");
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   let (request = navigator.mozApps.installPackage(app.manifestURL)) {
     let (deferred = Promise.defer()) {
       request.onerror = function() {
         deferred.reject(this.error.name);
       };
       request.onsuccess = deferred.resolve;
       yield deferred.promise;
--- a/toolkit/webapps/tests/test_hosted_checkforupdates_from_webapp_runtime.xul
+++ b/toolkit/webapps/tests/test_hosted_checkforupdates_from_webapp_runtime.xul
@@ -51,17 +51,17 @@ let runTest = Task.async(function*() {
   setDryRunPref();
 
   // On Mac build servers, we don't have enough privileges to write to /Applications,
   // so we install apps in a user-owned directory.
   if (MAC) {
     yield setMacRootInstallDir(OS.Path.join(OS.Constants.Path.homeDir, "Applications"));
   }
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   yield setState("Version", 1);
 
   let request = navigator.mozApps.install(app.manifestURL);
 
   let (deferred = Promise.defer()) {
     request.onerror = function() {
       deferred.reject(this.error.name);
--- a/toolkit/webapps/tests/test_install_appcache.xul
+++ b/toolkit/webapps/tests/test_install_appcache.xul
@@ -51,17 +51,17 @@ let runTest = Task.async(function*() {
   setDryRunPref();
 
   // On Mac build servers, we don't have enough privileges to write to /Applications,
   // so we install apps in a user-owned directory.
   if (MAC) {
     yield setMacRootInstallDir(OS.Path.join(OS.Constants.Path.homeDir, "Applications"));
   }
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   let request = navigator.mozApps.install(app.manifestURL);
 
   let (deferred = Promise.defer()) {
     request.onerror = function() {
       deferred.reject(this.error.name);
     };
     request.onsuccess = deferred.resolve;
--- a/toolkit/webapps/tests/test_packaged_checkforupdates_from_webapp_runtime.xul
+++ b/toolkit/webapps/tests/test_packaged_checkforupdates_from_webapp_runtime.xul
@@ -51,17 +51,17 @@ let runTest = Task.async(function*() {
   setDryRunPref();
 
   // On Mac build servers, we don't have enough privileges to write to /Applications,
   // so we install apps in a user-owned directory.
   if (MAC) {
     yield setMacRootInstallDir(OS.Path.join(OS.Constants.Path.homeDir, "Applications"));
   }
 
-  confirmNextInstall();
+  confirmNextPopup();
 
   yield setState("Version", 1);
 
   let request = navigator.mozApps.installPackage(app.manifestURL);
 
   let (deferred = Promise.defer()) {
     request.onerror = function() {
       deferred.reject(this.error.name);