Bug 1246664 - enable browser_f7_caret_browsing.js in e10s, r?mikedeboer draft
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Wed, 11 May 2016 20:49:58 +0100
changeset 367327 f2b4d1c0512453d0e12762f00bae495df1c30164
parent 367326 0c29ad917ac38c9ef26c9ff0b5d9762e75d13948
child 520974 ddf83f4ef7917b4d7f185b44418b99b8276d4282
push id18203
push usergijskruitbosch@gmail.com
push dateMon, 16 May 2016 10:32:28 +0000
reviewersmikedeboer
bugs1246664
milestone49.0a1
Bug 1246664 - enable browser_f7_caret_browsing.js in e10s, r?mikedeboer MozReview-Commit-ID: 3FcoylbqlBm
toolkit/content/tests/browser/browser.ini
toolkit/content/tests/browser/browser_f7_caret_browsing.js
--- a/toolkit/content/tests/browser/browser.ini
+++ b/toolkit/content/tests/browser/browser.ini
@@ -7,17 +7,16 @@ support-files =
 [browser_bug295977_autoscroll_overflow.js]
 [browser_bug451286.js]
 [browser_bug594509.js]
 [browser_bug982298.js]
 [browser_bug1198465.js]
 [browser_contentTitle.js]
 [browser_default_image_filename.js]
 [browser_f7_caret_browsing.js]
-skip-if = e10s
 [browser_findbar.js]
 [browser_label_textlink.js]
 [browser_isSynthetic.js]
 support-files =
   empty.png
 [browser_keyevents_during_autoscrolling.js]
 [browser_save_resend_postdata.js]
 support-files =
--- a/toolkit/content/tests/browser/browser_f7_caret_browsing.js
+++ b/toolkit/content/tests/browser/browser_f7_caret_browsing.js
@@ -1,14 +1,8 @@
-XPCOMUtils.defineLazyModuleGetter(this, "Promise",
-  "resource://gre/modules/Promise.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
-  "resource://gre/modules/Task.jsm");
-
-var gTab = null;
 var gListener = null;
 const kURL = "data:text/html;charset=utf-8,Caret browsing is fun.<input id='in'>";
 
 const kPrefShortcutEnabled = "accessibility.browsewithcaret_shortcut.enabled";
 const kPrefWarnOnEnable    = "accessibility.warn_on_browsewithcaret";
 const kPrefCaretBrowsingOn = "accessibility.browsewithcaret";
 
 var oldPrefs = {};
