Bug 1499995 - part 3 - Tests for nested iframes controlled by ServiceWorkers, r=ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Thu, 25 Oct 2018 10:44:12 +0200
changeset 491257 2393a7d9f454e3d5fc310c5ee4a1cd94fea42ab2
parent 491256 ccd2e78000b8645cca3f3d028140e0b461ddc6be
child 491258 5e6bc808c1d7bae1b7c63a257399820c67081c2c
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersehsan
bugs1499995
milestone65.0a1
Bug 1499995 - part 3 - Tests for nested iframes controlled by ServiceWorkers, r=ehsan
dom/serviceworkers/test/browser.ini
dom/serviceworkers/test/browser_antitracking.js
dom/serviceworkers/test/browser_antitracking_subiframes.js
dom/serviceworkers/test/page_post_controlled.html
dom/serviceworkers/test/utils.js
--- a/dom/serviceworkers/test/browser.ini
+++ b/dom/serviceworkers/test/browser.ini
@@ -13,16 +13,17 @@ support-files =
   empty.html
   empty_with_utils.html
   empty.js
   page_post_controlled.html
   storage_recovery_worker.sjs
   utils.js
 
 [browser_antitracking.js]
+[browser_antitracking_subiframes.js]
 [browser_devtools_serviceworker_interception.js]
 skip-if = serviceworker_e10s
 [browser_force_refresh.js]
 [browser_download.js]
 [browser_download_canceled.js]
 skip-if = verify
 [browser_storage_permission.js]
 skip-if = (verify && debug && (os == 'win' || os == 'mac'))
--- a/dom/serviceworkers/test/browser_antitracking.js
+++ b/dom/serviceworkers/test/browser_antitracking.js
@@ -27,77 +27,71 @@ const SW_REL_SW_SCRIPT = "empty.js";
 add_task(async function() {
   await SpecialPowers.pushPrefEnv({'set': [
     ['dom.serviceWorkers.enabled', true],
     ['dom.serviceWorkers.exemptFromPerDomainMax', true],
     ['dom.serviceWorkers.testing.enabled', true],
     ['network.cookie.cookieBehavior', BEHAVIOR_ACCEPT],
   ]});
 
+  // Open the top-level page.
+  info("Opening a new tab: " + SW_REGISTER_PAGE);
+  let topTab = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: SW_REGISTER_PAGE
+  });
+
   // ## Install SW
   info("Installing SW");
-  await BrowserTestUtils.withNewTab(
-    {
-      gBrowser,
-      url: SW_REGISTER_PAGE
-    },
-    async function(linkedBrowser) {
-      await ContentTask.spawn(
-        linkedBrowser,
-        { sw: SW_REL_SW_SCRIPT },
-        async function({ sw }) {
-          // Waive the xray to use the content utils.js script functions.
-          await content.wrappedJSObject.registerAndWaitForActive(sw);
-        }
-      );
+  await ContentTask.spawn(
+    topTab.linkedBrowser,
+    { sw: SW_REL_SW_SCRIPT },
+    async function({ sw }) {
+      // Waive the xray to use the content utils.js script functions.
+      await content.wrappedJSObject.registerAndWaitForActive(sw);
     }
   );
 
   // Enable Anti-tracking.
   await SpecialPowers.pushPrefEnv({'set': [
     ['privacy.trackingprotection.enabled', false],
     ["privacy.trackingprotection.pbmode.enabled", false],
     ["privacy.trackingprotection.annotate_channels", true],
     ['network.cookie.cookieBehavior', BEHAVIOR_REJECT_TRACKER],
   ]});
   await UrlClassifierTestUtils.addTestTrackers();
 
-  // Open the top-level page.
-  info("Open top-level page");
-  let topTab = await BrowserTestUtils.openNewForegroundTab({
-    gBrowser,
-    opening: TOP_EMPTY_PAGE
-  });
+  // Open the top-level URL.
+  info("Loading a new top-level URL: " + TOP_EMPTY_PAGE);
+  let browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser);
+  await BrowserTestUtils.loadURI(topTab.linkedBrowser, TOP_EMPTY_PAGE);
+  await browserLoadedPromise;
 
   // Create Iframe in the top-level page and verify its state.
   let { controlled } = await ContentTask.spawn(
     topTab.linkedBrowser,
     { url: SW_IFRAME_PAGE },
     async function ({ url }) {
       const payload =
         await content.wrappedJSObject.createIframeAndWaitForMessage(url);
       return payload;
     }
   );
 
   ok(!controlled, "Should not be controlled!");
 
   // ## Cleanup
+  info("Loading the SW unregister page: " + SW_REGISTER_PAGE);
+  browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser);
+  await BrowserTestUtils.loadURI(topTab.linkedBrowser, SW_REGISTER_PAGE);
+  await browserLoadedPromise;
+
+  await ContentTask.spawn(
+    topTab.linkedBrowser,
+    null,
+    async function() {
+      await content.wrappedJSObject.unregisterAll();
+    }
+  );
+
   // Close the testing tab.
   BrowserTestUtils.removeTab(topTab);
