--- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
+++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm
@@ -7,16 +7,20 @@
this.EXPORTED_SYMBOLS = ["ExtensionTestUtils"];
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Components.utils.import("resource://gre/modules/ExtensionUtils.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
+ "resource://gre/modules/AddonManager.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "AddonTestUtils",
+ "resource://testing-common/AddonTestUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Extension",
"resource://gre/modules/Extension.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Schemas",
"resource://gre/modules/Schemas.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
@@ -147,109 +151,165 @@ class ContentPage {
this.browser = null;
this.windowlessBrowser.close();
this.windowlessBrowser = null;
}
}
class ExtensionWrapper {
- constructor(extension, testScope) {
- this.extension = extension;
+ constructor(testScope, extension = null) {
this.testScope = testScope;
+ this.extension = null;
+
+ this.handleResult = this.handleResult.bind(this);
+ this.handleMessage = this.handleMessage.bind(this);
+
this.state = "uninitialized";
this.testResolve = null;
this.testDone = new Promise(resolve => { this.testResolve = resolve; });
this.messageHandler = new Map();
this.messageAwaiter = new Map();
this.messageQueue = new Set();
- this.attachListeners();
this.testScope.do_register_cleanup(() => {
- if (this.messageQueue.size) {
- let names = Array.from(this.messageQueue, ([msg]) => msg);
- this.testScope.equal(JSON.stringify(names), "[]", "message queue is empty");
- }
- if (this.messageAwaiter.size) {
- let names = Array.from(this.messageAwaiter.keys());
- this.testScope.equal(JSON.stringify(names), "[]", "no tasks awaiting on messages");
- }
- });
+ this.clearMessageQueues();
- this.testScope.do_register_cleanup(() => {
if (this.state == "pending" || this.state == "running") {
this.testScope.equal(this.state, "unloaded", "Extension left running at test shutdown");
return this.unload();
- } else if (extension.state == "unloading") {
+ } else if (this.state == "unloading") {
this.testScope.equal(this.state, "unloaded", "Extension not fully unloaded at test shutdown");
}
+ this.destroy();
});
- this.testScope.do_print(`Extension loaded`);
+ if (extension) {
+ this.id = extension.id;
+ this.attachExtension(extension);
+ }
+ }
+
+ destroy() {
+ // This method should be implemented in subclasses which need to
+ // perform cleanup when destroyed.
+ }
+
+ attachExtension(extension) {
+ if (extension === this.extension) {
+ return;
+ }
+
+ if (this.extension) {
+ this.extension.off("test-eq", this.handleResult);
+ this.extension.off("test-log", this.handleResult);
+ this.extension.off("test-result", this.handleResult);
+ this.extension.off("test-done", this.handleResult);
+ this.extension.off("test-message", this.handleMessage);
+ this.clearMessageQueues();
+ }
+ this.extension = extension;
+
+ extension.on("test-eq", this.handleResult);
+ extension.on("test-log", this.handleResult);
+ extension.on("test-result", this.handleResult);
+ extension.on("test-done", this.handleResult);
+ extension.on("test-message", this.handleMessage);
+
+ this.testScope.do_print(`Extension attached`);
}
- attachListeners() {
- /* eslint-disable mozilla/balanced-listeners */
- this.extension.on("test-eq", (kind, pass, msg, expected, actual) => {
- this.testScope.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`);
- });
- this.extension.on("test-log", (kind, pass, msg) => {
- this.testScope.do_print(msg);
- });
- this.extension.on("test-result", (kind, pass, msg) => {
- this.testScope.ok(pass, msg);
- });
- this.extension.on("test-done", (kind, pass, msg, expected, actual) => {
- this.testScope.ok(pass, msg);
- this.testResolve(msg);
- });
+ clearMessageQueues() {
+ if (this.messageQueue.size) {
+ let names = Array.from(this.messageQueue, ([msg]) => msg);
+ this.testScope.equal(JSON.stringify(names), "[]", "message queue is empty");
+ this.messageQueue.clear();
+ }
+ if (this.messageAwaiter.size) {
+ let names = Array.from(this.messageAwaiter.keys());
+ this.testScope.equal(JSON.stringify(names), "[]", "no tasks awaiting on messages");
+ for (let promise of this.messageAwaiter.values()) {
+ promise.reject();
+ }
+ this.messageAwaiter.clear();
+ }
+ }
+
+ handleResult(kind, pass, msg, expected, actual) {
+ switch (kind) {
+ case "test-eq":
+ this.testScope.ok(pass, `${msg} - Expected: ${expected}, Actual: ${actual}`);
+ break;
- this.extension.on("test-message", (kind, msg, ...args) => {
- let handler = this.messageHandler.get(msg);
- if (handler) {
- handler(...args);
- } else {
- this.messageQueue.add([msg, ...args]);
- this.checkMessages();
- }
- });
- /* eslint-enable mozilla/balanced-listeners */
+ case "test-log":
+ this.testScope.do_print(msg);
+ break;
+
+ case "test-result":
+ this.testScope.ok(pass, msg);
+ break;
+
+ case "test-done":
+ this.testScope.ok(pass, msg);
+ this.testResolve(msg);
+ break;
+ }
+ }
+
+ handleMessage(kind, msg, ...args) {
+ let handler = this.messageHandler.get(msg);
+ if (handler) {
+ handler(...args);
+ } else {
+ this.messageQueue.add([msg, ...args]);
+ this.checkMessages();
+ }
+ }
+
+ awaitStartup() {
+ return this.startupPromise;
}
startup() {
if (this.state != "uninitialized") {
throw new Error("Extension already started");
}
this.state = "pending";
- return this.extension.startup().then(
+ this.startupPromise = this.extension.startup().then(
result => {
this.state = "running";
return result;
},
error => {
this.state = "failed";
return Promise.reject(error);
});
+
+ return this.startupPromise;
}
async unload() {
if (this.state != "running") {
throw new Error("Extension not running");
}
this.state = "unloading";
- await this.extension.shutdown();
+ if (this.addon) {
+ this.addon.uninstall();
+ } else {
+ await this.extension.shutdown();
+ }
this.state = "unloaded";
}
/*
* This method marks the extension unloading without actually calling
* shutdown, since shutting down a MockExtension causes it to be uninstalled.
*
@@ -295,30 +355,211 @@ class ExtensionWrapper {
checkDuplicateListeners(msg) {
if (this.messageHandler.has(msg) || this.messageAwaiter.has(msg)) {
throw new Error("only one message handler allowed");
}
}
awaitMessage(msg) {
- return new Promise(resolve => {
+ return new Promise((resolve, reject) => {
this.checkDuplicateListeners(msg);
- this.messageAwaiter.set(msg, {resolve});
+ this.messageAwaiter.set(msg, {resolve, reject});
this.checkMessages();
});
}
onMessage(msg, callback) {
this.checkDuplicateListeners(msg);
this.messageHandler.set(msg, callback);
}
}
+class AOMExtensionWrapper extends ExtensionWrapper {
+ constructor(testScope, xpiFile, installType) {
+ super(testScope);
+
+ this.onEvent = this.onEvent.bind(this);
+
+ this.file = xpiFile;
+ this.installType = installType;
+
+ this.cleanupFiles = [xpiFile];
+
+ Management.on("ready", this.onEvent);
+ Management.on("shutdown", this.onEvent);
+ Management.on("startup", this.onEvent);
+
+ AddonTestUtils.on("addon-manager-shutdown", this.onEvent);
+ AddonTestUtils.on("addon-manager-started", this.onEvent);
+
+ AddonManager.addAddonListener(this);
+ }
+
+ destroy() {
+ this.id = null;
+ this.addon = null;
+
+ Management.off("ready", this.onEvent);
+ Management.off("shutdown", this.onEvent);
+ Management.off("startup", this.onEvent);
+
+ AddonTestUtils.off("addon-manager-shutdown", this.onEvent);
+ AddonTestUtils.off("addon-manager-started", this.onEvent);
+
+ AddonManager.removeAddonListener(this);
+
+ for (let file of this.cleanupFiles.splice(0)) {
+ try {
+ Services.obs.notifyObservers(file, "flush-cache-entry", null);
+ file.remove(false);
+ } catch (e) {
+ Cu.reportError(e);
+ }
+ }
+ }
+
+ setRestarting() {
+ if (this.state !== "restarting") {
+ this.startupPromise = new Promise(resolve => {
+ this.resolveStartup = resolve;
+ });
+ }
+ this.state = "restarting";
+ }
+
+ onEnabling(addon) {
+ if (addon.id === this.id) {
+ this.setRestarting();
+ }
+ }
+
+ onInstalling(addon) {
+ if (addon.id === this.id) {
+ this.setRestarting();
+ }
+ }
+
+ onInstalled(addon) {
+ if (addon.id === this.id) {
+ this.addon = addon;
+ }
+ }
+
+ onUninstalled(addon) {
+ if (addon.id === this.id) {
+ this.destroy();
+ }
+ }
+
+ onEvent(kind, ...args) {
+ switch (kind) {
+ case "addon-manager-started":
+ AddonManager.getAddonByID(this.id).then(addon => {
+ this.addon = addon;
+ });
+ // FALLTHROUGH
+ case "addon-manager-shutdown":
+ this.addon = null;
+
+ this.setRestarting();
+ break;
+
+ case "startup": {
+ let [extension] = args;
+ if (extension.id === this.id) {
+ this.attachExtension(extension);
+ this.state = "pending";
+ }
+ break;
+ }
+
+ case "shutdown": {
+ let [extension] = args;
+ if (extension.id === this.id && this.state !== "restarting") {
+ this.state = "unloaded";
+ }
+ break;
+ }
+
+ case "ready": {
+ let [extension] = args;
+ if (extension.id === this.id) {
+ this.state = "running";
+ this.resolveStartup(extension);
+ }
+ break;
+ }
+ }
+ }
+
+ _install(xpiFile) {
+ if (this.installType === "temporary") {
+ return AddonManager.installTemporaryAddon(xpiFile).then(addon => {
+ this.id = addon.id;
+ this.addon = addon;
+
+ return this.startupPromise;
+ }).catch(e => {
+ this.state = "unloaded";
+ return Promise.reject(e);
+ });
+ } else if (this.installType === "permanent") {
+ return AddonManager.getInstallForFile(xpiFile).then(install => {
+ let listener = {
+ onInstallFailed: () => {
+ this.state = "unloaded";
+ this.resolveStartup(Promise.reject(new Error("Install failed")));
+ },
+ onInstallEnded: (install, newAddon) => {
+ this.id = newAddon.id;
+ this.addon = newAddon;
+ },
+ };
+
+ install.addListener(listener);
+ install.install();
+
+ return this.startupPromise;
+ });
+ }
+ }
+
+ get version() {
+ return this.addon && this.addon.version;
+ }
+
+ startup() {
+ if (this.state != "uninitialized") {
+ throw new Error("Extension already started");
+ }
+
+ this.state = "pending";
+ this.startupPromise = new Promise(resolve => {
+ this.resolveStartup = resolve;
+ });
+
+ return this._install(this.file);
+ }
+
+ upgrade(data) {
+ this.startupPromise = new Promise(resolve => {
+ this.resolveStartup = resolve;
+ });
+ this.state = "restarting";
+
+ let xpiFile = Extension.generateXPI(data);
+
+ this.cleanupFiles.push(xpiFile);
+
+ return this._install(xpiFile);
+ }
+}
+
var ExtensionTestUtils = {
BASE_MANIFEST,
normalizeManifest: Task.async(function* (manifest, baseManifest = BASE_MANIFEST) {
yield Management.lazyInit();
let errors = [];
let context = {
@@ -403,19 +644,25 @@ var ExtensionTestUtils = {
this.mockAppInfo();
let manager = Cc["@mozilla.org/addons/integration;1"].getService(Ci.nsIObserver)
.QueryInterface(Ci.nsITimerCallback);
manager.observe(null, "addons-startup", null);
},
loadExtension(data) {
+ if (data.useAddonManager) {
+ let xpiFile = Extension.generateXPI(data);
+
+ return new AOMExtensionWrapper(this.currentScope, xpiFile, data.useAddonManager);
+ }
+
let extension = Extension.generate(data);
- return new ExtensionWrapper(extension, this.currentScope);
+ return new ExtensionWrapper(this.currentScope, extension);
},
get remoteContentScripts() {
return REMOTE_CONTENT_SCRIPTS;
},
set remoteContentScripts(val) {
REMOTE_CONTENT_SCRIPTS = !!val;
--- a/toolkit/components/extensions/test/xpcshell/test_ext_extensionPreferencesManager.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_extensionPreferencesManager.js
@@ -73,37 +73,37 @@ for (let setting in SETTINGS) {
function checkPrefs(settingObj, value, msg) {
for (let pref of settingObj.prefNames) {
equal(Preferences.get(pref), settingObj.valueFn(pref, value), msg);
}
}
add_task(async function test_preference_manager() {
+ await promiseStartupManager();
+
// Create an array of test framework extension wrappers to install.
let testExtensions = [
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {},
}),
];
- await promiseStartupManager();
-
for (let extension of testExtensions) {
await extension.startup();
}
// Create an array actual Extension objects which correspond to the
// test framework extension wrappers.
- let extensions = testExtensions.map(extension => extension.extension._extension);
+ let extensions = testExtensions.map(extension => extension.extension);
for (let setting in SETTINGS) {
let settingObj = SETTINGS[setting];
let newValue1 = "newValue1";
let levelOfControl = await ExtensionPreferencesManager.getLevelOfControl(
extensions[1], setting);
equal(levelOfControl, "controllable_by_this_extension",
"getLevelOfControl returns correct levelOfControl with no settings set.");
--- a/toolkit/components/extensions/test/xpcshell/test_ext_extensionSettingsStore.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_extensionSettingsStore.js
@@ -38,41 +38,41 @@ const TEST_TYPE = "myType";
let callbackCount = 0;
function initialValue(key) {
callbackCount++;
return `key:${key}`;
}
add_task(async function test_settings_store() {
+ await promiseStartupManager();
+
// Create an array of test framework extension wrappers to install.
let testExtensions = [
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {},
}),
ExtensionTestUtils.loadExtension({
useAddonManager: "temporary",
manifest: {},
}),
];
- await promiseStartupManager();
-
for (let extension of testExtensions) {
await extension.startup();
}
// Create an array actual Extension objects which correspond to the
// test framework extension wrappers.
- let extensions = testExtensions.map(extension => extension.extension._extension);
+ let extensions = testExtensions.map(extension => extension.extension);
let expectedCallbackCount = 0;
// Add a setting for the second oldest extension, where it is the only setting for a key.
for (let key of KEY_LIST) {
let extensionIndex = 1;
let itemToAdd = ITEMS[key][extensionIndex];
let levelOfControl = await ExtensionSettingsStore.getLevelOfControl(extensions[extensionIndex], TEST_TYPE, key);
--- a/toolkit/components/extensions/test/xpcshell/test_ext_management_uninstall_self.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_management_uninstall_self.js
@@ -62,17 +62,16 @@ add_task(function* test_management_unins
useAddonManager: "temporary",
});
yield extension.startup();
let addon = yield AddonManager.getAddonByID(id);
notEqual(addon, null, "Add-on is installed");
extension.sendMessage("uninstall");
yield waitForUninstalled();
- yield extension.markUnloaded();
Services.obs.notifyObservers(extension.extension.file, "flush-cache-entry", null);
});
add_task(function* test_management_uninstall_prompt_uninstall() {
promptService._response = 0;
function background() {
browser.test.onMessage.addListener(msg => {
@@ -86,17 +85,16 @@ add_task(function* test_management_unins
useAddonManager: "temporary",
});
yield extension.startup();
let addon = yield AddonManager.getAddonByID(id);
notEqual(addon, null, "Add-on is installed");
extension.sendMessage("uninstall");
yield waitForUninstalled();
- yield extension.markUnloaded();
// Test localization strings
equal(promptService._confirmExArgs[1], `Uninstall ${manifest.name}`);
equal(promptService._confirmExArgs[2],
`The extension “${manifest.name}” is requesting to be uninstalled. What would you like to do?`);
equal(promptService._confirmExArgs[4], "Uninstall");
equal(promptService._confirmExArgs[5], "Keep Installed");
Services.obs.notifyObservers(extension.extension.file, "flush-cache-entry", null);
@@ -118,17 +116,20 @@ add_task(function* test_management_unins
let extension = ExtensionTestUtils.loadExtension({
manifest,
background,
useAddonManager: "temporary",
});
yield extension.startup();
+
let addon = yield AddonManager.getAddonByID(id);
notEqual(addon, null, "Add-on is installed");
+
extension.sendMessage("uninstall");
yield extension.awaitMessage("uninstall-rejected");
+
addon = yield AddonManager.getAddonByID(id);
notEqual(addon, null, "Add-on remains installed");
+
yield extension.unload();
- Services.obs.notifyObservers(extension.extension.file, "flush-cache-entry", null);
});
--- a/toolkit/components/extensions/test/xpcshell/test_ext_privacy_update.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_privacy_update.js
@@ -10,43 +10,29 @@ XPCOMUtils.defineLazyGetter(this, "Manag
XPCOMUtils.defineLazyModuleGetter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
const {
createAppInfo,
createTempWebExtensionFile,
- promiseAddonEvent,
promiseCompleteAllInstalls,
promiseFindAddonUpdates,
promiseShutdownManager,
promiseStartupManager,
} = AddonTestUtils;
AddonTestUtils.init(this);
// Allow for unsigned addons.
AddonTestUtils.overrideCertDB();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
-function awaitEvent(eventName) {
- return new Promise(resolve => {
- let listener = (_eventName, ...args) => {
- if (_eventName === eventName) {
- Management.off(eventName, listener);
- resolve(...args);
- }
- };
-
- Management.on(eventName, listener);
- });
-}
-
add_task(async function test_privacy_update() {
// Create a object to hold the values to which we will initialize the prefs.
const PREFS = {
"network.predictor.enabled": true,
"network.prefetch-next": true,
"network.http.speculative-parallel-limit": 10,
"network.dns.disablePrefetch": false,
};
@@ -139,42 +125,34 @@ add_task(async function test_privacy_upd
await extension.startup();
// Change the value to false.
extension.sendMessage("set", {value: false});
let data = await extension.awaitMessage("privacyData");
ok(!data.value, "get returns expected value after setting.");
- let addon = await AddonManager.getAddonByID(EXTENSION_ID);
- equal(addon.version, "1.0", "The installed addon has the expected version.");
+ equal(extension.version, "1.0", "The installed addon has the expected version.");
- let update = await promiseFindAddonUpdates(addon);
+ let update = await promiseFindAddonUpdates(extension.addon);
let install = update.updateAvailable;
- let promiseInstalled = promiseAddonEvent("onInstalled");
await promiseCompleteAllInstalls([install]);
- let startupPromise = awaitEvent("ready");
+ await extension.awaitStartup();
- let [updated_addon] = await promiseInstalled;
- equal(updated_addon.version, "2.0", "The updated addon has the expected version.");
-
- extension.extension = await startupPromise;
- extension.attachListeners();
+ equal(extension.version, "2.0", "The updated addon has the expected version.");
extension.sendMessage("get");
data = await extension.awaitMessage("privacyData");
ok(!data.value, "get returns expected value after updating.");
// Verify the prefs are still set to match the "false" setting.
for (let pref in PREFS) {
let msg = `${pref} set correctly.`;
let expectedValue = pref === "network.http.speculative-parallel-limit" ? 0 : !PREFS[pref];
equal(Preferences.get(pref), expectedValue, msg);
}
await extension.unload();
- await updated_addon.uninstall();
-
await promiseShutdownManager();
});
--- a/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
+++ b/toolkit/components/extensions/test/xpcshell/test_ext_runtime_onInstalled_and_onStartup.js
@@ -3,16 +3,17 @@
"use strict";
XPCOMUtils.defineLazyGetter(this, "Management", () => {
const {Management} = Cu.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
Cu.import("resource://gre/modules/AddonManager.jsm");
+Cu.import("resource://gre/modules/Preferences.jsm");
const {
createAppInfo,
createTempWebExtensionFile,
promiseAddonEvent,
promiseCompleteAllInstalls,
promiseFindAddonUpdates,
promiseRestartManager,
@@ -22,29 +23,16 @@ const {
AddonTestUtils.init(this);
// Allow for unsigned addons.
AddonTestUtils.overrideCertDB();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
-function awaitEvent(eventName) {
- return new Promise(resolve => {
- let listener = (_eventName, ...args) => {
- if (_eventName === eventName) {
- Management.off(eventName, listener);
- resolve(...args);
- }
- };
-
- Management.on(eventName, listener);
- });
-}
-
function background() {
let onInstalledDetails = null;
let onStartupFired = false;
browser.runtime.onInstalled.addListener(details => {
onInstalledDetails = details;
});
@@ -79,16 +67,20 @@ function* expectEvents(extension, {onSta
}
extension.sendMessage("did-on-startup-fire");
let fired = yield extension.awaitMessage("on-startup-fired");
equal(fired, onStartupFired, `Expected runtime.onStartup to ${onStartupFired ? "" : "not "} fire`);
}
add_task(function* test_should_fire_on_addon_update() {
+ Preferences.set("extensions.logging.enabled", false);
+
+ yield promiseStartupManager();
+
const EXTENSION_ID = "test_runtime_on_installed_addon_update@tests.mozilla.org";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
// The test extension uses an insecure update url.
Services.prefs.setBoolPref(PREF_EM_CHECK_UPDATE_SECURITY, false);
const testServer = createHttpServer();
@@ -132,18 +124,16 @@ add_task(function* test_should_fire_on_a
},
},
},
background,
});
testServer.registerFile("/addons/test_runtime_on_installed-2.0.xpi", webExtensionFile);
- yield promiseStartupManager();
-
yield extension.startup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: true,
onInstalledReason: "install",
});
@@ -153,33 +143,29 @@ add_task(function* test_should_fire_on_a
let update = yield promiseFindAddonUpdates(addon);
let install = update.updateAvailable;
let promiseInstalled = promiseAddonEvent("onInstalled");
yield promiseCompleteAllInstalls([install]);
yield extension.awaitMessage("reloading");
- let startupPromise = awaitEvent("ready");
-
let [updated_addon] = yield promiseInstalled;
equal(updated_addon.version, "2.0", "The updated addon has the correct version");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: true,
onInstalledReason: "update",
});
yield extension.unload();
- yield updated_addon.uninstall();
yield promiseShutdownManager();
});
add_task(function* test_should_fire_on_browser_update() {
const EXTENSION_ID = "test_runtime_on_installed_browser_update@tests.mozilla.org";
yield promiseStartupManager();
@@ -199,54 +185,47 @@ add_task(function* test_should_fire_on_b
yield extension.startup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: true,
onInstalledReason: "install",
});
- let startupPromise = awaitEvent("ready");
yield promiseRestartManager("1");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: true,
onInstalledFired: false,
});
// Update the browser.
- startupPromise = awaitEvent("ready");
yield promiseRestartManager("2");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: true,
onInstalledFired: true,
onInstalledReason: "browser_update",
});
// Restart the browser.
- startupPromise = awaitEvent("ready");
yield promiseRestartManager("2");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: true,
onInstalledFired: false,
});
// Update the browser again.
- startupPromise = awaitEvent("ready");
yield promiseRestartManager("3");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: true,
onInstalledFired: true,
onInstalledReason: "browser_update",
});
yield extension.unload();
@@ -275,20 +254,19 @@ add_task(function* test_should_not_fire_
yield extension.startup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: true,
onInstalledReason: "install",
});
- let startupPromise = awaitEvent("ready");
extension.sendMessage("reload-extension");
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ extension.setRestarting();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: false,
});
yield extension.unload();
yield promiseShutdownManager();
@@ -318,20 +296,18 @@ add_task(function* test_should_not_fire_
onStartupFired: false,
onInstalledFired: true,
onInstalledReason: "install",
});
let addon = yield AddonManager.getAddonByID(EXTENSION_ID);
addon.userDisabled = true;
- let startupPromise = awaitEvent("ready");
addon.userDisabled = false;
- extension.extension = yield startupPromise;
- extension.attachListeners();
+ yield extension.awaitStartup();
yield expectEvents(extension, {
onStartupFired: false,
onInstalledFired: false,
});
yield extension.markUnloaded();
yield promiseShutdownManager();
--- a/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js
@@ -25,29 +25,16 @@ gPort = testserver.identity.primaryPort;
mapFile("/data/test_delay_updates_complete.json", testserver);
mapFile("/data/test_delay_updates_ignore.json", testserver);
mapFile("/data/test_delay_updates_defer.json", testserver);
mapFile("/data/test_no_update.json", testserver);
testserver.registerDirectory("/addons/", do_get_file("addons"));
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42");
-const { Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {});
-
-function promiseWebExtensionStartup() {
- return new Promise(resolve => {
- let listener = (event, extension) => {
- Management.off("startup", listener);
- resolve(extension);
- };
-
- Management.on("startup", listener);
- });
-}
-
// add-on registers upgrade listener, and ignores update.
add_task(function* delay_updates_ignore() {
startupManager();
let extension = ExtensionTestUtils.loadExtension({
useAddonManager: "permanent",
manifest: {
"version": "1.0",
@@ -100,31 +87,30 @@ add_task(function* delay_updates_ignore(
do_check_true(addon_postponed.isCompatible);
do_check_false(addon_postponed.appDisabled);
do_check_true(addon_postponed.isActive);
do_check_eq(addon_postponed.type, "extension");
yield extension.awaitFinish("delay");
// restarting allows upgrade to proceed
- yield extension.markUnloaded();
yield promiseRestartManager();
let addon_upgraded = yield promiseAddonByID(IGNORE_ID);
- yield promiseWebExtensionStartup();
+ yield extension.awaitStartup();
do_check_neq(addon_upgraded, null);
do_check_eq(addon_upgraded.version, "2.0");
do_check_eq(addon_upgraded.name, "Delay Upgrade");
do_check_true(addon_upgraded.isCompatible);
do_check_false(addon_upgraded.appDisabled);
do_check_true(addon_upgraded.isActive);
do_check_eq(addon_upgraded.type, "extension");
- yield addon_upgraded.uninstall();
+ yield extension.unload();
yield promiseShutdownManager();
});
// add-on registers upgrade listener, and allows update.
add_task(function* delay_updates_complete() {
startupManager();
let extension = ExtensionTestUtils.loadExtension({
@@ -163,32 +149,31 @@ add_task(function* delay_updates_complet
let promiseInstalled = promiseAddonEvent("onInstalled");
yield promiseCompleteAllInstalls([install]);
yield extension.awaitFinish("reload");
// addon upgrade has been allowed
let [addon_allowed] = yield promiseInstalled;
- yield promiseWebExtensionStartup();
+ yield extension.awaitStartup();
do_check_neq(addon_allowed, null);
do_check_eq(addon_allowed.version, "2.0");
do_check_eq(addon_allowed.name, "Delay Upgrade");
do_check_true(addon_allowed.isCompatible);
do_check_false(addon_allowed.appDisabled);
do_check_true(addon_allowed.isActive);
do_check_eq(addon_allowed.type, "extension");
if (stageDir.exists()) {
do_throw("Staging directory should not exist for formerly-postponed extension");
}
- yield extension.markUnloaded();
- yield addon_allowed.uninstall();
+ yield extension.unload();
yield promiseShutdownManager();
});
// add-on registers upgrade listener, initially defers update then allows upgrade
add_task(function* delay_updates_defer() {
startupManager();
let extension = ExtensionTestUtils.loadExtension({
@@ -250,42 +235,41 @@ add_task(function* delay_updates_defer()
// add-on will not allow upgrade until message is received
yield extension.awaitMessage("truly ready");
extension.sendMessage("allow");
yield extension.awaitFinish("allowed");
// addon upgrade has been allowed
let [addon_allowed] = yield promiseInstalled;
- yield promiseWebExtensionStartup();
+ yield extension.awaitStartup();
do_check_neq(addon_allowed, null);
do_check_eq(addon_allowed.version, "2.0");
do_check_eq(addon_allowed.name, "Delay Upgrade");
do_check_true(addon_allowed.isCompatible);
do_check_false(addon_allowed.appDisabled);
do_check_true(addon_allowed.isActive);
do_check_eq(addon_allowed.type, "extension");
- yield extension.markUnloaded();
yield promiseRestartManager();
// restart changes nothing
addon_allowed = yield promiseAddonByID(DEFER_ID);
- yield promiseWebExtensionStartup();
+ yield extension.awaitStartup();
do_check_neq(addon_allowed, null);
do_check_eq(addon_allowed.version, "2.0");
do_check_eq(addon_allowed.name, "Delay Upgrade");
do_check_true(addon_allowed.isCompatible);
do_check_false(addon_allowed.appDisabled);
do_check_true(addon_allowed.isActive);
do_check_eq(addon_allowed.type, "extension");
- yield addon_allowed.uninstall();
+ yield extension.unload();
yield promiseShutdownManager();
});
// browser.runtime.reload() without a pending upgrade should just reload.
add_task(function* runtime_reload() {
startupManager();
let extension = ExtensionTestUtils.loadExtension({
@@ -321,23 +305,22 @@ add_task(function* runtime_reload() {
do_check_false(addon.appDisabled);
do_check_true(addon.isActive);
do_check_eq(addon.type, "extension");
yield promiseFindAddonUpdates(addon);
extension.sendMessage("reload");
// Wait for extension to restart, to make sure reload works.
- yield promiseWebExtensionStartup();
+ yield extension.awaitStartup();
addon = yield promiseAddonByID(NOUPDATE_ID);
do_check_neq(addon, null);
do_check_eq(addon.version, "1.0");
do_check_eq(addon.name, "Generated extension");
do_check_true(addon.isCompatible);
do_check_false(addon.appDisabled);
do_check_true(addon.isActive);
do_check_eq(addon.type, "extension");
- yield extension.markUnloaded();
- yield addon.uninstall();
+ yield extension.unload();
yield promiseShutdownManager();
});