Bug 1410416 - Part 2 - Add test cases about removing service workers, r?baku draft
authorFischer.json <fischer.json@gmail.com>
Wed, 01 Nov 2017 13:43:58 +0800
changeset 693284 545f710bc4d420594c1c0a6131fd02d3a7827136
parent 693283 a7f1520e1dc96d1175f50ef9077012c23bd9c036
child 738982 19e357f8634045b74383c77dd14f25ac1714fdf7
push id87743
push userbmo:fliu@mozilla.com
push dateSun, 05 Nov 2017 05:32:00 +0000
reviewersbaku
bugs1410416
milestone58.0a1
Bug 1410416 - Part 2 - Add test cases about removing service workers, r?baku MozReview-Commit-ID: 6MeilGCkomc
browser/components/preferences/in-content/tests/browser.ini
browser/components/preferences/in-content/tests/browser_siteData.js
browser/components/preferences/in-content/tests/browser_siteData3.js
browser/components/preferences/in-content/tests/head.js
browser/components/preferences/in-content/tests/service_worker_test.html
browser/components/preferences/in-content/tests/service_worker_test.js
--- a/browser/components/preferences/in-content/tests/browser.ini
+++ b/browser/components/preferences/in-content/tests/browser.ini
@@ -1,13 +1,15 @@
 [DEFAULT]
 support-files =
   head.js
   privacypane_tests_perwindow.js
   site_data_test.html
+  service_worker_test.html
+  service_worker_test.js
   addons/set_homepage.xpi
   addons/set_newtab.xpi
   offline/offline.html
   offline/manifest.appcache
 
 [browser_applications_selection.js]
 skip-if = os == 'linux' # bug 1382057
 [browser_advanced_update.js]
--- a/browser/components/preferences/in-content/tests/browser_siteData.js
+++ b/browser/components/preferences/in-content/tests/browser_siteData.js
@@ -10,23 +10,26 @@ Cu.import("resource://gre/modules/XPCOMU
 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 } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
 const { DownloadUtils } = Cu.import("resource://gre/modules/DownloadUtils.jsm", {});
 const { SiteDataManager } = Cu.import("resource:///modules/SiteDataManager.jsm", {});
 const { OfflineAppCacheHelper } = Cu.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();
@@ -82,16 +85,50 @@ const cacheUsageGetter = {
 };
 
 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]]});
@@ -245,125 +282,60 @@ add_task(async function() {
   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 sorting
+// 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]]});
-  mockSiteDataManager.register(SiteDataManager);
-  mockSiteDataManager.fakeSites = [
-    {
-      usage: 1024,
-      principal: Services.scriptSecurityManager
-                         .createCodebasePrincipalFromOrigin("https://account.xyz.com"),
-      persisted: true
-    },
-    {
-      usage: 1024 * 2,
-      principal: Services.scriptSecurityManager
-                         .createCodebasePrincipalFromOrigin("https://books.foo.com"),
-      persisted: false
-    },
-    {
-      usage: 1024 * 3,
-      principal: Services.scriptSecurityManager
-                         .createCodebasePrincipalFromOrigin("http://cinema.bar.com"),
-      persisted: true
-    },
-  ];
-
-  let updatePromise = promiseSiteDataManagerSitesUpdated();
+  // Register a test service worker
+  await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL);
   await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
-  await updatePromise;
+  // Test the initial states
+  await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL);
+  // Open the Site Data Settings panel and remove the site
   await openSiteDataSettingsDialog();
