Bug 1422163 - Part 2 - Make a new test for clearing all site data with the new dialog. r=Gijs draft
authorJohann Hofmann <jhofmann@mozilla.com>
Wed, 10 Jan 2018 12:25:04 +0100
changeset 751408 84058f7bd58834923a9ff3bab360d3a863787ff4
parent 751407 efc9eb9a4669d9b6674c896bd6c4d5c710b73be4
push id97969
push userjhofmann@mozilla.com
push dateTue, 06 Feb 2018 09:52:53 +0000
reviewersGijs
bugs1422163
milestone60.0a1
Bug 1422163 - Part 2 - Make a new test for clearing all site data with the new dialog. r=Gijs MozReview-Commit-ID: 6Lt3hPZ1YiO
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_clearSiteData.js
browser/components/preferences/in-content/tests/browser_siteData.js
browser/components/preferences/in-content/tests/head.js
browser/components/preferences/in-content/tests/site_data_test.html
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -36,16 +36,17 @@ skip-if = !updater
 [browser_engines.js]
 support-files =
   browser_bug1184989_prevent_scrolling_when_preferences_flipped.xul
 [browser_change_app_handler.js]
 skip-if = os != "win" || (os == "win" && os_version == "6.1")
 # This test tests the windows-specific app selection dialog, so can't run on non-Windows.
 # Skip the test on Window 7, see the detail at Bug 1381706.
 [browser_checkspelling.js]
+[browser_clearSiteData.js]
 [browser_connection.js]
 [browser_connection_bug388287.js]
 [browser_cookies_exceptions.js]
 [browser_defaultbrowser_alwayscheck.js]
 [browser_healthreport.js]
 skip-if = true || !healthreport # Bug 1185403 for the "true"
 [browser_homepages_filter_aboutpreferences.js]
 [browser_extension_controlled.js]
copy from browser/components/preferences/in-content/tests/browser_siteData.js
copy to browser/components/preferences/in-content/tests/browser_clearSiteData.js
--- a/browser/components/preferences/in-content/tests/browser_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_clearSiteData.js
@@ -1,64 +1,25 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+ChromeUtils.import("resource:///modules/SitePermissions.jsm");
 
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-/* global sinon */
-Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
+const { SiteDataManager } = ChromeUtils.import("resource:///modules/SiteDataManager.jsm", {});
+const { DownloadUtils } = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm", {});
 
 const TEST_QUOTA_USAGE_HOST = "example.com";
 const TEST_QUOTA_USAGE_ORIGIN = "https://" + TEST_QUOTA_USAGE_HOST;
 const TEST_QUOTA_USAGE_URL = TEST_QUOTA_USAGE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/site_data_test.html";
 const TEST_OFFLINE_HOST = "example.org";
 const TEST_OFFLINE_ORIGIN = "https://" + TEST_OFFLINE_HOST;
 const TEST_OFFLINE_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/offline/offline.html";
 const TEST_SERVICE_WORKER_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/service_worker_test.html";
-const REMOVE_DIALOG_URL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
-
-const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm", {});
-const { DownloadUtils } = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm", {});
-const { SiteDataManager } = ChromeUtils.import("resource:///modules/SiteDataManager.jsm", {});
-const { OfflineAppCacheHelper } = ChromeUtils.import("resource:///modules/offlineAppCache.jsm", {});
-
-XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager", "@mozilla.org/serviceworkers/manager;1", "nsIServiceWorkerManager");
-
-const mockOfflineAppCacheHelper = {
-  clear: null,
-
-  originalClear: null,
-
-  register() {
-    this.originalClear = OfflineAppCacheHelper.clear;
-    this.clear = sinon.spy();
-    OfflineAppCacheHelper.clear = this.clear;
-  },
-
-  unregister() {
-    OfflineAppCacheHelper.clear = this.originalClear;
-  }
-};
-
-function getPersistentStoragePermStatus(origin) {
-  let uri = NetUtil.newURI(origin);
-  let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-  return Services.perms.testExactPermissionFromPrincipal(principal, "persistent-storage");
-}
-
-function getQuotaUsage(origin) {
-  return new Promise(resolve => {
-    let uri = NetUtil.newURI(origin);
-    let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-    Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
-  });
-}
 
 // XXX: The intermittent bug 1331851
 // The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced,
 // so we must hold this observer here well. If we didn't, there would be a chance that
 // in Linux debug test run the observer was released before the operation at gecko was completed
 // (may be because of a relatively quicker GC cycle or a relatively slower operation).
 // As a result of that, we would never get the cache usage we want so the test would fail from timeout.
 const cacheUsageGetter = {
@@ -79,264 +40,166 @@ const cacheUsageGetter = {
     cacheUsageGetter._resolve(usage);
   },
   QueryInterface: XPCOMUtils.generateQI([
     Components.interfaces.nsICacheStorageConsumptionObserver,
     Components.interfaces.nsISupportsWeakReference
   ]),
 };
 