-  // Unregister the SW we registered for the tracking protection origin.
-  await BrowserTestUtils.withNewTab(
-    {
-      gBrowser,
-      url: SW_REGISTER_PAGE
-    },
-    async function(linkedBrowser) {
-      await ContentTask.spawn(
-        linkedBrowser,
-        {},
-        async function() {
-          // Waive the xray to use the content utils.js script functions.
-          await content.wrappedJSObject.unregisterAll();
-        }
-      );
-    }
-  );
 });
new file mode 100644
--- /dev/null
+++ b/dom/serviceworkers/test/browser_antitracking_subiframes.js
@@ -0,0 +1,99 @@
+const BEHAVIOR_REJECT_TRACKER = Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER;
+
+const TOP_DOMAIN = "http://mochi.test:8888/";
+const SW_DOMAIN = "https://example.org/";
+
+const TOP_TEST_ROOT = getRootDirectory(gTestPath)
+  .replace("chrome://mochitests/content/", TOP_DOMAIN);
+const SW_TEST_ROOT = getRootDirectory(gTestPath)
+  .replace("chrome://mochitests/content/", SW_DOMAIN);
+
+const TOP_EMPTY_PAGE = `${TOP_TEST_ROOT}empty_with_utils.html`;
+const SW_REGISTER_PAGE = `${SW_TEST_ROOT}empty_with_utils.html`;
+const SW_IFRAME_PAGE = `${SW_TEST_ROOT}page_post_controlled.html`;
+const SW_REL_SW_SCRIPT = "empty.js";
+
+/**
+ * Set up a ServiceWorker on a domain that will be used as 3rd party iframe.
+ * That 3rd party frame should be controlled by the ServiceWorker.
+ * After that, we open a second iframe into the first one. That should not be
+ * controlled.
+ */
+add_task(async function() {
+  await SpecialPowers.pushPrefEnv({'set': [
+    ['dom.serviceWorkers.enabled', true],
+    ['dom.serviceWorkers.exemptFromPerDomainMax', true],
+    ['dom.serviceWorkers.testing.enabled', true],
+    ['network.cookie.cookieBehavior', BEHAVIOR_REJECT_TRACKER],
+  ]});
+
+  // Open the top-level page.
+  info("Opening a new tab: " + SW_REGISTER_PAGE);
+  let topTab = await BrowserTestUtils.openNewForegroundTab({
+    gBrowser,
+    opening: SW_REGISTER_PAGE
+  });
+
+  // Install SW
+  info("Registering a SW: " + SW_REL_SW_SCRIPT);
+  await ContentTask.spawn(
+    topTab.linkedBrowser,
+    { sw: SW_REL_SW_SCRIPT },
+    async function({ sw }) {
+      // Waive the xray to use the content utils.js script functions.
+      await content.wrappedJSObject.registerAndWaitForActive(sw);
+      // User interaction
+      content.document.userInteractionForTesting();
+    }
+  );
+
+  info("Loading a new top-level URL: " + TOP_EMPTY_PAGE);
+  let browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser);
+  await BrowserTestUtils.loadURI(topTab.linkedBrowser, TOP_EMPTY_PAGE);
+  await browserLoadedPromise;
+
+  // Create Iframe in the top-level page and verify its state.
+  info("Creating iframe and checking if controlled");
+  let { controlled } = await ContentTask.spawn(
+    topTab.linkedBrowser,
+    { url: SW_IFRAME_PAGE },
+    async function ({ url }) {
+      content.document.userInteractionForTesting();
+      const payload =
+        await content.wrappedJSObject.createIframeAndWaitForMessage(url);
+      return payload;
+    }
+  );
+
+  ok(controlled, "Should be controlled!");
+
+  // Create a nested Iframe.
+  info("Creating nested-iframe and checking if controlled");
+  let { nested_controlled } = await ContentTask.spawn(
+    topTab.linkedBrowser,
+    { url: SW_IFRAME_PAGE },
+    async function ({ url }) {
+      const payload =
+        await content.wrappedJSObject.createNestedIframeAndWaitForMessage(url);
+      return payload;
+    }
+  );
+
+  ok(!nested_controlled, "Should not be controlled!");
+
+  info("Loading the SW unregister page: " + SW_REGISTER_PAGE);
+  browserLoadedPromise = BrowserTestUtils.browserLoaded(topTab.linkedBrowser);
+  await BrowserTestUtils.loadURI(topTab.linkedBrowser, SW_REGISTER_PAGE);
+  await browserLoadedPromise;
+
+  await ContentTask.spawn(
+    topTab.linkedBrowser,
+    null,
+    async function() {
+      await content.wrappedJSObject.unregisterAll();
+    }
+  );
+
+  // Close the testing tab.
+  BrowserTestUtils.removeTab(topTab);
+});
--- a/dom/serviceworkers/test/page_post_controlled.html
+++ b/dom/serviceworkers/test/page_post_controlled.html
@@ -7,11 +7,21 @@
 <head>
   <meta charset="utf-8">
 </head>
 <body>
 <script type="text/javascript">
   window.parent.postMessage({
     controlled: !!navigator.serviceWorker.controller
   }, "*");
