Bug 1328501 - Part 2: Add test case. draft
authorSamael Wang <freesamael@gmail.com>
Mon, 11 Sep 2017 18:09:18 +0800
changeset 668182 4ce71b1cd5992e8791b2fd61892b30cbb655e693
parent 664787 b070e99bb84b6ba6a9de3f441588ebf5d6ae2a23
child 732617 d2bfb3f8b86579bec95b28e45a40b4f85ed11a44
push id80956
push userbmo:sawang@mozilla.com
push dateThu, 21 Sep 2017 08:20:43 +0000
bugs1328501
milestone57.0a1
Bug 1328501 - Part 2: Add test case. MozReview-Commit-ID: HpsK5HeHRO0
docshell/test/browser/browser.ini
docshell/test/browser/browser_bug1328501.js
docshell/test/browser/file_bug1328501.html
docshell/test/browser/file_bug1328501_frame.html
docshell/test/browser/file_bug1328501_framescript.js
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -31,30 +31,34 @@ support-files =
   file_bug422543_script.js
   file_bug503832.html
   file_bug655270.html
   file_bug670318.html
   file_bug852909.pdf
   file_bug852909.png
   file_bug1046022.html
   file_bug1206879.html
+  file_bug1328501.html
+  file_bug1328501_frame.html
+  file_bug1328501_framescript.js
   file_multiple_pushState.html
   print_postdata.sjs
   test-form_sjis.html
   timelineMarkers-04.html
   browser_timelineMarkers-frame-02.js
   browser_timelineMarkers-frame-03.js
   browser_timelineMarkers-frame-04.js
   browser_timelineMarkers-frame-05.js
   head.js
   frame-head.js
   file_click_link_within_view_source.html
 
 [browser_bug1206879.js]
 [browser_bug1309900_crossProcessHistoryNavigation.js]
+[browser_bug1328501.js]
 [browser_bug1347823.js]
 [browser_bug134911.js]
 [browser_bug234628-1.js]
 [browser_bug234628-10.js]
 [browser_bug234628-11.js]
 [browser_bug234628-2.js]
 [browser_bug234628-3.js]
 [browser_bug234628-4.js]
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/browser_bug1328501.js
@@ -0,0 +1,38 @@
+const HTML_URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501.html";
+const FRAME_URL = "http://mochi.test:8888/browser/docshell/test/browser/file_bug1328501_frame.html";
+const FRAME_SCRIPT_URL = "chrome://mochitests/content/browser/docshell/test/browser/file_bug1328501_framescript.js";
+add_task(async function testMultiFrameRestore() {
+  await BrowserTestUtils.withNewTab({gBrowser, url: HTML_URL}, async function(browser) {
+    // Navigate 2 subframes and load about:blank.
+    let browserLoaded = BrowserTestUtils.browserLoaded(browser);
+    await ContentTask.spawn(browser, FRAME_URL, async function(FRAME_URL) {
+      function frameLoaded(frame) {
+        frame.contentWindow.location = FRAME_URL;
+        return new Promise(r => frame.onload = r);
+      }
+      let frame1 = content.document.querySelector("#testFrame1");
+      let frame2 = content.document.querySelector("#testFrame2");
+      ok(frame1, "check found testFrame1");
+      ok(frame2, "check found testFrame2");
+      await frameLoaded(frame1);
+      await frameLoaded(frame2);
+      content.location = "dummy_page.html";
+    });
+    await browserLoaded;
+
+    // Load a frame script to query nsIDOMWindow on "http-on-opening-request",
+    // which will force about:blank content viewers being created.
+    browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
+
+    // The frame script also forwards frames-loaded.
+    let framesLoaded = BrowserTestUtils.waitForMessage(browser.messageManager, "test:frames-loaded");
+
+    browser.goBack();
+    await framesLoaded;
+    await new Promise(r => setTimeout(r, 1000));
+    await ContentTask.spawn(browser, FRAME_URL, (FRAME_URL) => {
+      is(content.document.querySelector("#testFrame1").contentWindow.location.href, FRAME_URL);
+      is(content.document.querySelector("#testFrame2").contentWindow.location.href, FRAME_URL);
+    })
+  })
+});
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/file_bug1328501.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Page with iframes</title>
+    <script type="application/javascript">
+    let promiseResolvers = {
+      "testFrame1": {},
+      "testFrame2": {}
+    }
+    let promises = [
+      new Promise(r => promiseResolvers["testFrame1"].resolve = r),
+      new Promise(r => promiseResolvers["testFrame2"].resolve = r)
+    ];
+    function frameLoaded(frame) {
+      dump("Resolving " + frame + "\n");
+      promiseResolvers[frame].resolve();
+    }
+    Promise.all(promises).then(() => window.dispatchEvent(new Event("frames-loaded")));
+    </script>
+  </head>
+  <body onunload="">
+    <div>
+      <iframe id="testFrame1" src="dummy_page.html" onload="frameLoaded(this.id);" ></iframe>
+      <iframe id="testFrame2" src="dummy_page.html" onload="frameLoaded(this.id);" ></iframe>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/file_bug1328501_frame.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<html lang="en">
+  <body>Subframe page for testing</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/file_bug1328501_framescript.js
@@ -0,0 +1,38 @@
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+// Forward iframe loaded event.
+addEventListener("frames-loaded",
+  e => sendAsyncMessage("test:frames-loaded"), true, true);
+
+let requestObserver = {
+  observe(subject, topic, data) {
+    if (topic == "http-on-opening-request") {
+      // Get DOMWindow on all child docshells to force about:blank
+      // content viewers being created.
+      getChildDocShells().map(ds => {
+        let window = ds.QueryInterface(Ci.nsIInterfaceRequestor)
+                      .getInterface(Ci.nsILoadContext)
+                      .associatedWindow;
+      });
+    }
+  },
+  QueryInterface: XPCOMUtils.generateQI([
+    Ci.nsIObserver,
+    Ci.nsISupportsWeakReference,
+  ])
+}
+Services.obs.addObserver(requestObserver, "http-on-opening-request", true /* ownsWeak */);
+
+function getChildDocShells() {
+  let docShellsEnum = docShell.getDocShellEnumerator(
+    Ci.nsIDocShellTreeItem.typeAll,
+    Ci.nsIDocShell.ENUMERATE_FORWARDS
+  );
+
+  let docShells = [];
+  while (docShellsEnum.hasMoreElements()) {
+    let ds = docShellsEnum.getNext();
+    docShells.push(ds);
+  }
+  return docShells;
+}