Bug 1486824 - change BrowserTestUtils to just call OpenBrowserWindow so it does the same thing as opening a window normally, r=mconley,nhnt11
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 03 Sep 2018 14:43:38 +0100
changeset 492265 c4b7704689846fb3684454872ea111d0a34eb1b8
parent 492264 cd105a01b7c0bd2935fe00472e9dc444d80afc2b
child 492266 c995c3a15034b631ccc7981b765f640f984a8209
push id1815
push userffxbld-merge
push dateMon, 15 Oct 2018 10:40:45 +0000
treeherdermozilla-release@18d4c09e9378 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley, nhnt11
bugs1486824
milestone63.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 1486824 - change BrowserTestUtils to just call OpenBrowserWindow so it does the same thing as opening a window normally, r=mconley,nhnt11 Differential Revision: https://phabricator.services.mozilla.com/D4466
accessible/tests/browser/events/browser_test_textcaret.js
browser/base/content/browser-captivePortal.js
browser/base/content/browser.js
browser/base/content/test/captivePortal/head.js
browser/base/content/test/forms/browser_selectpopup.js
browser/base/content/test/plugins/browser_private_clicktoplay.js
browser/base/content/test/sidebar/browser_sidebar_adopt.js
browser/components/customizableui/test/browser_editcontrols_update.js
browser/components/customizableui/test/browser_sidebar_toggle.js
browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js
browser/components/sessionstore/test/browser_394759_perwindowpb.js
dom/tests/browser/browser_bug1236512.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/accessible/tests/browser/events/browser_test_textcaret.js
+++ b/accessible/tests/browser/events/browser_test_textcaret.js
@@ -9,38 +9,37 @@
 function caretMoveChecker(target, caretOffset) {
   return function(event) {
     let cmEvent = event.QueryInterface(nsIAccessibleCaretMoveEvent);
     return cmEvent.accessible == getAccessible(target) && cmEvent.caretOffset == caretOffset;
   };
 }
 
 async function checkURLBarCaretEvents() {
-  let url = "about:mozilla";
+  const kURL = "about:mozilla";
+  let newWin = await BrowserTestUtils.openNewBrowserWindow();
+  newWin.gBrowser.selectedBrowser.loadURI(kURL);
 
-  let onDocLoad = waitForEvent(
+  await waitForEvent(
     EVENT_DOCUMENT_LOAD_COMPLETE,
     event => {
       try {
-        return event.accessible.QueryInterface(nsIAccessibleDocument).URL == url;
+        return event.accessible.QueryInterface(nsIAccessibleDocument).URL == kURL;
       } catch (e) {
         return false;
       }
     }
   );
-  let [ newWin ] = await Promise.all([
-    BrowserTestUtils.openNewBrowserWindow({ url }),
-    onDocLoad
-  ]);
+  info("Loaded " + kURL);
 
   let urlbarInputEl = newWin.document.getElementById("urlbar").inputField;
   let urlbarInput = getAccessible(urlbarInputEl, [ nsIAccessibleText ]);
 
   let onCaretMove = waitForEvents([
-    [ EVENT_TEXT_CARET_MOVED, caretMoveChecker(urlbarInput, url.length) ],
+    [ EVENT_TEXT_CARET_MOVED, caretMoveChecker(urlbarInput, kURL.length) ],
     [ EVENT_FOCUS, urlbarInput ]
   ]);
 
   urlbarInput.caretOffset = -1;
   await onCaretMove;
   ok(true, "Caret move in URL bar #1");
 
   onCaretMove = waitForEvent(
--- a/browser/base/content/browser-captivePortal.js
+++ b/browser/base/content/browser-captivePortal.js
@@ -108,16 +108,22 @@ var CaptivePortalWatcher = {
   },
 
   _captivePortalDetected() {
     if (this._delayedCaptivePortalDetectedInProgress) {
       return;
     }
 
     let win = BrowserWindowTracker.getTopWindow();
+    // Used by tests: ignore the main test window in order to enable testing of
+    // the case where we have no open windows.
+    if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
+      win = null;
+    }
+
     // If no browser window has focus, open and show the tab when we regain focus.
     // This is so that if a different application was focused, when the user
     // (re-)focuses a browser window, we open the tab immediately in that window
     // so they can log in before continuing to browse.
     if (win != Services.ww.activeWindow) {
       this._delayedCaptivePortalDetectedInProgress = true;
       Services.obs.addObserver(this, "xul-window-visible");
     }
@@ -131,16 +137,22 @@ var CaptivePortalWatcher = {
    * the tab if needed after a short delay to allow the recheck to complete.
    */
   _delayedCaptivePortalDetected() {
     if (!this._delayedCaptivePortalDetectedInProgress) {
       return;
     }
 
     let win = BrowserWindowTracker.getTopWindow();
+    // Used by tests: ignore the main test window in order to enable testing of
+    // the case where we have no open windows.
+    if (win && win.document.documentElement.getAttribute("ignorecaptiveportal")) {
+      win = null;
+    }
+
     if (win != Services.ww.activeWindow) {
       // The window that got focused was not a browser window.
       return;
     }
     Services.obs.removeObserver(this, "xul-window-visible");
     this._delayedCaptivePortalDetectedInProgress = false;
 
     if (win != window) {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4287,16 +4287,29 @@ function toOpenWindowByType(inType, uri,
   if (topWindow)
     topWindow.focus();
   else if (features)
     window.open(uri, "_blank", features);
   else
     window.open(uri, "_blank", "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar");
 }
 
+/**
+ * Open a new browser window.
+ *
+ * @param {Object} options
+ *        {
+ *          private: A boolean indicating if the window should be
+ *                   private
+ *          remote:  A boolean indicating if the window should run
+ *                   remote browser tabs or not. If omitted, the window
+ *                   will choose the profile default state.
+ *        }
+ * @return a reference to the new window.
+ */
 function OpenBrowserWindow(options) {
   var telemetryObj = {};
   TelemetryStopwatch.start("FX_NEW_WINDOW_MS", telemetryObj);
 
   var handler = Cc["@mozilla.org/browser/clh;1"]
                   .getService(Ci.nsIBrowserHandler);
   var defaultArgs = handler.defaultArgs;
   var wintype = document.documentElement.getAttribute("windowtype");
--- a/browser/base/content/test/captivePortal/head.js
+++ b/browser/base/content/test/captivePortal/head.js
@@ -15,32 +15,23 @@ const PORTAL_NOTIFICATION_VALUE = "capti
 async function setupPrefsAndRecentWindowBehavior() {
   await SpecialPowers.pushPrefEnv({
     set: [["captivedetect.canonicalURL", CANONICAL_URL],
           ["captivedetect.canonicalContent", CANONICAL_CONTENT]],
   });
   // We need to test behavior when a portal is detected when there is no browser
   // window, but we can't close the default window opened by the test harness.
   // Instead, we deactivate CaptivePortalWatcher in the default window and
-  // exclude it from BrowserWindowTracker.getTopWindow in an attempt to
-  // mask its presence.
+  // exclude it using an attribute to mask its presence.
   window.CaptivePortalWatcher.uninit();
-  let getTopWindowCopy = BrowserWindowTracker.getTopWindow;
-  let defaultWindow = window;
-  BrowserWindowTracker.getTopWindow = () => {
-    let win = getTopWindowCopy();
-    if (win == defaultWindow) {
-      return null;
-    }
-    return win;
-  };
+  window.document.documentElement.setAttribute("ignorecaptiveportal", "true");
 
   registerCleanupFunction(function cleanUp() {
-    BrowserWindowTracker.getTopWindow = getTopWindowCopy;
     window.CaptivePortalWatcher.init();
+    window.document.documentElement.removeAttribute("ignorecaptiveportal");
   });
 }
 
 async function portalDetected() {
   Services.obs.notifyObservers(null, "captive-portal-login");
   await BrowserTestUtils.waitForCondition(() => {
     return cps.state == cps.LOCKED_PORTAL;
   }, "Waiting for Captive Portal Service to update state after portal detected.");
--- a/browser/base/content/test/forms/browser_selectpopup.js
+++ b/browser/base/content/test/forms/browser_selectpopup.js
@@ -585,28 +585,34 @@ add_task(async function test_large_popup
 
   await performLargePopupTests(window);
 
   BrowserTestUtils.removeTab(tab);
 });
 
 // This test checks the same as the previous test but in a new smaller window.
 add_task(async function test_large_popup_in_small_window() {
-  let newwin = await BrowserTestUtils.openNewBrowserWindow({ width: 400, height: 400 });
+  let newWin = await BrowserTestUtils.openNewBrowserWindow();
+
+  let resizePromise = BrowserTestUtils.waitForEvent(newWin, "resize", false, e => {
+    return newWin.innerHeight <= 400 && newWin.innerWidth <= 400;
+  });
+  newWin.resizeTo(400, 400);
+  await resizePromise;
 
   const pageUrl = "data:text/html," + escape(PAGECONTENT_SMALL);
-  let browserLoadedPromise = BrowserTestUtils.browserLoaded(newwin.gBrowser.selectedBrowser);
-  await BrowserTestUtils.loadURI(newwin.gBrowser.selectedBrowser, pageUrl);
+  let browserLoadedPromise = BrowserTestUtils.browserLoaded(newWin.gBrowser.selectedBrowser);
+  await BrowserTestUtils.loadURI(newWin.gBrowser.selectedBrowser, pageUrl);
   await browserLoadedPromise;
 
-  newwin.gBrowser.selectedBrowser.focus();
+  newWin.gBrowser.selectedBrowser.focus();
 
-  await performLargePopupTests(newwin);
+  await performLargePopupTests(newWin);
 
-  await BrowserTestUtils.closeWindow(newwin);
+  await BrowserTestUtils.closeWindow(newWin);
 });
 
 async function performSelectSearchTests(win) {
   let browser = win.gBrowser.selectedBrowser;
   await ContentTask.spawn(browser, null, async function() {
     let doc = content.document;
     let select = doc.getElementById("one");
 
--- a/browser/base/content/test/plugins/browser_private_clicktoplay.js
+++ b/browser/base/content/test/plugins/browser_private_clicktoplay.js
@@ -21,17 +21,18 @@ function finishTest() {
 }
 
 let createPrivateWindow = async function createPrivateWindow(url) {
   gPrivateWindow = await BrowserTestUtils.openNewBrowserWindow({private: true});
   ok(!!gPrivateWindow, "should have created a private window.");
   gPrivateBrowser = gPrivateWindow.getBrowser().selectedBrowser;
 
   BrowserTestUtils.loadURI(gPrivateBrowser, url);
-  await BrowserTestUtils.browserLoaded(gPrivateBrowser);
+  await BrowserTestUtils.browserLoaded(gPrivateBrowser, false, url);
+  info("loaded " + url);
 };
 
 add_task(async function test() {
   registerCleanupFunction(function() {
     clearAllPluginPermissions();
     getTestPlugin().enabledState = Ci.nsIPluginTag.STATE_ENABLED;
     getTestPlugin("Second Test Plug-in").enabledState = Ci.nsIPluginTag.STATE_ENABLED;
   });
--- a/browser/base/content/test/sidebar/browser_sidebar_adopt.js
+++ b/browser/base/content/test/sidebar/browser_sidebar_adopt.js
@@ -14,21 +14,21 @@ function failIfSidebarFocusedFires() {
 }
 
 add_task(async function testAdoptedTwoWindows() {
   // First open a new window, show the sidebar in that window, and close it.
   // Then, open another new window and confirm that the sidebar is closed since it is
   // being adopted from the main window which doesn't have a shown sidebar. See Bug 1407737.
   info("Ensure that sidebar state is adopted only from the opener");
 
-  let win1 = await BrowserTestUtils.openNewBrowserWindow({opener: window});
+  let win1 = await BrowserTestUtils.openNewBrowserWindow();
   await win1.SidebarUI.show("viewBookmarksSidebar");
   await BrowserTestUtils.closeWindow(win1);
 
-  let win2 = await BrowserTestUtils.openNewBrowserWindow({opener: window});
+  let win2 = await BrowserTestUtils.openNewBrowserWindow();
   ok(!win2.document.getElementById("sidebar-button").hasAttribute("checked"), "Sidebar button isn't checked");
   ok(!win2.SidebarUI.isOpen, "Sidebar is closed");
   await BrowserTestUtils.closeWindow(win2);
 });
 
 add_task(async function testEventsReceivedInMainWindow() {
   info("Opening the sidebar and expecting both SidebarShown and SidebarFocused events");
 
@@ -41,17 +41,17 @@ add_task(async function testEventsReceiv
 
   ok(true, "SidebarShown and SidebarFocused events fired on a new window");
 });
 
 add_task(async function testEventReceivedInNewWindow() {
   info("Opening a new window and expecting the SidebarFocused event to not fire");
 
   let promiseNewWindow = BrowserTestUtils.waitForNewWindow();
-  BrowserTestUtils.openNewBrowserWindow({opener: window});
+  BrowserTestUtils.openNewBrowserWindow();
   let win = await promiseNewWindow;
 
   let adoptedShown = BrowserTestUtils.waitForEvent(win, "SidebarShown");
   win.addEventListener("SidebarFocused", failIfSidebarFocusedFires);
 
   registerCleanupFunction(async function() {
     win.removeEventListener("SidebarFocused", failIfSidebarFocusedFires);
     await BrowserTestUtils.closeWindow(win);
--- a/browser/components/customizableui/test/browser_editcontrols_update.js
+++ b/browser/components/customizableui/test/browser_editcontrols_update.js
@@ -197,16 +197,21 @@ add_task(async function finish() {
 
 // Test updating in the initial state when the edit-controls are on the panel but
 // have not yet been created. This needs to be done in a new window to ensure that
 // other tests haven't opened the panel.
 add_task(async function test_initial_state() {
   let testWindow = await BrowserTestUtils.openNewBrowserWindow();
   await SimpleTest.promiseFocus(testWindow);
 
+  // For focusing the URL bar to have an effect, we need to ensure the URL bar isn't
+  // initially focused:
+  testWindow.gBrowser.selectedTab.focus();
+  await TestUtils.waitForCondition(() => !testWindow.gURLBar.focused);
+
   let overridePromise = expectCommandUpdate(isMac, testWindow);
 
   testWindow.gURLBar.focus();
   testWindow.gURLBar.value = "test";
 
   await overridePromise;
 
   // Commands won't update when no edit UI is present. They default to being
--- a/browser/components/customizableui/test/browser_sidebar_toggle.js
+++ b/browser/components/customizableui/test/browser_sidebar_toggle.js
@@ -37,15 +37,15 @@ add_task(async function() {
   is(SidebarUI.currentID, "viewBookmarksSidebar", "Default sidebar selected");
   await SidebarUI.show("viewHistorySidebar");
 
   await hideSidebar();
   await showSidebar();
   is(SidebarUI.currentID, "viewHistorySidebar", "Selected sidebar remembered");
 
   await hideSidebar();
-  let otherWin = await BrowserTestUtils.openNewBrowserWindow({opener: window});
+  let otherWin = await BrowserTestUtils.openNewBrowserWindow();
   await showSidebar(otherWin);
   is(otherWin.SidebarUI.currentID, "viewHistorySidebar", "Selected sidebar remembered across windows");
   await hideSidebar(otherWin);
 
   await BrowserTestUtils.closeWindow(otherWin);
 });
--- a/browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
+++ b/browser/components/extensions/test/browser/browser_ext_sidebarAction_windows.js
@@ -43,17 +43,17 @@ add_task(async function sidebar_windows(
   ok(elements.length > 0, "have a menuitem");
   let style = elements[0].getAttribute("style");
   ok(style.includes("webextension-menuitem-image"), "this menu has style");
 
   let secondSidebar = extension.awaitMessage("sidebar");
 
   // SidebarUI relies on window.opener being set, which is normal behavior when
   // using menu or key commands to open a new browser window.
-  let win = await BrowserTestUtils.openNewBrowserWindow({opener: window});
+  let win = await BrowserTestUtils.openNewBrowserWindow();
 
   await secondSidebar;
   ok(!win.document.getElementById("sidebar-box").hidden, "sidebar box is visible in second window");
   // Check that the menuitem has our image styling.
   elements = win.document.getElementsByClassName("webextension-menuitem");
   ok(elements.length > 0, "have a menuitem");
   style = elements[0].getAttribute("style");
   ok(style.includes("webextension-menuitem-image"), "this menu has style");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_about.js
@@ -5,20 +5,21 @@
 const TP_PB_ENABLED_PREF = "privacy.trackingprotection.pbmode.enabled";
 const CB_ENABLED_PREF = "browser.contentblocking.enabled";
 const CB_UI_ENABLED_PREF = "browser.contentblocking.ui.enabled";
 
 /**
  * Opens a new private window and loads "about:privatebrowsing" there.
  */
 async function openAboutPrivateBrowsing() {
-  let win = await BrowserTestUtils.openNewBrowserWindow({ private: true });
+  let win = await BrowserTestUtils.openNewBrowserWindow({
+    private: true,
+    waitForNonAboutBlankLoad: true,
+  });
   let tab = win.gBrowser.selectedBrowser;
-  tab.loadURI("about:privatebrowsing");
-  await BrowserTestUtils.browserLoaded(tab);
   return { win, tab };
 }
 
 /**
  * Clicks the given link and checks this opens a new tab with the given URI.
  */
 async function testLinkOpensTab({ win, tab, elementId, expectedUrl }) {
   let newTabPromise = BrowserTestUtils.waitForNewTab(win.gBrowser, expectedUrl);
--- a/browser/components/sessionstore/test/browser_394759_perwindowpb.js
+++ b/browser/components/sessionstore/test/browser_394759_perwindowpb.js
@@ -12,18 +12,17 @@ const TESTS = [
     key: "bug 394759 PB",
     value: "uniq" + r() },
 ];
 
 function promiseTestOpenCloseWindow(aIsPrivate, aTest) {
   return (async function() {
     let win = await BrowserTestUtils.openNewBrowserWindow({ "private": aIsPrivate });
     win.gBrowser.selectedBrowser.loadURI(aTest.url);
-    await promiseBrowserLoaded(win.gBrowser.selectedBrowser);
-    await Promise.resolve();
+    await promiseBrowserLoaded(win.gBrowser.selectedBrowser, true, aTest.url);
     // Mark the window with some unique data to be restored later on.
     ss.setWindowValue(win, aTest.key, aTest.value);
     await TabStateFlusher.flushWindow(win);
     // Close.
     await BrowserTestUtils.closeWindow(win);
   })();
 }
 
--- a/dom/tests/browser/browser_bug1236512.js
+++ b/dom/tests/browser/browser_bug1236512.js
@@ -38,22 +38,26 @@ async function waitContentVisibilityChan
 /**
  * This test is to test the visibility state will change to "hidden" when browser
  * window is fully covered by another non-translucent application. Note that we
  * only support this on Mac for now, other platforms don't support reporting
  * occlusion state.
  */
 add_task(async function() {
   info("creating test window");
+  let winTest = await BrowserTestUtils.openNewBrowserWindow();
   // Specify the width, height, left and top, so that the new window can be
   // fully covered by "window".
-  let winTest = await BrowserTestUtils.openNewBrowserWindow({ width: 500,
-                                                              height: 500,
-                                                              left: 200,
-                                                              top: 200 });
+  let resizePromise = BrowserTestUtils.waitForEvent(winTest, "resize", false, e => {
+    return winTest.innerHeight <= 500 && winTest.innerWidth <= 500;
+  });
+  winTest.moveTo(200, 200);
+  winTest.resizeTo(500, 500);
+  await resizePromise;
+
   let browserTest = winTest.gBrowser;
 
   info(`loading test page: ${testPageURL}`);
   browserTest.selectedBrowser.loadURI(testPageURL);
   await BrowserTestUtils.browserLoaded(browserTest.selectedBrowser);
 
   info("test init visibility state");
   await testContentVisibilityState(false /* isHidden */, browserTest);
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -20,16 +20,19 @@ var EXPORTED_SYMBOLS = [
 ];
 
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://testing-common/TestUtils.jsm");
 ChromeUtils.import("resource://testing-common/ContentTask.jsm");
 
+ChromeUtils.defineModuleGetter(this, "BrowserWindowTracker",
+  "resource:///modules/BrowserWindowTracker.jsm");
+
 Services
   .mm
   .loadFrameScript(
     "chrome://mochikit/content/tests/BrowserTestUtils/content-utils.js", true);
 
 ChromeUtils.defineModuleGetter(this, "E10SUtils",
   "resource://gre/modules/E10SUtils.jsm");
 
@@ -696,80 +699,44 @@ var BrowserTestUtils = {
           resolve(subject.QueryInterface(Ci.nsIDOMWindow));
         }
       }
       Services.ww.registerNotification(observer);
     });
   },
 
   /**
-   * @param {Object} options
-   *        {
-   *          private: A boolean indicating if the window should be
-   *                   private
-   *          remote:  A boolean indicating if the window should run
-   *                   remote browser tabs or not. If omitted, the window
-   *                   will choose the profile default state.
-   *          width: Desired width of window
-   *          height: Desired height of window
-   *        }
+   * Open a new browser window from an existing one.
+   * This relies on OpenBrowserWindow in browser.js, and waits for the window
+   * to be completely loaded before resolving.
+   *
+   * @param {Object}
+   *        Options to pass to OpenBrowserWindow. Additionally, supports:
+   *        - waitForNonAboutBlankLoad
+   *          Forces the initial browserLoaded check to wait for the tab to
+   *          load something other than about:blank.
+   *
    * @return {Promise}
    *         Resolves with the new window once it is loaded.
    */
   async openNewBrowserWindow(options = {}) {
-    let argString = Cc["@mozilla.org/supports-string;1"].
-                    createInstance(Ci.nsISupportsString);
-    argString.data = "";
-    let features = "chrome,dialog=no,all";
-    let opener = null;
-
-    if (options.opener) {
-      opener = options.opener;
-    }
-
-    if (options.private) {
-      features += ",private";
-    }
-
-    if (options.width) {
-      features += ",width=" + options.width;
-    }
-    if (options.height) {
-      features += ",height=" + options.height;
+    let currentWin = BrowserWindowTracker.getTopWindow({private: false});
+    if (!currentWin) {
+      throw new Error("Can't open a new browser window from this helper if no non-private window is open.");
     }
-
-    if (options.left) {
-      features += ",left=" + options.left;
-    }
-
-    if (options.top) {
-      features += ",top=" + options.top;
-    }
-
-    if (options.hasOwnProperty("remote")) {
-      let remoteState = options.remote ? "remote" : "non-remote";
-      features += `,${remoteState}`;
-    }
-
-    if (options.url) {
-      argString.data = options.url;
-    }
-
-    let win = Services.ww.openWindow(
-      opener, AppConstants.BROWSER_CHROME_URL, "_blank",
-      features, argString);
+    let win = currentWin.OpenBrowserWindow(options);
 
     // Wait for browser-delayed-startup-finished notification, it indicates
     // that the window has loaded completely and is ready to be used for
     // testing.
     let startupPromise =
       TestUtils.topicObserved("browser-delayed-startup-finished",
                               subject => subject == win).then(() => win);
 
-    let loadPromise = this.firstBrowserLoaded(win);
+    let loadPromise = this.firstBrowserLoaded(win, !options.waitForNonAboutBlankLoad);
 
     await startupPromise;
     await loadPromise;
 
     return win;
   },
 
   /**