+
+  addEventListener("message", e => {
+    if (e.data == "create nested iframe") {
+      const iframe = document.createElement('iframe');
+      document.body.appendChild(iframe);
+      iframe.src = location.href;
+    } else {
+      window.parent.postMessage(e.data, "*");
+    }
+  });
 </script>
 </body>
 </html>
--- a/dom/serviceworkers/test/utils.js
+++ b/dom/serviceworkers/test/utils.js
@@ -56,14 +56,32 @@ function createIframeAndWaitForMessage(u
     window.addEventListener(
       'message',
       (event) => { resolve(event.data); },
       { once: true });
     iframe.src = url;
   });
 }
 
+/**
+ * Helper to create a nested iframe into the iframe created by
+ * createIframeAndWaitForMessage().
+ *
+ * A promise will be returned that resolves with the payload of the postMessage
+ * call.
+ */
+function createNestedIframeAndWaitForMessage(url) {
+  const iframe = document.getElementsByTagName('iframe')[0];
+  iframe.contentWindow.postMessage("create nested iframe", "*");
+  return new Promise((resolve) => {
+    window.addEventListener(
+      'message',
+      (event) => { resolve(event.data); },
+      { once: true });
+  });
+}
+
 async function unregisterAll() {
   const registrations = await navigator.serviceWorker.getRegistrations();
   for (const reg of registrations) {
     await reg.unregister();
   }
 }