Bug 332195 - part 5: fix test for e10s, r=mconley
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Mon, 26 Oct 2015 14:16:46 +0100
changeset 304755 a60f220db385060583af460764abd87cd628c01e
parent 304754 e9d1a369d21762e16c0af0608bc9b1aff53c4428
child 304756 31033f04e561f64b6bb2a86e065d5b226616cfe4
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs332195
milestone44.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 332195 - part 5: fix test for e10s, r=mconley
browser/base/content/test/general/browser_openPromptInBackgroundTab.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/browser/base/content/test/general/browser_openPromptInBackgroundTab.js
+++ b/browser/base/content/test/general/browser_openPromptInBackgroundTab.js
@@ -14,18 +14,21 @@ registerCleanupFunction(function() {
  * the user to enable this automatically re-selecting. We then check that
  * checking the checkbox does actually enable that behaviour.
  */
 add_task(function*() {
   yield pushPrefs(["browser.tabs.dontfocusfordialogs", true]);
   let firstTab = gBrowser.selectedTab;
   // load page that opens prompt when page is hidden
   let openedTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, pageWithAlert, true);
+  let openedTabGotAttentionPromise = BrowserTestUtils.waitForAttribute("attention", openedTab, "true");
   // switch away from that tab again - this triggers the alert.
   yield BrowserTestUtils.switchTab(gBrowser, firstTab);
+  // ... but that's async on e10s...
+  yield openedTabGotAttentionPromise;
   // check for attention attribute
   is(openedTab.getAttribute("attention"), "true", "Tab with alert should have 'attention' attribute.");
   ok(!openedTab.selected, "Tab with alert should not be selected");
 
   // switch tab back, and check the checkbox is displayed:
   yield BrowserTestUtils.switchTab(gBrowser, openedTab);
   // check the prompt is there, and the extra row is present
   let prompts = openedTab.linkedBrowser.parentNode.querySelectorAll("tabmodalprompt");
@@ -38,16 +41,23 @@ add_task(function*() {
   ok(!checkbox.checked, "Checkbox shouldn't be checked");
   // tick box and accept dialog
   checkbox.checked = true;
   ourPrompt.onButtonClick(0);
   // check permission is set
   let ps = Services.perms;
   is(ps.ALLOW_ACTION, ps.testPermission(makeURI(pageWithAlert), "focus-tab-by-prompt"),
      "Tab switching should now be allowed");
+
+  let openedTabSelectedPromise = BrowserTestUtils.waitForAttribute("selected", openedTab, "true");
   // switch to other tab again
   yield BrowserTestUtils.switchTab(gBrowser, firstTab);
+
+  // This is sync in non-e10s, but in e10s we need to wait for this, so yield anyway.
+  // Note that the switchTab promise doesn't actually guarantee anything about *which*
+  // tab ends up as selected when its event fires, so using that here wouldn't work.
+  yield openedTabSelectedPromise;
   // should be switched back
   ok(openedTab.selected, "Ta-dah, the other tab should now be selected again!");
 
   yield BrowserTestUtils.removeTab(openedTab);
 });
 
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -599,16 +599,44 @@ this.BrowserTestUtils = {
     if (tab.getAttribute("crashed") != "true") {
       throw new Error("Tab should be marked as crashed");
     }
 
     return extra;
   }),
 
   /**
+   * Returns a promise that is resolved when element gains attribute (or,
+   * optionally, when it is set to value).
+   * @param {String} attr
+   *        The attribute to wait for
+   * @param {Element} element
+   *        The element which should gain the attribute
+   * @param {String} value (optional)
+   *        Optional, the value the attribute should have.
+   *
+   * @returns {Promise}
+   */
+  waitForAttribute(attr, element, value) {
+    let MutationObserver = element.ownerDocument.defaultView.MutationObserver;
+    return new Promise(resolve => {
+      let mut = new MutationObserver(mutations => {
+        if ((!value && element.getAttribute(attr)) ||
+            (value && element.getAttribute(attr) === value)) {
+          resolve();
+          mut.disconnect();
+          return;
+        }
+      });
+
+      mut.observe(element, {attributeFilter: [attr]});
+    });
+  },
+
+  /**
    * Version of EventUtils' `sendChar` function; it will synthesize a keypress
    * event in a child process and returns a Promise that will result when the
    * event was fired. Instead of a Window, a Browser object is required to be
    * passed to this function.
    *
    * @param {String} char
    *        A character for the keypress event that is sent to the browser.
    * @param {Browser} browser