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.

--HG--
extra : rebase_source : 434b7dc0e899fef0c508d5dd01438514da519ba3
extra : histedit_source : 517043f2bbe7a22bd53e8ae0c77f585ac107f6c9
This commit is contained in:
Gregory Szorc 2014-04-10 14:30:40 -07:00
parent 4e0d9f32be
commit df6e0b4232
2 changed files with 141 additions and 130 deletions

View File

@ -7,169 +7,150 @@ let gCategoryUtilities;
let gInstalledAddons = [];
let gContext = this;
function test() {
waitForExplicitFinish();
add_task(function* initializeState() {
gManagerWindow = yield open_manager();
gCategoryUtilities = new CategoryUtilities(gManagerWindow);
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);
// 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);
// 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();
}
});
}
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);
add_task(function* testActiveExperiment() {
let addon = yield install_addon("addons/browser_experiment1.xpi");
gInstalledAddons.push(addon);
Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install.");
Assert.equal(addon.isActive, false, "Add-on is not active.");
Assert.ok(addon.userDisabled, "Add-on is disabled upon initial install.");
Assert.equal(addon.isActive, false, "Add-on is not active.");
Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible.");
Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible.");
gCategoryUtilities.openType("experiment", (win) => {
let el = gManagerWindow.document.getElementsByClassName("experiment-info-container")[0];
is_element_visible(el, "Experiment info is visible on experiment tab.");
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;
}
window.addEventListener("DOMContentLoaded", function onLoad(event) {
info("Telemetry privacy policy window opened.");
window.removeEventListener("DOMContentLoaded", onLoad, false);
is_element_visible(btn, "Learn more button visible.");
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 deferred = Promise.defer();
window.addEventListener("DOMContentLoaded", function onLoad(event) {
info("Telemetry privacy policy window opened.");
window.removeEventListener("DOMContentLoaded", onLoad, false);
Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
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();
run_next_test();
}, false);
Services.prefs.clearUserPref("toolkit.telemetry.infoURL");
info("Opening telemetry privacy policy.");
EventUtils.synthesizeMouseAtCenter(btn, {}, gManagerWindow);
});
deferred.resolve();
}, false);
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.");
run_next_test();
});
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.");
});
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();
}
});

View File

@ -283,6 +283,8 @@ function wait_for_manager_load(aManagerWindow, aCallback) {
}
function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
let deferred = Promise.defer();
function setup_manager(aManagerWindow) {
if (aLoadCallback)
log_exceptions(aLoadCallback, aManagerWindow);
@ -299,7 +301,10 @@ function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
// 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);
});
@ -309,7 +314,7 @@ function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
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) {
@ -318,7 +323,7 @@ function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
return;
setup_manager(aSubject);
}, "EM-loaded", false);
return;
return deferred.promise;
}
openDialog(MANAGER_URI);
@ -326,9 +331,12 @@ function open_manager(aView, aCallback, aLoadCallback, aLongerTimeout) {
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");
@ -336,10 +344,15 @@ function close_manager(aManagerWindow, aCallback, aLongerTimeout) {
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) {
@ -424,17 +437,25 @@ function is_element_hidden(aElement, aMsg) {
* 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) {
@ -496,17 +517,26 @@ CategoryUtilities.prototype = {
},
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);
}
}