Bug 989137 - Part 15: Convert browser_experiments.js to add_task; r=Unfocused
authorGregory Szorc <gps@mozilla.com>
Thu, 10 Apr 2014 14:30:40 -0700
changeset 179396 2c1a0b0551fb628660f6d3fef83b32e293b57858
parent 179395 73da7e611e92575866d4928bd2621591f110c3e0
child 179397 c94117f49274f5fb719f761d7dd961cf8e5c52ac
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersUnfocused
bugs989137
milestone31.0a1
Bug 989137 - Part 15: Convert browser_experiments.js to add_task; r=Unfocused Upcoming tests rely heavily on promises. I just learned that browser chrome tests support add_task() as an alternative to test(). This patch ports the browser_experiments.js test and utilized utility functions to use add_task() and promises.
toolkit/mozapps/extensions/test/browser/browser_experiments.js
toolkit/mozapps/extensions/test/browser/head.js
--- a/toolkit/mozapps/extensions/test/browser/browser_experiments.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_experiments.js
@@ -2,174 +2,155 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 let gManagerWindow;
 let gCategoryUtilities;
 let gInstalledAddons = [];
 let gContext = this;
 
-function test() {
-  waitForExplicitFinish();
-
-  open_manager(null, (win) => {
-    gManagerWindow = win;
-    gCategoryUtilities = new CategoryUtilities(win);
-
-    // The Experiments Manager will interfere with us by preventing installs
-    // of experiments it doesn't know about. We remove it from the equation
-    // because here we are only concerned with core Addon Manager operation,
-    // not the superset Experiments Manager has imposed.
-    if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
-      Components.utils.import("resource:///modules/experiments/Experiments.jsm", gContext);
+add_task(function* initializeState() {
+  gManagerWindow = yield open_manager();
+  gCategoryUtilities = new CategoryUtilities(gManagerWindow);
 
-      // There is a race condition between XPCOM service initialization and
-      // this test running. We have to initialize the instance first, then
-      // uninitialize it to prevent this.
-      let instance = gContext.Experiments.instance();
-      instance.uninit().then(run_next_test);
-    } else {
-      run_next_test();
-    }
-  });
-}
+  // The Experiments Manager will interfere with us by preventing installs
+  // of experiments it doesn't know about. We remove it from the equation
+  // because here we are only concerned with core Addon Manager operation,
+  // not the superset Experiments Manager has imposed.
+  if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
+    Components.utils.import("resource:///modules/experiments/Experiments.jsm", gContext);
 
-function end_test() {
-  for (let addon of gInstalledAddons) {
-    addon.uninstall();
+    // There is a race condition between XPCOM service initialization and
+    // this test running. We have to initialize the instance first, then
+    // uninitialize it to prevent this.
+    let instance = gContext.Experiments.instance();
+    yield instance.uninit();
   }
-
-  close_manager(gManagerWindow, () => {
-    if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
-      gContext.Experiments.instance().init();
-      finish();
-    } else {
-      finish();
-    }
-  });
-}
+});
 
 // On an empty profile with no experiments, the experiment category
 // should be hidden.