-
-  let dialog = content.gSubDialog._topDialog;
-  let dialogFrame = dialog._frame;
-  let frameDoc = dialogFrame.contentDocument;
-  let hostCol = frameDoc.getElementById("hostCol");
-  let usageCol = frameDoc.getElementById("usageCol");
-  let statusCol = frameDoc.getElementById("statusCol");
-  let sitesList = frameDoc.getElementById("sitesList");
-
-  // Test default sorting
-  assertSortByUsage("descending");
-
-  // Test sorting on the usage column
-  usageCol.click();
-  assertSortByUsage("ascending");
-  usageCol.click();
-  assertSortByUsage("descending");
-
-  // Test sorting on the host column
-  hostCol.click();
-  assertSortByHost("ascending");
-  hostCol.click();
-  assertSortByHost("descending");
-
-  // Test sorting on the permission status column
-  statusCol.click();
-  assertSortByStatus("ascending");
-  statusCol.click();
-  assertSortByStatus("descending");
-
-  mockSiteDataManager.unregister();
+  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);
-
-  function assertSortByHost(order) {
-    let siteItems = sitesList.getElementsByTagName("richlistitem");
-    for (let i = 0; i < siteItems.length - 1; ++i) {
-      let aHost = siteItems[i].getAttribute("host");
-      let bHost = siteItems[i + 1].getAttribute("host");
-      let result = aHost.localeCompare(bHost);
-      if (order == "ascending") {
-        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by host");
-      } else {
-        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by host");
-      }
-    }
-  }
-
-  function assertSortByStatus(order) {
-    let siteItems = sitesList.getElementsByTagName("richlistitem");
-    for (let i = 0; i < siteItems.length - 1; ++i) {
-      let aHost = siteItems[i].getAttribute("host");
-      let bHost = siteItems[i + 1].getAttribute("host");
-      let a = findSiteByHost(aHost);
-      let b = findSiteByHost(bHost);
-      let result = 0;
-      if (a.persisted && !b.persisted) {
-        result = 1;
-      } else if (!a.persisted && b.persisted) {
-        result = -1;
-      }
-      if (order == "ascending") {
-        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by permission status");
-      } else {
-        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by permission status");
-      }
-    }
-  }
-
-  function assertSortByUsage(order) {
-    let siteItems = sitesList.getElementsByTagName("richlistitem");
-    for (let i = 0; i < siteItems.length - 1; ++i) {
-      let aHost = siteItems[i].getAttribute("host");
-      let bHost = siteItems[i + 1].getAttribute("host");
-      let a = findSiteByHost(aHost);
-      let b = findSiteByHost(bHost);
-      let result = a.usage - b.usage;
-      if (order == "ascending") {
-        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by usage");
-      } else {
-        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by usage");
-      }
-    }
-  }
-
-  function findSiteByHost(host) {
-    return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
-  }
 });
--- a/browser/components/preferences/in-content/tests/browser_siteData3.js
+++ b/browser/components/preferences/in-content/tests/browser_siteData3.js
@@ -101,8 +101,126 @@ add_task(async function() {
 
   expected = prefStrBundle.getString("persistent");
   let status = siteItems[0].getAttribute("status");
   is(status, expected, "Should mark persisted status across scheme, port and origin attributes");
 
   mockSiteDataManager.unregister();
   await BrowserTestUtils.removeTab(gBrowser.selectedTab);
 });
