Bug 1058164 - Test that we get pageshow and pagehide events in content scripts when swapping frameloaders. r=smaug.
authorMike Conley <mconley@mozilla.com>
Tue, 02 Sep 2014 23:09:12 -0400
changeset 203222 e92f2cc211cab77c5981f6ad526635300cffde80
parent 203221 53ab51cc4eb0a8b475ff1e8e1db8e59688c8b97e
child 203223 c537b894b7f45ac0f97a2d48f709f474309d1ca8
push id27424
push userryanvm@gmail.com
push dateWed, 03 Sep 2014 19:35:53 +0000
treeherdermozilla-central@bfef88becbba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1058164
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1058164 - Test that we get pageshow and pagehide events in content scripts when swapping frameloaders. r=smaug.
content/base/test/browser.ini
content/base/test/browser_bug1058164.js
--- a/content/base/test/browser.ini
+++ b/content/base/test/browser.ini
@@ -2,8 +2,10 @@
 
 [browser_bug593387.js]
 skip-if = e10s # Bug ?????? - test directly touches content (contentWindow.iframe.addEventListener)
 [browser_bug902350.js]
 skip-if = e10s # Bug ?????? - test e10s utils don't support load events from iframe etc, which this test relies on.
 [browser_state_notifications.js]
 # skip-if = e10s # Bug ?????? - content-document-* notifications come while document's URI is still about:blank, but test expects real URL.
 skip-if = true # Intermittent failures - bug 987493. Restore the skip-if above once fixed
+[browser_bug1058164.js]
+skip-if = e10s # We need bug 918634 to land before this can be tested with e10s.
new file mode 100644
--- /dev/null
+++ b/content/base/test/browser_bug1058164.js
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const kTimeout = 5000; // ms
+
+/**
+ * Frame script injected in the test browser that sends
+ * messages when it sees the pagehide and pageshow events
+ * with the persisted property set to true.
+ */
+function frame_script() {
+  addEventListener("pageshow", (event) => {
+    if (event.persisted) {
+      sendAsyncMessage("test:pageshow");
+    }
+  });
+  addEventListener("pagehide", (event) => {
+    if (event.persisted) {
+      sendAsyncMessage("test:pagehide");
+    }
+  });
+}
+
+/**
+ * Return a Promise that resolves when the browser's frame
+ * script sees an event of type eventType. eventType can be
+ * either "pagehide" or "pageshow". Times out after kTimeout
+ * milliseconds if the event is never seen.
+ */
+function prepareForPageEvent(browser, eventType) {
+  return new Promise((resolve, reject) => {
+    let mm = browser.messageManager;
+
+    let timeoutId = setTimeout(() => {
+      ok(false, "Timed out waiting for " + eventType)
+      reject();
+    }, kTimeout);
+
+    mm.addMessageListener("test:" + eventType, function onSawEvent(message) {
+      mm.removeMessageListener("test:" + eventType, onSawEvent);
+      ok(true, "Saw " + eventType + " event in frame script.");
+      clearTimeout(timeoutId);
+      resolve();
+    });
+  });
+}
+
+/**
+ * Returns a Promise that resolves when both the pagehide
+ * and pageshow events have been seen from the frame script.
+ */
+function prepareForPageHideAndShow(browser) {
+  return Promise.all([prepareForPageEvent(browser, "pagehide"),
+                      prepareForPageEvent(browser, "pageshow")]);
+}
+
+/**
+ * Returns a Promise that resolves when the load event for
+ * aWindow fires during the capture phase.
+ */
+function waitForLoad(aWindow) {
+  return new Promise((resolve, reject) => {
+    aWindow.addEventListener("load", function onLoad(aEvent) {
+      aWindow.removeEventListener("load", onLoad, true);
+      resolve();
+    }, true);
+  });
+}
+
+/**
+ * Tests that frame scripts get pageshow / pagehide events when
+ * swapping browser frameloaders (which occurs when moving a tab
+ * into a different window).
+ */
+add_task(function* test_swap_frameloader_pagevisibility_events() {
+  // Inject our frame script into a new browser.
+  let tab = gBrowser.addTab();
+  gBrowser.selectedTab = tab;
+  let mm = window.getGroupMessageManager("browsers");
+  mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
+  let browser = gBrowser.selectedBrowser;
+
+  // Swap the browser out to a new window
+  let newWindow = gBrowser.replaceTabWithWindow(tab);
+  // We have to wait for the window to load so we can get the selected browser
+  // to listen to.
+  yield waitForLoad(newWindow);
+  let pageHideAndShowPromise = prepareForPageHideAndShow(newWindow.gBrowser.selectedBrowser);
+  // Yield waiting for the pagehide and pageshow events.
+  yield pageHideAndShowPromise;
+
+  // Send the browser back to its original window
+  let newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  browser = newWindow.gBrowser.selectedBrowser;
+  pageHideAndShowPromise = prepareForPageHideAndShow(gBrowser.selectedBrowser);
+  gBrowser.swapBrowsersAndCloseOther(newTab, newWindow.gBrowser.selectedTab);
+
+  // Yield waiting for the pagehide and pageshow events.
+  yield pageHideAndShowPromise;
+
+  gBrowser.removeTab(gBrowser.selectedTab);
+});