@@ -16,264 +10,214 @@ for (let pref of [kPrefShortcutEnabled, 
   oldPrefs[pref] = Services.prefs.getBoolPref(pref);
 }
 
 Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
 Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
 Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
 
 registerCleanupFunction(function() {
-  if (gTab)
-    gBrowser.removeTab(gTab);
-  if (gListener)
-    Services.wm.removeListener(gListener);
-
   for (let pref of [kPrefShortcutEnabled, kPrefWarnOnEnable, kPrefCaretBrowsingOn]) {
     Services.prefs.setBoolPref(pref, oldPrefs[pref]);
   }
 });
 
-function waitForCondition(aConditionFn, aMaxTries=50, aCheckInterval=100) {
-  function tryNow() {
-    tries++;
-    if (aConditionFn()) {
-      deferred.resolve();
-    } else if (tries < aMaxTries) {
-      tryAgain();
-    } else {
-      deferred.reject("Condition timed out: " + aConditionFn.toSource());
+// NB: not using BrowserTestUtils.domWindowOpened here because there's no way to
+// undo waiting for a window open. If we don't want the window to be opened, and
+// wait for it to verify that it indeed does not open, we need to be able to
+// then "stop" waiting so that when we next *do* want it to open, our "old"
+// listener doesn't fire and do things we don't want (like close the window...).
+let gCaretPromptOpeningObserver;
+function promiseCaretPromptOpened() {
+  return new Promise(resolve => {
+    function observer(subject, topic, data) {
+      if (topic == "domwindowopened") {
+        Services.ww.unregisterNotification(observer);
+        let win = subject.QueryInterface(Ci.nsIDOMWindow);
+        BrowserTestUtils.waitForEvent(win, "load", false, e => e.target.location.href != "about:blank").then(() => resolve(win));
+        gCaretPromptOpeningObserver = null;
+      }
     }
-  }
-  function tryAgain() {
-    setTimeout(tryNow, aCheckInterval);
-  }
-  let deferred = Promise.defer();
-  let tries = 0;
-  tryAgain();
-  return deferred.promise;
-}
-
-function promiseWaitForDialogUnload(dialog) {
-  let deferred = Promise.defer();
-  dialog.addEventListener("unload", function listener() {
-    dialog.removeEventListener("unload", listener, false);
-    deferred.resolve();
-  }, false);
-  return deferred.promise;
-}
-
-function promiseWaitForFocusEvent(el) {
-  if (el.ownerDocument.activeElement == el) {
-    return true;
-  }
-  let deferred = Promise.defer();
-  el.addEventListener("focus", function listener() {
-    el.removeEventListener("focus", listener, false);
-    deferred.resolve();
-  }, false);
-  return deferred.promise;
-}
-
-function promiseTestPageLoad() {
-  let deferred = Promise.defer();
-  info("Waiting for test page to load.");
-
-  gTab = gBrowser.selectedTab = gBrowser.addTab(kURL);
-  let browser = gBrowser.selectedBrowser;
-  browser.addEventListener("load", function listener() {
-    if (browser.currentURI.spec == "about:blank")
-      return;
-    info("Page loaded: " + browser.currentURI.spec);
-    browser.removeEventListener("load", listener, true);
-
-    deferred.resolve();
-  }, true);
-
-  return deferred.promise;
-}
-
-function promiseCaretPromptOpened() {
-  let deferred = Promise.defer();
-  if (gListener) {
-    console.trace();
-    ok(false, "Should not be waiting for another prompt right now.");
-    return false;
-  }
-  info("Waiting for caret prompt to open");
-  gListener = {
-    onOpenWindow: function(win) {
-      let window = win.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIDOMWindow);
-      window.addEventListener("load", function listener() {
-        window.removeEventListener("load", listener);
-        if (window.location.href == "chrome://global/content/commonDialog.xul") {
-          info("Caret prompt opened, removing listener and focusing");
-          Services.wm.removeListener(gListener);
-          gListener = null;
-          deferred.resolve(window);
-        }
-      });
-    },
-    onCloseWindow: function() {},
-  };
-  Services.wm.addListener(gListener);
-  return deferred.promise;
+    Services.ww.registerNotification(observer);
+    gCaretPromptOpeningObserver = observer;
+  });
 }
 
 function hitF7(async = true) {
-  let f7 = () => EventUtils.sendKey("F7", window.content);
+  let f7 = () => EventUtils.sendKey("F7");
   // Need to not stop execution inside this task:
   if (async) {
     executeSoon(f7);
   } else {
     f7();
   }
 }
 
 function syncToggleCaretNoDialog(expected) {
   let openedDialog = false;
   promiseCaretPromptOpened().then(function(win) {
     openedDialog = true;
     win.close(); // This will eventually return focus here and allow the test to continue...
   });
   // Cause the dialog to appear sync, if it still does.
   hitF7(false);
-  if (gListener) {
-    Services.wm.removeListener(gListener);
-    gListener = null;
-  }
+
   let expectedStr = expected ? "on." : "off.";
   ok(!openedDialog, "Shouldn't open a dialog to turn caret browsing " + expectedStr);
+  // Need to clean up if the dialog wasn't opened, so the observer doesn't get
+  // re-triggered later on causing "issues".
+  if (!openedDialog) {
+    Services.ww.unregisterNotification(gCaretPromptOpeningObserver);
+    gCaretPromptOpeningObserver = null;
+  }
   let prefVal = Services.prefs.getBoolPref(kPrefCaretBrowsingOn);
   is(prefVal, expected, "Caret browsing should now be " + expectedStr);
 }
 
+function waitForFocusOnInput(browser)
+{
+  return BrowserTestUtils.waitForMessage(browser.messageManager, "F7CaretBrowsingTest:FocusChanged");
+}
+
+function focusInput(browser)
+{
+  return ContentTask.spawn(browser, null, function* () {
+    let textEl = content.document.getElementById("in");
+    textEl.focus();
+
+    textEl.addEventListener("focus", () => {
+      info("Sending focus message");
+      sendAsyncMessage("F7CaretBrowsingTest:FocusChanged");
+    });
+  });
+}
+
 add_task(function* checkTogglingCaretBrowsing() {
-  yield promiseTestPageLoad();
-  let textEl = window.content.document.getElementById("in");
-  textEl.focus();
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
+  yield focusInput(tab.linkedBrowser);
 
   let promiseGotKey = promiseCaretPromptOpened();
   hitF7();
   let prompt = yield promiseGotKey;
   let doc = prompt.document;
   is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
   ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
-  let promiseDialogUnloaded = promiseWaitForDialogUnload(prompt);
+  let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
+  let promiseFocusOnInput = waitForFocusOnInput(tab.linkedBrowser);
+
   doc.documentElement.cancelDialog();
-  yield promiseDialogUnloaded;
-  yield waitForCondition(() => textEl.ownerDocument.activeElement == textEl);
+  promiseDialogUnloaded.then(() => info("Dialog unloaded"));
+  yield Promise.all([promiseDialogUnloaded, promiseFocusOnInput]);
   ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off after cancelling the dialog.");
 
   promiseGotKey = promiseCaretPromptOpened();
   hitF7();
   prompt = yield promiseGotKey;
 
   doc = prompt.document;
   is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
   ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
-  promiseDialogUnloaded = promiseWaitForDialogUnload(prompt);
+  promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
+  promiseFocusOnInput = waitForFocusOnInput(tab.linkedBrowser);
+
   doc.documentElement.acceptDialog();
-  yield promiseDialogUnloaded;
-  yield waitForCondition(() => textEl.ownerDocument.activeElement == textEl);
+  yield Promise.all([promiseDialogUnloaded, promiseFocusOnInput]);
   ok(Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should be on after accepting the dialog.");
 
   syncToggleCaretNoDialog(false);
 
   promiseGotKey = promiseCaretPromptOpened();
   hitF7();
   prompt = yield promiseGotKey;
   doc = prompt.document;
 
   is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
   ok(!doc.getElementById("checkbox").checked, "Checkbox shouldn't be checked by default.");
 
-  promiseDialogUnloaded = promiseWaitForDialogUnload(prompt);
+  promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
+  promiseFocusOnInput = waitForFocusOnInput(tab.linkedBrowser);
   doc.documentElement.cancelDialog();
-  yield promiseDialogUnloaded;
-  yield waitForCondition(() => textEl.ownerDocument.activeElement == textEl);
+  yield Promise.all([promiseDialogUnloaded, promiseFocusOnInput]);
 
   ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off after cancelling the dialog.");
 
   Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
   Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
   Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
 
-  gBrowser.removeTab(gTab);
-  gTab = null;
+  yield BrowserTestUtils.removeTab(tab);
 });
 
 add_task(function* toggleCheckboxNoCaretBrowsing() {
-  yield promiseTestPageLoad();
-  let textEl = window.content.document.getElementById("in");
-  textEl.focus();
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
+  yield focusInput(tab.linkedBrowser);
 
   let promiseGotKey = promiseCaretPromptOpened();
   hitF7();
   let prompt = yield promiseGotKey;
   let doc = prompt.document;
   is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
   let checkbox = doc.getElementById("checkbox");
   ok(!checkbox.checked, "Checkbox shouldn't be checked by default.");
 
   // Check the box:
   checkbox.click();
-  let promiseDialogUnloaded = promiseWaitForDialogUnload(prompt);
+
+  let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
+  let promiseFocusOnInput = waitForFocusOnInput(tab.linkedBrowser);
+
   // Say no:
   doc.documentElement.getButton("cancel").click();
-  yield promiseDialogUnloaded;
-  yield waitForCondition(() => textEl.ownerDocument.activeElement == textEl);
+
+  yield Promise.all([promiseDialogUnloaded, promiseFocusOnInput]);
   ok(!Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should still be off.");
-
   ok(!Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should now be disabled.");
 
   syncToggleCaretNoDialog(false);
   ok(!Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should still be disabled.");
 
   Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
   Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
   Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
 
-  gBrowser.removeTab(gTab);
-  gTab = null;
+  yield BrowserTestUtils.removeTab(tab);
 });
 
 
 add_task(function* toggleCheckboxWantCaretBrowsing() {
-  yield promiseTestPageLoad();
-  let textEl = window.content.document.getElementById("in");
-  textEl.focus();
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, kURL);
+  yield focusInput(tab.linkedBrowser);
 
   let promiseGotKey = promiseCaretPromptOpened();
   hitF7();
   let prompt = yield promiseGotKey;
   let doc = prompt.document;
   is(doc.documentElement.defaultButton, "cancel", "No button should be the default");
   let checkbox = doc.getElementById("checkbox");
   ok(!checkbox.checked, "Checkbox shouldn't be checked by default.");
 
   // Check the box:
   checkbox.click();
-  let promiseDialogUnloaded = promiseWaitForDialogUnload(prompt);
+
+  let promiseDialogUnloaded = BrowserTestUtils.waitForEvent(prompt, "unload");
+  let promiseFocusOnInput = waitForFocusOnInput(tab.linkedBrowser);
+
   // Say yes:
   doc.documentElement.acceptDialog();
-  yield promiseDialogUnloaded;
-  yield waitForCondition(() => textEl.ownerDocument.activeElement == textEl);
+  yield Promise.all([promiseDialogUnloaded, promiseFocusOnInput]);
   ok(Services.prefs.getBoolPref(kPrefCaretBrowsingOn), "Caret browsing should now be on.");
   ok(Services.prefs.getBoolPref(kPrefShortcutEnabled), "Shortcut should still be enabled.");
   ok(!Services.prefs.getBoolPref(kPrefWarnOnEnable), "Should no longer warn when enabling.");
 
-
   syncToggleCaretNoDialog(false);
   syncToggleCaretNoDialog(true);
   syncToggleCaretNoDialog(false);
 
   Services.prefs.setBoolPref(kPrefShortcutEnabled, true);
   Services.prefs.setBoolPref(kPrefWarnOnEnable, true);
   Services.prefs.setBoolPref(kPrefCaretBrowsingOn, false);
 
-  gBrowser.removeTab(gTab);
-  gTab = null;
+  yield BrowserTestUtils.removeTab(tab);
 });