Bug 1047603 - Regression test. r=Mossop.
authorMike Conley <mconley@mozilla.com>
Thu, 29 Jan 2015 17:27:23 -0500
changeset 228521 fc4dbee3da2bad065f28c74b931e4258b56a9d53
parent 228520 73e42f528ee6fe304357312b5e922567f4799dd3
child 228522 8f27590f84179816352c9e2fad4b8f9b472e2535
push id28264
push usercbook@mozilla.com
push dateWed, 11 Feb 2015 13:58:35 +0000
treeherdermozilla-central@38058cb42a0e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1047603
milestone38.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 1047603 - Regression test. r=Mossop. Disabled on Linux without e10s on by default because e10s windows cannot be opened without OMTC being enabled. OMTC is force-enabled for Linux when e10s is on by default.
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
browser/base/content/test/general/head.js
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -422,16 +422,18 @@ skip-if = os == "linux" || os == "mac" #
 [browser_tabfocus.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s (test calls getFocusedElementForWindow with a content window)
 [browser_tabkeynavigation.js]
 skip-if = e10s
 [browser_tabopen_reflows.js]
 [browser_tabs_isActive.js]
 skip-if = e10s # Bug 1100664 - test relies on linkedBrowser.docShell
 [browser_tabs_owner.js]
+[browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js]
+skip-if = !e10s && os == "linux" # Bug 994541 - Need OMTC enabled by default on Linux, or else we get blocked by an alert dialog when opening e10s window.
 [browser_trackingUI.js]
 support-files =
   trackingPage.html
   benignPage.html
 [browser_typeAheadFind.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 921935 - focusmanager issues with e10s (test calls waitForFocus)
 [browser_unloaddialogs.js]
 skip-if = e10s # Bug 1100700 - test relies on unload event firing on closed tabs, which it doesn't
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_testOpenNewRemoteTabsFromNonRemoteBrowsers.js
@@ -0,0 +1,124 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+const OPEN_LOCATION_PREF = "browser.link.open_newwindow";
+const NON_REMOTE_PAGE = "about:welcomeback";
+
+Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+function frame_script() {
+  content.document.body.innerHTML = `
+    <a href="about:home" target="_blank" id="testAnchor">Open a window</a>
+  `;
+
+  let element = content.document.getElementById("testAnchor");
+  element.click();
+}
+
+/**
+ * Takes some browser in some window, and forces that browser
+ * to become non-remote, and then navigates it to a page that
+ * we're not supposed to be displaying remotely. Returns a
+ * Promise that resolves when the browser is no longer remote.
+ */
+function prepareNonRemoteBrowser(aWindow, browser) {
+  browser.loadURI(NON_REMOTE_PAGE);
+  return waitForDocLoadComplete(browser);
+}
+
+registerCleanupFunction(() => {
+  Services.prefs.clearUserPref(OPEN_LOCATION_PREF);
+});
+
+/**
+ * Test that if we open a new tab from a link in a non-remote
+ * browser in an e10s window, that the new tab will load properly.
+ */
+add_task(function* test_new_tab() {
+  let normalWindow = yield promiseOpenAndLoadWindow({
+    remote: true
+  }, true);
+  let privateWindow = yield promiseOpenAndLoadWindow({
+    remote: true,
+    private: true,
+  }, true);
+
+  for (let testWindow of [normalWindow, privateWindow]) {
+    yield promiseWaitForFocus(testWindow);
+    let testBrowser = testWindow.gBrowser.selectedBrowser;
+    info("Preparing non-remote browser");
+    yield prepareNonRemoteBrowser(testWindow, testBrowser);
+    info("Non-remote browser prepared - sending frame script");
+
+    // Get our framescript ready
+    let mm = testBrowser.messageManager;
+    mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
+
+    let tabOpenEvent = yield waitForNewTabEvent(testWindow.gBrowser);
+    let newTab = tabOpenEvent.target;
+
+    yield promiseTabLoadEvent(newTab);
+
+    // Our framescript opens to about:home which means that the
+    // tab should eventually become remote.
+    ok(newTab.linkedBrowser.isRemoteBrowser,
+       "The opened browser never became remote.");
+
+    testWindow.gBrowser.removeTab(newTab);
+  }
+
+  normalWindow.close();
+  privateWindow.close();
+});
+
+/**
+ * Test that if we open a new window from a link in a non-remote
+ * browser in an e10s window, that the new window is not an e10s
+ * window. Also tests with a private browsing window.
+ */
+add_task(function* test_new_window() {
+  let normalWindow = yield promiseOpenAndLoadWindow({
+    remote: true
+  }, true);
+  let privateWindow = yield promiseOpenAndLoadWindow({
+    remote: true,
+    private: true,
+  }, true);
+
+  // Fiddle with the prefs so that we open target="_blank" links
+  // in new windows instead of new tabs.
+  Services.prefs.setIntPref(OPEN_LOCATION_PREF,
+                            Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW);
+
+  for (let testWindow of [normalWindow, privateWindow]) {
+    yield promiseWaitForFocus(testWindow);
+    let testBrowser = testWindow.gBrowser.selectedBrowser;
+    yield prepareNonRemoteBrowser(testWindow, testBrowser);
+
+    // Get our framescript ready
+    let mm = testBrowser.messageManager;
+    mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", true);
+
+    // Click on the link in the browser, and wait for the new window.
+    let {subject: newWindow} =
+      yield promiseTopicObserved("browser-delayed-startup-finished");
+
+    is(PrivateBrowsingUtils.isWindowPrivate(testWindow),
+       PrivateBrowsingUtils.isWindowPrivate(newWindow),
+       "Private browsing state of new window does not match the original!");
+
+    let newTab = newWindow.gBrowser.selectedTab;
+
+    yield promiseTabLoadEvent(newTab);
+
+    // Our framescript opens to about:home which means that the
+    // tab should eventually become remote.
+    ok(newTab.linkedBrowser.isRemoteBrowser,
+       "The opened browser never became remote.");
+    newWindow.close();
+  }
+
+  normalWindow.close();
+  privateWindow.close();
+});
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -118,16 +118,33 @@ function promiseWaitForEvent(object, eve
       resolve(event);
     }
 
     info("Waiting for " + eventName);
     object.addEventListener(eventName, listener, capturing, chrome);
   });
 }
 
