Bug 1153289 - Add some tab switching methods to BrowserTestUtils.jsm. r=felipe, a=test-only
authorNeil Deakin <neil@mozilla.com>
Thu, 16 Apr 2015 15:38:13 -0400
changeset 267512 91cd2fcb1fd50958700002a92c70b18021ac5368
parent 267511 31d67ade835483397cb68769100256e8f7421c64
child 267517 eff3a3e4e107a3e18f40af7363f070747949c316
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfelipe, test-only
bugs1153289
milestone39.0
Bug 1153289 - Add some tab switching methods to BrowserTestUtils.jsm. r=felipe, a=test-only
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -46,26 +46,87 @@ this.BrowserTestUtils = {
    *        the tab is loaded. The first argument passed to the function is a
    *        reference to the browser object for the new tab.
    *
    * @return {Promise}
    * @resolves When the tab has been closed.
    * @rejects Any exception from taskFn is propagated.
    */
   withNewTab: Task.async(function* (options, taskFn) {
-    let tab = options.gBrowser.addTab(options.url);
-    yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
-    options.gBrowser.selectedTab = tab;
-
+    let tab = yield BrowserTestUtils.openNewForegroundTab(options.gBrowser, options.url);
     yield taskFn(tab.linkedBrowser);
-
     options.gBrowser.removeTab(tab);
   }),
 
   /**
+   * Opens a new tab in the foreground.
+   *
+   * @param {tabbrowser} tabbrowser
+   *        The tabbrowser to open the tab new in.
+   * @param {string} opening
+   *        May be either a string URL to load in the tab, or a function that
+   *        will be called to open a foreground tab. Defaults to "about:blank".
+   * @param {boolean} waitForLoad
+   *        True to wait for the page in the new tab to load. Defaults to true.
+   *
+   * @return {Promise}
+   *         Resolves when the tab is ready and loaded as necessary.
+   * @resolves The new tab.
+   */
+  openNewForegroundTab(tabbrowser, opening = "about:blank", aWaitForLoad = true) {
+    let tab;
+    let promises = [
+      BrowserTestUtils.switchTab(tabbrowser, function () {
+        if (typeof opening == "function") {
+          opening();
+          tab = tabbrowser.selectedTab;
+        }
+        else {
+          tabbrowser.selectedTab = tab = tabbrowser.addTab(opening);
+        }
+      })
+    ];
+
+    if (aWaitForLoad) {
+      promises.push(BrowserTestUtils.browserLoaded(tab.linkedBrowser));
+    }
+
+    return Promise.all(promises).then(() => tab);
+  },
+
+  /**
+   * Switches to a tab and resolves when it is ready.
+   *
+   * @param {tabbrowser} tabbrowser
+   *        The tabbrowser.
+   * @param {tab} tab
+   *        Either a tab element to switch to or a function to perform the switch.
+   *
+   * @return {Promise}
+   *         Resolves when the tab has been switched to.
+   * @resolves The tab switched to.
+   */
+  switchTab(tabbrowser, tab) {
+    let promise = new Promise(resolve => {
+      tabbrowser.addEventListener("TabSwitchDone", function onSwitch() {
+        tabbrowser.removeEventListener("TabSwitchDone", onSwitch);
+        TestUtils.executeSoon(() => resolve(tabbrowser.selectedTab));
+      });
+    });
+
+    if (typeof tab == "function") {
+      tab();
+    }
+    else {
+      tabbrowser.selectedTab = tab;
+    }
+    return promise;
+  },
+
+  /**
    * Waits for an ongoing page load in a browser window to complete.
    *
    * This can be used in conjunction with any synchronous method for starting a
    * load, like the "addTab" method on "tabbrowser", and must be called before
    * yielding control to the event loop. This is guaranteed to work because the
    * way we're listening for the load is in the content-utils.js frame script,
    * and then sending an async message up, so we can't miss the message.
    *