-function promiseCookiesCleared() {
-  return TestUtils.topicObserved("cookie-changed", (subj, data) => {
-    return data === "cleared";
-  });
-}
-
-async function loadServiceWorkerTestPage(url) {
-  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-  await BrowserTestUtils.waitForCondition(() => {
-    return ContentTask.spawn(tab.linkedBrowser, {}, () =>
-      content.document.body.getAttribute("data-test-service-worker-registered") === "true");
-  }, `Fail to load service worker test ${url}`);
-  await BrowserTestUtils.removeTab(tab);
-}
+async function testClearData(clearSiteData, clearCache) {
+  let quotaURI = Services.io.newURI(TEST_QUOTA_USAGE_ORIGIN);
+  SitePermissions.set(quotaURI, "persistent-storage", SitePermissions.ALLOW);
 
-function promiseServiceWorkerRegisteredFor(url) {
-  return BrowserTestUtils.waitForCondition(() => {
-    try {
-      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(url);
-      let sw = serviceWorkerManager.getRegistrationByPrincipal(principal, principal.URI.spec);
-      if (sw) {
-        ok(true, `Found the service worker registered for ${url}`);
-        return true;
-      }
-    } catch (e) {}
-    return false;
-  }, `Should register service worker for ${url}`);
-}
-
-function promiseServiceWorkersCleared() {
-  return BrowserTestUtils.waitForCondition(() => {
-    let serviceWorkers = serviceWorkerManager.getAllRegistrations();
-    if (serviceWorkers.length == 0) {
-      ok(true, "Cleared all service workers");
-      return true;
-    }
-    return false;
-  }, "Should clear all service workers");
-}
-
-registerCleanupFunction(function() {
-  delete window.sinon;
-  mockOfflineAppCacheHelper.unregister();
-});
-
-// Test listing site using quota usage or site using appcache
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-
-  // Open a test site which would save into appcache
+  // Open a test site which saves into appcache.
   await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_OFFLINE_URL);
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
-  // Open a test site which would save into quota manager
-  await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL);
-  // eslint-disable-next-line mozilla/no-cpows-in-tests
-  await waitForEvent(gBrowser.selectedBrowser.contentWindowAsCPOW, "test-indexedDB-done");
+  // Fill indexedDB with test data.
+  // Don't wait for the page to load, to register the content event handler as quickly as possible.
+  // If this test goes intermittent, we might have to tell the page to wait longer before
+  // firing the event.
+  BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL, false);
+  await BrowserTestUtils.waitForContentEvent(
+    gBrowser.selectedBrowser, "test-indexedDB-done", false, null, true);
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
-  let updatedPromise = promiseSiteDataManagerSitesUpdated();
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  await updatedPromise;
-  await openSiteDataSettingsDialog();
-  // eslint-disable-next-line mozilla/no-cpows-in-tests
-  let dialog = content.gSubDialog._topDialog;
-  let dialogFrame = dialog._frame;
-  let frameDoc = dialogFrame.contentDocument;
-
-  let siteItems = frameDoc.getElementsByTagName("richlistitem");
-  is(siteItems.length, 2, "Should list sites using quota usage or appcache");
-
-  let appcacheSite = frameDoc.querySelector(`richlistitem[host="${TEST_OFFLINE_HOST}"]`);
-  ok(appcacheSite, "Should list site using appcache");
-
-  let qoutaUsageSite = frameDoc.querySelector(`richlistitem[host="${TEST_QUOTA_USAGE_HOST}"]`);
-  ok(qoutaUsageSite, "Should list site using quota usage");
-
-  // Always remember to clean up
-  OfflineAppCacheHelper.clear();
-  await new Promise(resolve => {
-    let principal = Services.scriptSecurityManager
-                            .createCodebasePrincipalFromOrigin(TEST_QUOTA_USAGE_ORIGIN);
-    let request = Services.qms.clearStoragesForPrincipal(principal, null, true);
-    request.callback = resolve;
-  });
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Test buttons are disabled and loading message shown while updating sites
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  let updatedPromise = promiseSiteDataManagerSitesUpdated();
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  await updatedPromise;
-
-  let actual = null;
-  let expected = null;
-  let doc = gBrowser.selectedBrowser.contentDocument;
-  let clearBtn = doc.getElementById("clearSiteDataButton");
-  let settingsButton = doc.getElementById("siteDataSettings");
-  let prefStrBundle = doc.getElementById("bundlePreferences");
-  let totalSiteDataSizeLabel = doc.getElementById("totalSiteDataSize");
-  is(clearBtn.disabled, false, "Should enable clear button after sites updated");
-  is(settingsButton.disabled, false, "Should enable settings button after sites updated");
-  await SiteDataManager.getTotalUsage()
-                       .then(usage => {
-                         actual = totalSiteDataSizeLabel.textContent;
-                         expected = prefStrBundle.getFormattedString(
-                           "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
-                          is(actual, expected, "Should show the right total site data size");
-                       });
-
-  Services.obs.notifyObservers(null, "sitedatamanager:updating-sites");
-  is(clearBtn.disabled, true, "Should disable clear button while updating sites");
-  is(settingsButton.disabled, true, "Should disable settings button while updating sites");
-  actual = totalSiteDataSizeLabel.textContent;
-  expected = prefStrBundle.getString("loadingSiteDataSize");
-  is(actual, expected, "Should show the loading message while updating");
-
-  Services.obs.notifyObservers(null, "sitedatamanager:sites-updated");
-  is(clearBtn.disabled, false, "Should enable clear button after sites updated");
-  is(settingsButton.disabled, false, "Should enable settings button after sites updated");
-  await SiteDataManager.getTotalUsage()
-                       .then(usage => {
-                         actual = totalSiteDataSizeLabel.textContent;
-                         expected = prefStrBundle.getFormattedString(
-                           "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
-                          is(actual, expected, "Should show the right total site data size");
-                       });
-
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Test the function of the "Clear All Data" button
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  addPersistentStoragePerm(TEST_QUOTA_USAGE_ORIGIN);
-
-  await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL);
-  // eslint-disable-next-line mozilla/no-cpows-in-tests
-  await waitForEvent(gBrowser.selectedBrowser.contentWindowAsCPOW, "test-indexedDB-done");
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+  // Register some service workers.
+  await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
+  await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
 
   await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
 
-  // Test the initial states
+  // Test the initial states.
   let cacheUsage = await cacheUsageGetter.get();
   let quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
   let totalUsage = await SiteDataManager.getTotalUsage();
   Assert.greater(cacheUsage, 0, "The cache usage should not be 0");
   Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
   Assert.greater(totalUsage, 0, "The total usage should not be 0");
 
-  // Test cancelling "Clear All Data"
-  // Click "Clear All Data" button and then cancel
   let doc = gBrowser.selectedBrowser.contentDocument;
-  let cancelPromise = promiseAlertDialogOpen("cancel");
-  let clearBtn = doc.getElementById("clearSiteDataButton");
-  clearBtn.doCommand();
-  await cancelPromise;
+  let clearSiteDataButton = doc.getElementById("clearSiteDataButton");
+
+  let dialogOpened = promiseLoadSubDialog("chrome://browser/content/preferences/clearSiteData.xul");
+  clearSiteDataButton.doCommand();
+  let dialogWin = await dialogOpened;
+
+  // Convert the usage numbers in the same way the UI does it to assert
+  // that they're displayed in the dialog.
+  let [convertedTotalUsage] = DownloadUtils.convertByteUnits(totalUsage);
+  // For cache we just assert that the right unit (KB, probably) is displayed,
+  // since we've had cache intermittently changing under our feet.
+  let [, convertedCacheUnit] = DownloadUtils.convertByteUnits(cacheUsage);
 
-  // Test the items are not removed
-  let status = getPersistentStoragePermStatus(TEST_QUOTA_USAGE_ORIGIN);
-  is(status, Ci.nsIPermissionManager.ALLOW_ACTION, "Should not remove permission");
+  let clearSiteDataLabel = dialogWin.document.getElementById("clearSiteDataLabel");
+  let clearCacheLabel = dialogWin.document.getElementById("clearCacheLabel");
+  // The usage details are filled asynchronously, so we assert that they're present by
+  // waiting for them to be filled in.
+  await Promise.all([
+    TestUtils.waitForCondition(
+      () => clearSiteDataLabel.value && clearSiteDataLabel.value.includes(convertedTotalUsage), "Should show the quota usage"),
+    TestUtils.waitForCondition(
+      () => clearCacheLabel.value && clearCacheLabel.value.includes(convertedCacheUnit), "Should show the cache usage")
+  ]);
 
-  cacheUsage = await cacheUsageGetter.get();
-  quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
-  totalUsage = await SiteDataManager.getTotalUsage();
-  Assert.greater(cacheUsage, 0, "The cache usage should not be 0");
-  Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
-  Assert.greater(totalUsage, 0, "The total usage should not be 0");
-  // Test cancelling "Clear All Data" ends
+  // Check the boxes according to our test input.
+  let clearSiteDataCheckbox = dialogWin.document.getElementById("clearSiteData");
+  let clearCacheCheckbox = dialogWin.document.getElementById("clearCache");
+  clearSiteDataCheckbox.checked = clearSiteData;
+  clearCacheCheckbox.checked = clearCache;
+
+  // Some additional promises/assertions to wait for
+  // when deleting site data.
+  let acceptPromise;
+  let updatePromise;
+  let cookiesClearedPromise;
+  if (clearSiteData) {
+    acceptPromise = promiseAlertDialogOpen("accept");
+    updatePromise = promiseSiteDataManagerSitesUpdated();
+    cookiesClearedPromise = promiseCookiesCleared();
+  }
+
+  let dialogClosed = BrowserTestUtils.waitForEvent(dialogWin, "unload");
 
-  // Test accepting "Clear All Data"
-  // Click "Clear All Data" button and then accept
-  let acceptPromise = promiseAlertDialogOpen("accept");
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
-  let cookiesClearedPromise = promiseCookiesCleared();
+  let clearButton = dialogWin.document.getElementById("clearButton");
+  if (!clearSiteData && !clearCache) {
+    // Simulate user input on one of the checkboxes to trigger the event listener for
+    // disabling the clearButton.
+    clearCacheCheckbox.doCommand();
+    // Check that the clearButton gets disabled by unchecking both options.
+    await TestUtils.waitForCondition(() => clearButton.disabled, "Clear button should be disabled");
+    let cancelButton = dialogWin.document.getElementById("cancelButton");
+    // Cancel, since we can't delete anything.
+    cancelButton.click();
+  } else {
+    // Delete stuff!
+    clearButton.click();
+  }
 
-  mockOfflineAppCacheHelper.register();
-  clearBtn.doCommand();
-  await acceptPromise;
-  await updatePromise;
-  mockOfflineAppCacheHelper.unregister();
+  // For site data we display an extra warning dialog, make sure
+  // to accept it.
+  if (clearSiteData) {
+    await acceptPromise;
+  }
+
+  await dialogClosed;
 
-  // Test all the items are removed
-  await cookiesClearedPromise;
+  if (clearCache) {
+    TestUtils.waitForCondition(async function() {
+      let usage = await cacheUsageGetter.get();
+      return usage == 0;
+    }, "The cache usage should be removed");
+  } else {
+    Assert.greater(await cacheUsageGetter.get(), 0, "The cache usage should not be 0");
+  }
 
-  ok(mockOfflineAppCacheHelper.clear.calledOnce, "Should clear app cache");
-
-  status = getPersistentStoragePermStatus(TEST_QUOTA_USAGE_ORIGIN);
-  is(status, Ci.nsIPermissionManager.UNKNOWN_ACTION, "Should remove permission");
+  if (clearSiteData) {
+    await updatePromise;
+    await cookiesClearedPromise;
+    await promiseServiceWorkersCleared();
 
-  cacheUsage = await cacheUsageGetter.get();
-  quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
-  totalUsage = await SiteDataManager.getTotalUsage();
-  is(cacheUsage, 0, "The cache usage should be removed");
-  is(quotaUsage, 0, "The quota usage should be removed");
-  is(totalUsage, 0, "The total usage should be removed");
-  // Test accepting "Clear All Data" ends
+    TestUtils.waitForCondition(async function() {
+      let usage = await SiteDataManager.getTotalUsage();
+      return usage == 0;
+    }, "The total usage should be removed");
+
+    // Check that the size label in about:preferences updates after we cleared data.
+    await ContentTask.spawn(gBrowser.selectedBrowser, null, async function() {
+      let sizeLabel = content.document.getElementById("totalSiteDataSize");
+
+      await ContentTaskUtils.waitForCondition(
+        () => sizeLabel.textContent.includes("0"), "Site data size label should have updated.");
+    });
+  } else {
+    quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
+    totalUsage = await SiteDataManager.getTotalUsage();
+    Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
+    Assert.greater(totalUsage, 0, "The total usage should not be 0");
+  }
+
+  let desiredPermissionState = clearSiteData ? SitePermissions.UNKNOWN : SitePermissions.ALLOW;
+  let permission = SitePermissions.get(quotaURI, "persistent-storage");
+  is(permission.state, desiredPermissionState, "Should have the correct permission state.");
 
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+  await SiteDataManager.removeAll();
+}
+
+// Test opening the "Clear All Data" dialog and cancelling.
+add_task(async function() {
+  await testClearData(false, false);
 });
 