+/**
+ * Allows setting focus on a window, and waiting for that window to achieve
+ * focus.
+ *
+ * @param aWindow
+ *        The window to focus and wait for.
+ *
+ * @return {Promise}
+ * @resolves When the window is focused.
+ * @rejects Never.
+ */
+function promiseWaitForFocus(aWindow) {
+  return new Promise((resolve) => {
+    waitForFocus(resolve, aWindow);
+  });
+}
+
 function getTestPlugin(aName) {
   var pluginName = aName || "Test Plug-in";
   var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
   var tags = ph.getPluginTags();
 
   // Find the test plugin
   for (var i = 0; i < tags.length; i++) {
     if (tags[i].name == pluginName)
@@ -567,16 +584,31 @@ function promiseTabLoadEvent(tab, url, e
   }, 30000);
 
   tab.linkedBrowser.addEventListener(eventType, handle, true, true);
   if (url)
     tab.linkedBrowser.loadURI(url);
   return deferred.promise;
 }
 
+/**
+ * Returns a Promise that resolves once a new tab has been opened in
+ * a xul:tabbrowser.
+ *
+ * @param aTabBrowser
+ *        The xul:tabbrowser to monitor for a new tab.
+ * @return {Promise}
+ *        Resolved when the new tab has been opened.
+ * @resolves to the TabOpen event that was fired.
+ * @rejects Never.
+ */
+function waitForNewTabEvent(aTabBrowser) {
+  return promiseWaitForEvent(aTabBrowser.tabContainer, "TabOpen");
+}
+
 function assertWebRTCIndicatorStatus(expected) {
   let ui = Cu.import("resource:///modules/webrtcUI.jsm", {}).webrtcUI;
   let expectedState = expected ? "visible" : "hidden";
   let msg = "WebRTC indicator " + expectedState;
   is(ui.showGlobalIndicator, !!expected, msg);
 
   let expectVideo = false, expectAudio = false, expectScreen = false;
   if (expected) {
@@ -740,8 +772,31 @@ function promiseAutocompleteResultPopup(
   waitForFocus(() => {
     win.gURLBar.focus();
     win.gURLBar.value = inputText;
     win.gURLBar.controller.startSearch(inputText);
   }, win);
 
   return promiseSearchComplete(win);
 }
+
+/**
+ * Allows waiting for an observer notification once.
+ *
+ * @param aTopic
+ *        Notification topic to observe.
+ *
+ * @return {Promise}
+ * @resolves An object with subject and data properties from the observed
+ *           notification.
+ * @rejects Never.
+ */
+function promiseTopicObserved(aTopic)
+{
+  return new Promise((resolve) => {
+    Services.obs.addObserver(
+      function PTO_observe(aSubject, aTopic, aData) {
+        Services.obs.removeObserver(PTO_observe, aTopic);
+        resolve({subject: aSubject, data: aData});
+      }, aTopic, false);
+  });
+}
+