+
+// Test sorting
+add_task(async function() {
+  await SpecialPowers.pushPrefEnv({set: [["browser.storageManager.enabled", true]]});
+  mockSiteDataManager.register(SiteDataManager);
+  mockSiteDataManager.fakeSites = [
+    {
+      usage: 1024,
+      principal: Services.scriptSecurityManager
+                         .createCodebasePrincipalFromOrigin("https://account.xyz.com"),
+      persisted: true
+    },
+    {
+      usage: 1024 * 2,
+      principal: Services.scriptSecurityManager
+                         .createCodebasePrincipalFromOrigin("https://books.foo.com"),
+      persisted: false
+    },
+    {
+      usage: 1024 * 3,
+      principal: Services.scriptSecurityManager
+                         .createCodebasePrincipalFromOrigin("http://cinema.bar.com"),
+      persisted: true
+    },
+  ];
+
+  let updatePromise = promiseSiteDataManagerSitesUpdated();
+  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
+  await updatePromise;
+  await openSiteDataSettingsDialog();
+
+  let dialog = content.gSubDialog._topDialog;
+  let dialogFrame = dialog._frame;
+  let frameDoc = dialogFrame.contentDocument;
+  let hostCol = frameDoc.getElementById("hostCol");
+  let usageCol = frameDoc.getElementById("usageCol");
+  let statusCol = frameDoc.getElementById("statusCol");
+  let sitesList = frameDoc.getElementById("sitesList");
+
+  // Test default sorting
+  assertSortByUsage("descending");
+
+  // Test sorting on the usage column
+  usageCol.click();
+  assertSortByUsage("ascending");
+  usageCol.click();
+  assertSortByUsage("descending");
+
+  // Test sorting on the host column
+  hostCol.click();
+  assertSortByHost("ascending");
+  hostCol.click();
+  assertSortByHost("descending");
+
+  // Test sorting on the permission status column
+  statusCol.click();
+  assertSortByStatus("ascending");
+  statusCol.click();
+  assertSortByStatus("descending");
+
+  mockSiteDataManager.unregister();
+  await BrowserTestUtils.removeTab(gBrowser.selectedTab);
+
+  function assertSortByHost(order) {
+    let siteItems = sitesList.getElementsByTagName("richlistitem");
+    for (let i = 0; i < siteItems.length - 1; ++i) {
+      let aHost = siteItems[i].getAttribute("host");
+      let bHost = siteItems[i + 1].getAttribute("host");
+      let result = aHost.localeCompare(bHost);
+      if (order == "ascending") {
+        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by host");
+      } else {
+        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by host");
+      }
+    }
+  }
+
+  function assertSortByStatus(order) {
+    let siteItems = sitesList.getElementsByTagName("richlistitem");
+    for (let i = 0; i < siteItems.length - 1; ++i) {
+      let aHost = siteItems[i].getAttribute("host");
+      let bHost = siteItems[i + 1].getAttribute("host");
+      let a = findSiteByHost(aHost);
+      let b = findSiteByHost(bHost);
+      let result = 0;
+      if (a.persisted && !b.persisted) {
+        result = 1;
+      } else if (!a.persisted && b.persisted) {
+        result = -1;
+      }
+      if (order == "ascending") {
+        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by permission status");
+      } else {
+        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by permission status");
+      }
+    }
+  }
+
+  function assertSortByUsage(order) {
+    let siteItems = sitesList.getElementsByTagName("richlistitem");
+    for (let i = 0; i < siteItems.length - 1; ++i) {
+      let aHost = siteItems[i].getAttribute("host");
+      let bHost = siteItems[i + 1].getAttribute("host");
+      let a = findSiteByHost(aHost);
+      let b = findSiteByHost(bHost);
+      let result = a.usage - b.usage;
+      if (order == "ascending") {
+        Assert.lessOrEqual(result, 0, "Should sort sites in the ascending order by usage");
+      } else {
+        Assert.greaterOrEqual(result, 0, "Should sort sites in the descending order by usage");
+      }
+    }
+  }
+
+  function findSiteByHost(host) {
+    return mockSiteDataManager.fakeSites.find(site => site.principal.URI.host == host);
+  }
+});
--- a/browser/components/preferences/in-content/tests/head.js
+++ b/browser/components/preferences/in-content/tests/head.js
@@ -249,17 +249,17 @@ const mockSiteDataManager = {
   _originalRemoveQuotaUsage: null,
 
   getUsage(onUsageResult) {
     let result = this.fakeSites.map(site => ({
       origin: site.principal.origin,
       usage: site.usage,
       persisted: site.persisted
     }));
-    onUsageResult({ result });
+    onUsageResult({ result, resultCode: Components.results.NS_OK });
   },
 
   _removeQuotaUsage(site) {
     var target = site.principals[0].URI.host;
     this.fakeSites = this.fakeSites.filter(fakeSite => {
       return fakeSite.principal.URI.host != target;
     });
   },
new file mode 100755
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/service_worker_test.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta http-equiv="Cache-Control" content="public" />
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
+
+    <title>Service Worker Test</title>
+
+  </head>
+
+  <body>
+    <h1>Service Worker Test</h1>
+    <script type="text/javascript">
+      navigator.serviceWorker.register("service_worker_test.js")
+               .then(regis => document.body.setAttribute("data-test-service-worker-registered", "true"));
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/preferences/in-content/tests/service_worker_test.js
@@ -0,0 +1,1 @@
+// empty worker, always succeed!