-// Test clearing service wroker through the "Clear All" button
+// Test opening the "Clear All Data" dialog and removing all site data.
 add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  // Register a test service
-  await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  // Test the initial states
-  await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
-  // Click the "Clear All" button
-  let doc = gBrowser.selectedBrowser.contentDocument;
-  let clearBtn = doc.getElementById("clearSiteDataButton");
-  let acceptPromise = promiseAlertDialogOpen("accept");
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
-  clearBtn.doCommand();
-  await acceptPromise;
-  await updatePromise;
-  await promiseServiceWorkersCleared();
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+  await testClearData(true, false);
 });
 
-// Test clearing service wroker through the settings panel
+// Test opening the "Clear All Data" dialog and removing all cache.
 add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  // Register a test service worker
-  await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  // Test the initial states
-  await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
-  // Open the Site Data Settings panel and remove the site
-  await openSiteDataSettingsDialog();
-  let acceptRemovePromise = promiseAlertDialogOpen("accept");
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
-  ContentTask.spawn(gBrowser.selectedBrowser, { TEST_OFFLINE_HOST }, args => {
-    let host = args.TEST_OFFLINE_HOST;
-    let frameDoc = content.gSubDialog._topDialog._frame.contentDocument;
-    let sitesList = frameDoc.getElementById("sitesList");
-    let site = sitesList.querySelector(`richlistitem[host="${host}"]`);
-    if (site) {
-      let removeBtn = frameDoc.getElementById("removeSelected");
-      let saveBtn = frameDoc.getElementById("save");
-      site.click();
-      removeBtn.doCommand();
-      saveBtn.doCommand();
-    } else {
-      ok(false, `Should have one site of ${host}`);
-    }
-  });
-  await acceptRemovePromise;
-  await updatePromise;
-  await promiseServiceWorkersCleared();
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+  await testClearData(false, true);
 });