-add_test(function testInitialState() {
+add_task(function* testInitialState() {
   Assert.ok(gCategoryUtilities.get("experiment", false), "Experiment tab is defined.");
 
   Assert.ok(!gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab hidden by default.");
-
-  run_next_test();
 });
 
-add_test(function testExperimentInfoNotVisible() {
-  gCategoryUtilities.openType("extension", () => {
-    let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0];
-    is_element_hidden(el, "Experiment info not visible on other types.");
-
-    run_next_test();
-  });
+add_task(function* testExperimentInfoNotVisible() {
+  yield gCategoryUtilities.openType("extension");
+  let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0];
+  is_element_hidden(el, "Experiment info not visible on other types.");
 });
 
 // If we have an active experiment, we should see the experiments tab
 // and that tab should have some messages.
-add_test(function testActiveExperiment() {
-  install_addon("addons/browser_experiment1.xpi", (addon) => {
-    gInstalledAddons.push(addon);
-
-    Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install.");
-    Assert.equal(addon.isActive, false, "Add-on is not active.");
+add_task(function* testActiveExperiment() {
+  let addon = yield install_addon("addons/browser_experiment1.xpi");
+  gInstalledAddons.push(addon);
 
-    Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible.");
+  Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install.");
+  Assert.equal(addon.isActive, false, "Add-on is not active.");
 
-    gCategoryUtilities.openType("experiment", (win) => {
-      let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0];
-      is_element_visible(el, "Experiment info is visible on experiment tab.");
+  Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible.");
 
-      run_next_test();
-    });
-  });
+  yield gCategoryUtilities.openType("experiment");
+  let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0];
+  is_element_visible(el, "Experiment info is visible on experiment tab.");
 });
 
-add_test(function testExperimentLearnMore() {
+add_task(function* testExperimentLearnMore() {
   // Actual URL is irrelevant.
   Services.prefs.setCharPref("toolkit.telemetry.infoURL",
                              "http://mochi.test:8888/server.js");
 
-  gCategoryUtilities.openType("experiment", (win) => {
-    let btn = gManagerWindow.document.getElementById("experiments-learn-more");
+  yield gCategoryUtilities.openType("experiment");
+  let btn = gManagerWindow.document.getElementById("experiments-learn-more");
 
-    if (!gUseInContentUI) {
-      is_element_hidden(btn, "Learn more button hidden if not using in-content UI.");
-      Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
+  if (!gUseInContentUI) {
+    is_element_hidden(btn, "Learn more button hidden if not using in-content UI.");
+    Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
 
-      run_next_test();
-      return;
-    } else {
-      is_element_visible(btn, "Learn more button visible.");
-    }
+    return;
+  }
+
+  is_element_visible(btn, "Learn more button visible.");
 
-    window.addEventListener("DOMContentLoaded", function onLoad(event) {
-      info("Telemetry privacy policy window opened.");
-      window.removeEventListener("DOMContentLoaded", onLoad, false);
+  let deferred = Promise.defer();
+  window.addEventListener("DOMContentLoaded", function onLoad(event) {
+    info("Telemetry privacy policy window opened.");
+    window.removeEventListener("DOMContentLoaded", onLoad, false);
 
-      let browser = gBrowser.selectedTab.linkedBrowser;
-      let expected = Services.prefs.getCharPref("toolkit.telemetry.infoURL");
-      Assert.equal(browser.currentURI.spec, expected, "New tab should have loaded privacy policy.");
-      browser.contentWindow.close();
+    let browser = gBrowser.selectedTab.linkedBrowser;
+    let expected = Services.prefs.getCharPref("toolkit.telemetry.infoURL");
+    Assert.equal(browser.currentURI.spec, expected, "New tab should have loaded privacy policy.");
+    browser.contentWindow.close();
 
-      Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
+    Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
+
+    deferred.resolve();
+  }, false);
 
-      run_next_test();
-    }, false);
+  info("Opening telemetry privacy policy.");
+  EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow);
 
-    info("Opening telemetry privacy policy.");
-    EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow);
-  });
+  yield deferred.promise;
 });
 
-add_test(function testOpenPreferences() {
-  gCategoryUtilities.openType("experiment", (win) => {
-    let btn = gManagerWindow.document.getElementById("experiments-change-telemetry");
-    if (!gUseInContentUI) {
-      is_element_hidden(btn, "Change telemetry button not enabled in out of window UI.");
-      info("Skipping preferences open test because not using in-content UI.");
-      run_next_test();
-      return;
-    }
+add_task(function* testOpenPreferences() {
+  yield gCategoryUtilities.openType("experiment");
+  let btn = gManagerWindow.document.getElementById("experiments-change-telemetry");
+  if (!gUseInContentUI) {
+    is_element_hidden(btn, "Change telemetry button not enabled in out of window UI.");
+    info("Skipping preferences open test because not using in-content UI.");
+    return;
+  }
 
-    is_element_visible(btn, "Change telemetry button visible in in-content UI.");
+  is_element_visible(btn, "Change telemetry button visible in in-content UI.");
 
-    Services.obs.addObserver(function observer(prefWin, topic, data) {
-      Services.obs.removeObserver(observer, "advanced-pane-loaded");
+  let deferred = Promise.defer();
+  Services.obs.addObserver(function observer(prefWin, topic, data) {
+    Services.obs.removeObserver(observer, "advanced-pane-loaded");
 
-      info("Advanced preference pane opened.");
+    info("Advanced preference pane opened.");
 
-      // We want this test to fail if the preferences pane changes.
-      let el = prefWin.document.getElementById("dataChoicesPanel");
-      is_element_visible(el);
+    // We want this test to fail if the preferences pane changes.
+    let el = prefWin.document.getElementById("dataChoicesPanel");
+    is_element_visible(el);
 
-      prefWin.close();
-      info("Closed preferences pane.");
+    prefWin.close();
+    info("Closed preferences pane.");
 
-      run_next_test();
-    }, "advanced-pane-loaded", false);
+    deferred.resolve();
+  }, "advanced-pane-loaded", false);
 
-    info("Loading preferences pane.");
-    EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow);
-  });
+  info("Loading preferences pane.");
+  EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow);
+
+  yield deferred.promise;
 });
 
-add_test(function testButtonPresence() {
-  gCategoryUtilities.openType("experiment", (win) => {
-    let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org");
-    Assert.ok(item, "Got add-on element.");
+add_task(function* testButtonPresence() {
+  yield gCategoryUtilities.openType("experiment");
+  let item = get_addon_element(gManagerWindow, "test-experiment1@experiments.mozilla.org");
+  Assert.ok(item, "Got add-on element.");
 
-    let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn");
-    // Corresponds to the uninstall permission.
-    is_element_visible(el, "Remove button is visible.");
-    // Corresponds to lack of disable permission.
-    el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn");
-    is_element_hidden(el, "Disable button not visible.");
-    // Corresponds to lack of enable permission.
-    el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn");
-    is_element_hidden(el, "Enable button not visible.");
+  let el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "remove-btn");
+  // Corresponds to the uninstall permission.
+  is_element_visible(el, "Remove button is visible.");
+  // Corresponds to lack of disable permission.
+  el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "disable-btn");
+  is_element_hidden(el, "Disable button not visible.");
+  // Corresponds to lack of enable permission.
+  el = item.ownerDocument.getAnonymousElementByAttribute(item, "anonid", "enable-btn");
+  is_element_hidden(el, "Enable button not visible.");
+});
 
-    run_next_test();
-  });
+add_task(function* testCleanup() {
+  for (let addon of gInstalledAddons) {
+    addon.uninstall();
+  }
+
+  yield close_manager(gManagerWindow);
+
+  if ("@mozilla.org/browser/experiments-service;1" in Components.classes) {
+    yield gContext.Experiments.instance().init();
+  }
 });
--- a/toolkit/mozapps/extensions/test/browser/head.js
+++ b/toolkit/mozapps/extensions/test/browser/head.js
@@ -278,73 +278,86 @@ function wait_for_manager_load(aManagerW
   info("Waiting for initialization");
   aManagerWindow.document.addEventListener("Initialized", function() {
     aManagerWindow.document.removeEventListener("Initialized", arguments.callee, false);
     log_exceptions(aCallback, aManagerWindow);
   }, false);
 }
 
 function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
+  let deferred = Promise.defer();
+
   function setup_manager(aManagerWindow) {
     if (aLoadCallback)
       log_exceptions(aLoadCallback, aManagerWindow);
 
     if (aView)
       aManagerWindow.loadView(aView);
 
     ok(aManagerWindow != null, "Should have an add-ons manager window");
     is(aManagerWindow.location, MANAGER_URI, "Should be displaying the correct UI");
 
     waitForFocus(function() {
       wait_for_manager_load(aManagerWindow, function() {
         wait_for_view_load(aManagerWindow, function() {
           // Some functions like synthesizeMouse don't like to be called during
           // the load event so ensure that has completed
           executeSoon(function() {
-            log_exceptions(aCallback, aManagerWindow);
+            if (aCallback) {
+              log_exceptions(aCallback, aManagerWindow);
+            }
+            deferred.resolve(aManagerWindow);
           });
         }, null, aLongerTimeout);
       });
     }, aManagerWindow);
   }
 
   if (gUseInContentUI) {
     gBrowser.selectedTab = gBrowser.addTab();
     switchToTabHavingURI(MANAGER_URI, true);
-    
+
     // This must be a new load, else the ping/pong would have
     // found the window above.
     Services.obs.addObserver(function (aSubject, aTopic, aData) {
       Services.obs.removeObserver(arguments.callee, aTopic);
       if (aSubject.location.href != MANAGER_URI)
         return;
       setup_manager(aSubject);
     }, "EM-loaded", false);
-    return;
+    return deferred.promise;
   }
 
   openDialog(MANAGER_URI);
   Services.obs.addObserver(function (aSubject, aTopic, aData) {
     Services.obs.removeObserver(arguments.callee, aTopic);
     setup_manager(aSubject);
   }, "EM-loaded", false);
+
+  return deferred.promise;
 }
 
 function close_manager(aManagerWindow, aCallback, aLongerTimeout) {
+  let deferred = Promise.defer();
   requestLongerTimeout(aLongerTimeout ? aLongerTimeout : 2);
 
   ok(aManagerWindow != null, "Should have an add-ons manager window to close");
   is(aManagerWindow.location, MANAGER_URI, "Should be closing window with correct URI");
 
   aManagerWindow.addEventListener("unload", function() {
     this.removeEventListener("unload", arguments.callee, false);
-    log_exceptions(aCallback);
+    if (aCallback) {
+      log_exceptions(aCallback);
+    }
+    deferred.resolve();
   }, false);
 
   aManagerWindow.close();
+
+  return deferred.promise;
 }
 
 function restart_manager(aManagerWindow, aView, aCallback, aLoadCallback) {
   if (!aManagerWindow) {
     open_manager(aView, aCallback, aLoadCallback);
     return;
   }
 
@@ -419,27 +432,35 @@ function is_element_hidden(aElement, aMs
 }
 
 /**
  * Install an add-on and call a callback when complete.
  *
  * The callback will receive the Addon for the installed add-on.
  */
 function install_addon(path, cb, pathPrefix=TESTROOT) {
+  let deferred = Promise.defer();
+
   AddonManager.getInstallForURL(pathPrefix + path, (install) => {
     install.addListener({
       onInstallEnded: () => {
         executeSoon(() => {
-          cb(install.addon);
+          if (cb) {
+            cb(install.addon);
+          }
+
+          deferred.resolve(install.addon);
         });
       },
     });
 
     install.install();
   }, "application/x-xpinstall");
+
+  return deferred.promise;
 }
 
 function CategoryUtilities(aManagerWindow) {
   this.window = aManagerWindow;
 
   var self = this;
   this.window.addEventListener("unload", function() {
     self.window.removeEventListener("unload", arguments.callee, false);
@@ -491,27 +512,36 @@ CategoryUtilities.prototype = {
     return !is_hidden(aCategory);
   },
 
   isTypeVisible: function(aCategoryType) {
     return this.isVisible(this.get(aCategoryType));
   },
 
   open: function(aCategory, aCallback) {
+    let deferred = Promise.defer();
+
     isnot(this.window, null, "Should not open category when manager window is not loaded");
     ok(this.isVisible(aCategory), "Category should be visible if attempting to open it");
 
     EventUtils.synthesizeMouse(aCategory, 2, 2, { }, this.window);
 
-    if (aCallback)
-      wait_for_view_load(this.window, aCallback);
+    wait_for_view_load(this.window, (win) => {
+      if (aCallback) {
+        log_exceptions(aCallback, win);
+      }
+
+      deferred.resolve(win);
+    });
+
+    return deferred.promise;
   },
 
   openType: function(aCategoryType, aCallback) {
-    this.open(this.get(aCategoryType), aCallback);
+    return this.open(this.get(aCategoryType), aCallback);
   }
 }
 
 function CertOverrideListener(host, bits) {
   this.host = host;
   this.bits = bits;
 }