Bug 1356273: Part 2 - Add tests that document.open()/write() only loads content scripts once. r?aswan draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 03 Aug 2017 15:21:22 -0700
changeset 641028 b5a5fe06d9ee559c17eeab4e711401c0f03fbca1
parent 620783 38ee59c2de1fd21a8fccb04a5036e01f63c7de10
child 724692 32dd26dcab3cab14fef107db1935d9755746ce3a
push id72403
push usermaglione.k@gmail.com
push dateFri, 04 Aug 2017 23:44:46 +0000
reviewersaswan
bugs1356273
milestone57.0a1
Bug 1356273: Part 2 - Add tests that document.open()/write() only loads content scripts once. r?aswan The combination of "match_about_blank": true and "run_at": "document_start" can potentially cause content scripts to run twice for the same document, once for the intermediate about:blank document created by the document.open() call, and again for the same document with its final URL after it's been fully setup. This test ensures that that behavior doesn't regress. MozReview-Commit-ID: 9XSfW3rEL4f
toolkit/components/extensions/test/xpcshell/data/file_document_open.html
toolkit/components/extensions/test/xpcshell/test_ext_contentscript.js
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/data/file_document_open.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+
+  <iframe id="iframe"></iframe>
+
+  <script type="text/javascript">
+    "use strict";
+    addEventListener("load", () => {
+      let iframe = document.getElementById("iframe");
+      let doc = iframe.contentDocument;
+      doc.open("text/html");
+      doc.write("Hello.");
+      doc.close();
+    }, {once: true});
+  </script>
+</body>
+</html>
--- a/toolkit/components/extensions/test/xpcshell/test_ext_contentscript.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript.js
@@ -109,8 +109,64 @@ add_task(async function test_contentscri
   await contentPage.close();
 
   equal(loadingCount, 1, "document_start script ran exactly once");
   equal(interactiveCount, 1, "document_end script ran exactly once");
   equal(completeCount, 2, "document_idle script ran exactly twice");
 
   await extension.unload();
 });
+
+add_task(async function test_contentscript_window_open() {
+  let extension = ExtensionTestUtils.loadExtension({
+    manifest: {
+      applications: {gecko: {id: "contentscript@tests.mozilla.org"}},
+      content_scripts: [
+        {
+          "matches": ["<all_urls>"],
+          "js": ["content_script.js"],
+          "run_at": "document_start",
+          "match_about_blank": true,
+          "all_frames": true,
+        },
+      ],
+    },
+
+    files: {
+      "content_script.js": `
+        var x = (x || 0) + 1;
+        (${async () => {
+          /* globals x */
+          browser.test.assertEq(1, x, "Should only run once");
+
+          if (top !== window) {
+            await new Promise(resolve => setTimeout(resolve, 0));
+          }
+
+          browser.test.sendMessage("content-script", [location.href, top === window]);
+        }})();
+      `,
+    },
+  });
+
+  await extension.startup();
+
+  let url = `${BASE_URL}/file_document_open.html`;
+  let contentPage = await ExtensionTestUtils.loadContentPage(url);
+
+  Assert.deepEqual(await extension.awaitMessage("content-script"),
+                   [url, true]);
+
+  let [frameURL, isTop] = await extension.awaitMessage("content-script");
+  // Sometimes we get a content script load for the initial about:blank
+  // iframe here, sometimes we don't. Either way is fine, as long as we
+  // don't get two loads into the same document.open() document.
+  if (frameURL === "about:blank") {
+    equal(isTop, false);
+
+    [frameURL, isTop] = await extension.awaitMessage("content-script");
+  }
+
+  Assert.deepEqual([frameURL, isTop], [url, false]);
+
+  await contentPage.close();
+  await extension.unload();
+});