+
+// Test opening the "Clear All Data" dialog and removing everything.
+add_task(async function() {
+  await testClearData(true, true);
+});
--- a/browser/components/preferences/in-content/tests/browser_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_siteData.js
@@ -1,151 +1,44 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-/* global sinon */
-Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
-
 const TEST_QUOTA_USAGE_HOST = "example.com";
 const TEST_QUOTA_USAGE_ORIGIN = "https://" + TEST_QUOTA_USAGE_HOST;
 const TEST_QUOTA_USAGE_URL = TEST_QUOTA_USAGE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/site_data_test.html";
 const TEST_OFFLINE_HOST = "example.org";
 const TEST_OFFLINE_ORIGIN = "https://" + TEST_OFFLINE_HOST;
 const TEST_OFFLINE_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/offline/offline.html";
 const TEST_SERVICE_WORKER_URL = TEST_OFFLINE_ORIGIN + "/browser/browser/components/preferences/in-content/tests/service_worker_test.html";
-const REMOVE_DIALOG_URL = "chrome://browser/content/preferences/siteDataRemoveSelected.xul";
 
 const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm", {});
 const { DownloadUtils } = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm", {});
 const { SiteDataManager } = ChromeUtils.import("resource:///modules/SiteDataManager.jsm", {});
 const { OfflineAppCacheHelper } = ChromeUtils.import("resource:///modules/offlineAppCache.jsm", {});
 
-XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager", "@mozilla.org/serviceworkers/manager;1", "nsIServiceWorkerManager");
-
-const mockOfflineAppCacheHelper = {
-  clear: null,
-
-  originalClear: null,
-
-  register() {
-    this.originalClear = OfflineAppCacheHelper.clear;
-    this.clear = sinon.spy();
-    OfflineAppCacheHelper.clear = this.clear;
-  },
-
-  unregister() {
-    OfflineAppCacheHelper.clear = this.originalClear;
-  }
-};
-
 function getPersistentStoragePermStatus(origin) {
   let uri = NetUtil.newURI(origin);
   let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
   return Services.perms.testExactPermissionFromPrincipal(principal, "persistent-storage");
 }
 
-function getQuotaUsage(origin) {
-  return new Promise(resolve => {
-    let uri = NetUtil.newURI(origin);
-    let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-    Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
-  });
-}
-
-// XXX: The intermittent bug 1331851
-// The implementation of nsICacheStorageConsumptionObserver must be passed as weak referenced,
-// so we must hold this observer here well. If we didn't, there would be a chance that
-// in Linux debug test run the observer was released before the operation at gecko was completed
-// (may be because of a relatively quicker GC cycle or a relatively slower operation).
-// As a result of that, we would never get the cache usage we want so the test would fail from timeout.
-const cacheUsageGetter = {
-  _promise: null,
-  _resolve: null,
-  get() {
-    if (!this._promise) {
-      this._promise = new Promise(resolve => {
-        this._resolve = resolve;
-        Services.cache2.asyncGetDiskConsumption(this);
-      });
-    }
-    return this._promise;
-  },
-  // nsICacheStorageConsumptionObserver implementations
-  onNetworkCacheDiskConsumption(usage) {
-    cacheUsageGetter._promise = null;
-    cacheUsageGetter._resolve(usage);
-  },
-  QueryInterface: XPCOMUtils.generateQI([
-    Components.interfaces.nsICacheStorageConsumptionObserver,
-    Components.interfaces.nsISupportsWeakReference
-  ]),
-};
-
-function promiseCookiesCleared() {
-  return TestUtils.topicObserved("cookie-changed", (subj, data) => {
-    return data === "cleared";
-  });
-}
-
-async function loadServiceWorkerTestPage(url) {
-  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
-  await BrowserTestUtils.waitForCondition(() => {
-    return ContentTask.spawn(tab.linkedBrowser, {}, () =>
-      content.document.body.getAttribute("data-test-service-worker-registered") === "true");
-  }, `Fail to load service worker test ${url}`);
-  await BrowserTestUtils.removeTab(tab);
-}
-
-function promiseServiceWorkerRegisteredFor(url) {
-  return BrowserTestUtils.waitForCondition(() => {
-    try {
-      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(url);
-      let sw = serviceWorkerManager.getRegistrationByPrincipal(principal, principal.URI.spec);
-      if (sw) {
-        ok(true, `Found the service worker registered for ${url}`);
-        return true;
-      }
-    } catch (e) {}
-    return false;
-  }, `Should register service worker for ${url}`);
-}
-
-function promiseServiceWorkersCleared() {
-  return BrowserTestUtils.waitForCondition(() => {
-    let serviceWorkers = serviceWorkerManager.getAllRegistrations();
-    if (serviceWorkers.length == 0) {
-      ok(true, "Cleared all service workers");
-      return true;
-    }
-    return false;
-  }, "Should clear all service workers");
-}
-
-registerCleanupFunction(function() {
-  delete window.sinon;
-  mockOfflineAppCacheHelper.unregister();
-});
-
 // Test listing site using quota usage or site using appcache
 add_task(async function() {
   await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
 
   // Open a test site which would save into appcache
   await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_OFFLINE_URL);
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
   // Open a test site which would save into quota manager
-  await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL);
-  // eslint-disable-next-line mozilla/no-cpows-in-tests
-  await waitForEvent(gBrowser.selectedBrowser.contentWindowAsCPOW, "test-indexedDB-done");
+  BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL);
+  await BrowserTestUtils.waitForContentEvent(
+    gBrowser.selectedBrowser, "test-indexedDB-done", false, null, true);
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 
   let updatedPromise = promiseSiteDataManagerSitesUpdated();
   await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   await updatedPromise;
   await openSiteDataSettingsDialog();
   // eslint-disable-next-line mozilla/no-cpows-in-tests
   let dialog = content.gSubDialog._topDialog;
