Bug 1379148: Part 4 - Add tests for document.write() with document_start content script present. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 20 Sep 2017 17:01:33 -0700
changeset 667978 5bee303b5e28ab7c496d2e4b22a071ae7e5606d6
parent 667977 502a142bccef8f9237b2639d6566a5d8458a5d3f
child 732569 f3f9b1e4c89056d5316b3fda4b6f4e1fc79c1a9a
push id80907
push usermaglione.k@gmail.com
push dateThu, 21 Sep 2017 00:03:55 +0000
reviewersmixedpuppy
bugs1379148
milestone57.0a1
Bug 1379148: Part 4 - Add tests for document.write() with document_start content script present. r?mixedpuppy MozReview-Commit-ID: 5yxgpur1tvf
toolkit/components/extensions/ExtensionXPCShellUtils.jsm
toolkit/components/extensions/test/xpcshell/data/file_document_write.html
toolkit/components/extensions/test/xpcshell/test_ext_contentscript_scriptCreated.js
toolkit/components/extensions/test/xpcshell/xpcshell-content.ini
--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -54,16 +54,21 @@ let BASE_MANIFEST = Object.freeze({
   "version": "0",
 });
 
 
 function frameScript() {
   Components.utils.import("resource://gre/modules/Services.jsm");
 
   Services.obs.notifyObservers(this, "tab-content-frameloader-created");
+
+  // eslint-disable-next-line mozilla/balanced-listeners
+  addEventListener("MozHeapMinimize", () => {
+    Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
+  }, true, true);
 }
 
 const FRAME_SCRIPT = `data:text/javascript,(${encodeURI(frameScript)}).call(this)`;
 
 let kungFuDeathGrip = new Set();
 function promiseBrowserLoaded(browser, url, redirectUrl) {
   return new Promise(resolve => {
     const listener = {
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/data/file_document_write.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+</head>
+<body>
+  <iframe id="iframe"></iframe>
+
+  <script type="text/javascript">
+    "use strict";
+    addEventListener("load", () => {
+      // Send a heap-minimize observer notification so our script cache is
+      // cleared, and our content script isn't available for synchronous
+      // insertion.
+      window.dispatchEvent(new CustomEvent("MozHeapMinimize"));
+
+      let iframe = document.getElementById("iframe");
+      let doc = iframe.contentDocument;
+      doc.open("text/html");
+      // We need to do two writes here. The first creates the document element,
+      // which normally triggers parser blocking. The second triggers the
+      // creation of the element we're about to query for, which would normally
+      // happen asynchronously if the parser were blocked.
+      doc.write("<div id=meh>");
+      doc.write("<div id=beer></div>");
+
+      let elem = doc.getElementById("beer");
+      top.postMessage(elem instanceof HTMLDivElement ? "ok" : "fail",
+                      "*");
+
+      doc.close();
+    }, {once: true});
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_contentscript_scriptCreated.js
@@ -0,0 +1,49 @@
+"use strict";
+
+const server = createHttpServer();
+server.registerDirectory("/data/", do_get_file("data"));
+
+const BASE_URL = `http://localhost:${server.identity.primaryPort}/data`;
+
+// ExtensionContent.jsm needs to know when it's running from xpcshell,
+// to use the right timeout for content scripts executed at document_idle.
+ExtensionTestUtils.mockAppInfo();
+
+// Test that document_start content scripts don't block script-created
+// parsers.
+add_task(async function test_contentscript_scriptCreated() {
+  let extensionData = {
+    manifest: {
+      content_scripts: [{
+        "matches": ["http://*/*/file_document_write.html"],
+        "js": ["content_script.js"],
+        "run_at": "document_start",
+        "match_about_blank": true,
+        "all_frames": true,
+      }],
+    },
+
+    files: {
+      "content_script.js": function() {
+        if (window === top) {
+          addEventListener("message", msg => {
+            browser.test.assertEq("ok", msg.data, "document.write() succeeded");
+            browser.test.sendMessage("content-script-done");
+          }, {once: true});
+        }
+      },
+    },
+  };
+
+  let extension = ExtensionTestUtils.loadExtension(extensionData);
+
+  await extension.startup();
+
+  let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_document_write.html`);
+
+  await extension.awaitMessage("content-script-done");
+
+  await contentPage.close();
+
+  await extension.unload();
+});
--- a/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini
+++ b/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini
@@ -1,5 +1,6 @@
 [test_ext_i18n.js]
 skip-if = os == "android" || (os == "win" && debug)
 [test_ext_i18n_css.js]
 [test_ext_contentscript.js]
+[test_ext_contentscript_scriptCreated.js]
 [test_ext_contentscript_xrays.js]