@@ -212,107 +105,16 @@ add_task(async function() {
                          expected = prefStrBundle.getFormattedString(
                            "totalSiteDataSize", DownloadUtils.convertByteUnits(usage));
                           is(actual, expected, "Should show the right total site data size");
                        });
 
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
 
-// Test the function of the "Clear All Data" button
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  addPersistentStoragePerm(TEST_QUOTA_USAGE_ORIGIN);
-
-  await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL);
-  // eslint-disable-next-line mozilla/no-cpows-in-tests
-  await waitForEvent(gBrowser.selectedBrowser.contentWindowAsCPOW, "test-indexedDB-done");
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-
-  // Test the initial states
-  let cacheUsage = await cacheUsageGetter.get();
-  let quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
-  let totalUsage = await SiteDataManager.getTotalUsage();
-  Assert.greater(cacheUsage, 0, "The cache usage should not be 0");
-  Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
-  Assert.greater(totalUsage, 0, "The total usage should not be 0");
-
-  // Test cancelling "Clear All Data"
-  // Click "Clear All Data" button and then cancel
-  let doc = gBrowser.selectedBrowser.contentDocument;
-  let cancelPromise = promiseAlertDialogOpen("cancel");
-  let clearBtn = doc.getElementById("clearSiteDataButton");
-  clearBtn.doCommand();
-  await cancelPromise;
-
-  // Test the items are not removed
-  let status = getPersistentStoragePermStatus(TEST_QUOTA_USAGE_ORIGIN);
-  is(status, Ci.nsIPermissionManager.ALLOW_ACTION, "Should not remove permission");
-
-  cacheUsage = await cacheUsageGetter.get();
-  quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
-  totalUsage = await SiteDataManager.getTotalUsage();
-  Assert.greater(cacheUsage, 0, "The cache usage should not be 0");
-  Assert.greater(quotaUsage, 0, "The quota usage should not be 0");
-  Assert.greater(totalUsage, 0, "The total usage should not be 0");
-  // Test cancelling "Clear All Data" ends
-
-  // Test accepting "Clear All Data"
-  // Click "Clear All Data" button and then accept
-  let acceptPromise = promiseAlertDialogOpen("accept");
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
-  let cookiesClearedPromise = promiseCookiesCleared();
-
-  mockOfflineAppCacheHelper.register();
-  clearBtn.doCommand();
-  await acceptPromise;
-  await updatePromise;
-  mockOfflineAppCacheHelper.unregister();
-
-  // Test all the items are removed
-  await cookiesClearedPromise;
-
-  ok(mockOfflineAppCacheHelper.clear.calledOnce, "Should clear app cache");
-
-  status = getPersistentStoragePermStatus(TEST_QUOTA_USAGE_ORIGIN);
-  is(status, Ci.nsIPermissionManager.UNKNOWN_ACTION, "Should remove permission");
-
-  cacheUsage = await cacheUsageGetter.get();
-  quotaUsage = await getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN);
-  totalUsage = await SiteDataManager.getTotalUsage();
-  is(cacheUsage, 0, "The cache usage should be removed");
-  is(quotaUsage, 0, "The quota usage should be removed");
-  is(totalUsage, 0, "The total usage should be removed");
-  // Test accepting "Clear All Data" ends
-
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
-// Test clearing service wroker through the "Clear All" button
-add_task(async function() {
-  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
-  // Register a test service
-  await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
-  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  // Test the initial states
-  await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
-  // Click the "Clear All" button
-  let doc = gBrowser.selectedBrowser.contentDocument;
-  let clearBtn = doc.getElementById("clearSiteDataButton");
-  let acceptPromise = promiseAlertDialogOpen("accept");
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
-  clearBtn.doCommand();
-  await acceptPromise;
-  await updatePromise;
-  await promiseServiceWorkersCleared();
-  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
-});
-
 // Test clearing service wroker through the settings panel
 add_task(async function() {
   await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
   // Register a test service worker
   await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
   await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   // Test the initial states
   await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
--- a/browser/components/preferences/in-content/tests/head.js
+++ b/browser/components/preferences/in-content/tests/head.js
@@ -1,13 +1,15 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 ChromeUtils.import("resource://gre/modules/Promise.jsm", this);
 
+XPCOMUtils.defineLazyServiceGetter(this, "serviceWorkerManager", "@mozilla.org/serviceworkers/manager;1", "nsIServiceWorkerManager");
+
 const kDefaultWait = 2000;
 
 function is_hidden(aElement) {
   var style = aElement.ownerGlobal.getComputedStyle(aElement);
   if (style.display == "none")
     return true;
   if (style.visibility != "visible")
     return true;
@@ -158,22 +160,16 @@ function promiseWindowDialogOpen(buttonA
     });
   });
 }
 
 function promiseAlertDialogOpen(buttonAction) {
   return promiseWindowDialogOpen(buttonAction, "chrome://global/content/commonDialog.xul");
 }
 
-function addPersistentStoragePerm(origin) {
-  let uri = NetUtil.newURI(origin);
-  let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
-  Services.perms.addFromPrincipal(principal, "persistent-storage", Ci.nsIPermissionManager.ALLOW_ACTION);
-}
-
 function promiseSiteDataManagerSitesUpdated() {
   return TestUtils.topicObserved("sitedatamanager:sites-updated", () => true);
 }
 
 function openSiteDataSettingsDialog() {
   let doc = gBrowser.selectedBrowser.contentDocument;
   let settingsBtn = doc.getElementById("siteDataSettings");
   let dialogOverlay = content.gSubDialog._preloadDialog._overlay;
@@ -254,8 +250,57 @@ const mockSiteDataManager = {
     this.fakeSites = null;
   },
 
   unregister() {
     this._SiteDataManager._qms = this._originalQMS;
     this._SiteDataManager._removeQuotaUsage = this._originalRemoveQuotaUsage;
   }
 };
+
+function getQuotaUsage(origin) {
+  return new Promise(resolve => {
+    let uri = NetUtil.newURI(origin);
+    let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
+    Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
+  });
+}
+
+function promiseCookiesCleared() {
+  return TestUtils.topicObserved("cookie-changed", (subj, data) => {
+    return data === "cleared";
+  });
+}
+
+async function loadServiceWorkerTestPage(url) {
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+  await BrowserTestUtils.waitForCondition(() => {
+    return ContentTask.spawn(tab.linkedBrowser, {}, () =>
+      content.document.body.getAttribute("data-test-service-worker-registered") === "true");
+  }, `Fail to load service worker test ${url}`);
+  await BrowserTestUtils.removeTab(tab);
+}
+
+function promiseServiceWorkersCleared() {
+  return BrowserTestUtils.waitForCondition(() => {
+    let serviceWorkers = serviceWorkerManager.getAllRegistrations();
+    if (serviceWorkers.length == 0) {
+      ok(true, "Cleared all service workers");
+      return true;
+    }
+    return false;
+  }, "Should clear all service workers");
+}
+
+function promiseServiceWorkerRegisteredFor(url) {
+  return BrowserTestUtils.waitForCondition(() => {
+    try {
+      let principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(url);
+      let sw = serviceWorkerManager.getRegistrationByPrincipal(principal, principal.URI.spec);
+      if (sw) {
+        ok(true, `Found the service worker registered for ${url}`);
+        return true;
+      }
+    } catch (e) {}
+    return false;
+  }, `Should register service worker for ${url}`);
+}
+
--- a/browser/components/preferences/in-content/tests/site_data_test.html
+++ b/browser/components/preferences/in-content/tests/site_data_test.html
@@ -16,14 +16,14 @@
       request.onupgradeneeded = function(e) {
         let db = e.target.result;
         db.createObjectStore("TestStore", { keyPath: "id" });
       };
       request.onsuccess = function(e) {
         let db = e.target.result;
         let tx = db.transaction("TestStore", "readwrite");
         let store = tx.objectStore("TestStore");
-        tx.oncomplete = () => window.dispatchEvent(new Event("test-indexedDB-done"));
+        tx.oncomplete = () => document.dispatchEvent(new CustomEvent("test-indexedDB-done", {bubbles: true, cancelable: false}));
         store.put({ id: "test_id", description: "Site Data Test"});
       };
     </script>
   </body>
 </html>