forked from mirrors/gecko-dev
751 lines
22 KiB
JavaScript
751 lines
22 KiB
JavaScript
"use strict";
|
|
|
|
// Delay loading until createAppInfo is called and setup.
|
|
ChromeUtils.defineESModuleGetters(this, {
|
|
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
|
|
});
|
|
|
|
AddonTestUtils.init(this);
|
|
AddonTestUtils.overrideCertDB();
|
|
|
|
// The app and platform version here should be >= of the version set in the extensions.webExtensionsMinPlatformVersion preference,
|
|
// otherwise test_persistent_listener_after_staged_update will fail because no compatible updates will be found.
|
|
AddonTestUtils.createAppInfo(
|
|
"xpcshell@tests.mozilla.org",
|
|
"XPCShell",
|
|
"42",
|
|
"42"
|
|
);
|
|
|
|
let { promiseShutdownManager, promiseStartupManager, promiseRestartManager } =
|
|
AddonTestUtils;
|
|
|
|
const server = createHttpServer({ hosts: ["example.com"] });
|
|
server.registerDirectory("/data/", do_get_file("data"));
|
|
|
|
let scopes = AddonManager.SCOPE_PROFILE | AddonManager.SCOPE_APPLICATION;
|
|
Services.prefs.setIntPref("extensions.enabledScopes", scopes);
|
|
|
|
function trackEvents(wrapper) {
|
|
let events = new Map();
|
|
for (let event of ["background-script-event", "start-background-script"]) {
|
|
events.set(event, false);
|
|
wrapper.extension.once(event, () => events.set(event, true));
|
|
}
|
|
return events;
|
|
}
|
|
|
|
/**
|
|
* That that we get the expected events
|
|
*
|
|
* @param {Extension} extension
|
|
* @param {Map} events
|
|
* @param {object} expect
|
|
* @param {boolean} expect.background delayed startup event expected
|
|
* @param {boolean} expect.started background has already started
|
|
* @param {boolean} expect.delayedStart startup is delayed, notify start and
|
|
* expect the starting event
|
|
* @param {boolean} expect.request wait for the request event
|
|
*/
|
|
async function testPersistentRequestStartup(extension, events, expect = {}) {
|
|
equal(
|
|
events.get("background-script-event"),
|
|
!!expect.background,
|
|
"Should have gotten a background script event"
|
|
);
|
|
equal(
|
|
events.get("start-background-script"),
|
|
!!expect.started,
|
|
"Background script should be started"
|
|
);
|
|
|
|
if (!expect.started) {
|
|
AddonTestUtils.notifyEarlyStartup();
|
|
await ExtensionParent.browserPaintedPromise;
|
|
|
|
equal(
|
|
events.get("start-background-script"),
|
|
!!expect.delayedStart,
|
|
"Should have gotten start-background-script event"
|
|
);
|
|
}
|
|
|
|
if (expect.request) {
|
|
await extension.awaitMessage("got-request");
|
|
ok(true, "Background page loaded and received webRequest event");
|
|
}
|
|
}
|
|
|
|
// Test that a non-blocking listener does not start the background on
|
|
// startup, but that it does work after startup.
|
|
add_task(async function test_nonblocking() {
|
|
await promiseStartupManager();
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
permissions: ["webRequest", "http://example.com/"],
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] }
|
|
);
|
|
browser.test.sendMessage("ready");
|
|
},
|
|
});
|
|
|
|
// First install runs background immediately, this sets persistent listeners
|
|
await extension.startup();
|
|
await extension.awaitMessage("ready");
|
|
|
|
// Restart to get APP_STARTUP, the background should not start
|
|
await promiseRestartManager({ lateStartup: false });
|
|
await extension.awaitStartup();
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
|
|
// Test an early startup event
|
|
let events = trackEvents(extension);
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
|
|
await testPersistentRequestStartup(extension, events, {
|
|
background: false,
|
|
delayedStart: false,
|
|
request: false,
|
|
});
|
|
|
|
AddonTestUtils.notifyLateStartup();
|
|
await extension.awaitMessage("ready");
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
|
|
// Test an event after startup
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
|
|
await testPersistentRequestStartup(extension, events, {
|
|
background: false,
|
|
started: true,
|
|
request: true,
|
|
});
|
|
|
|
await extension.unload();
|
|
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
// Test that a non-blocking listener does not start the background on
|
|
// startup, but that it does work after startup.
|
|
add_task(async function test_eventpage_nonblocking() {
|
|
Services.prefs.setBoolPref("extensions.eventPages.enabled", true);
|
|
await promiseStartupManager();
|
|
|
|
let id = "event-nonblocking@test";
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
browser_specific_settings: { gecko: { id } },
|
|
permissions: ["webRequest", "http://example.com/"],
|
|
background: { persistent: false },
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] }
|
|
);
|
|
},
|
|
});
|
|
|
|
// First install runs background immediately, this sets persistent listeners
|
|
await extension.startup();
|
|
|
|
// Restart to get APP_STARTUP, the background should not start
|
|
await promiseRestartManager({ lateStartup: false });
|
|
await extension.awaitStartup();
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
|
|
// Test an early startup event
|
|
let events = trackEvents(extension);
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
|
|
await testPersistentRequestStartup(extension, events);
|
|
|
|
await AddonTestUtils.notifyLateStartup();
|
|
// After late startup, event page listeners should be primed.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: true,
|
|
});
|
|
|
|
// We should not have seen any events yet.
|
|
await testPersistentRequestStartup(extension, events);
|
|
|
|
// Test an event after startup
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
|
|
// Now the event page should be started and we'll see the request.
|
|
await testPersistentRequestStartup(extension, events, {
|
|
background: true,
|
|
started: true,
|
|
request: true,
|
|
});
|
|
|
|
await extension.unload();
|
|
|
|
await promiseShutdownManager();
|
|
Services.prefs.setBoolPref("extensions.eventPages.enabled", false);
|
|
});
|
|
|
|
// Tests that filters are handled properly: if we have a blocking listener
|
|
// with a filter, a request that does not match the filter does not get
|
|
// suspended and does not start the background page.
|
|
add_task(async function test_persistent_blocking() {
|
|
await promiseStartupManager();
|
|
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
permissions: [
|
|
"webRequest",
|
|
"webRequestBlocking",
|
|
"http://test1.example.com/",
|
|
],
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.fail("Listener should not have been called");
|
|
},
|
|
{ urls: ["http://test1.example.com/*"] },
|
|
["blocking"]
|
|
);
|
|
},
|
|
});
|
|
|
|
await extension.startup();
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
|
|
await promiseRestartManager({ lateStartup: false });
|
|
await extension.awaitStartup();
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: true,
|
|
});
|
|
|
|
let events = trackEvents(extension);
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
|
|
await testPersistentRequestStartup(extension, events, {
|
|
background: false,
|
|
delayedStart: false,
|
|
request: false,
|
|
});
|
|
|
|
AddonTestUtils.notifyLateStartup();
|
|
|
|
await extension.unload();
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
// Tests that moving permission to optional retains permission and that the
|
|
// persistent listeners are used as expected.
|
|
add_task(async function test_persistent_listener_after_sideload_upgrade() {
|
|
let id = "permission-sideload-upgrade@test";
|
|
let extensionData = {
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
browser_specific_settings: { gecko: { id } },
|
|
permissions: ["webRequest", "webRequestBlocking", "http://example.com/"],
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] },
|
|
["blocking"]
|
|
);
|
|
},
|
|
};
|
|
let xpi = AddonTestUtils.createTempWebExtensionFile(extensionData);
|
|
|
|
let extension = ExtensionTestUtils.expectExtension(id);
|
|
await AddonTestUtils.manuallyInstall(xpi);
|
|
await promiseStartupManager();
|
|
await extension.awaitStartup();
|
|
// Sideload install does not prime listeners
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
await extension.awaitMessage("got-request");
|
|
|
|
await promiseShutdownManager();
|
|
|
|
// Prepare a sideload update for the extension.
|
|
extensionData.manifest.version = "2.0";
|
|
extensionData.manifest.permissions = ["http://example.com/"];
|
|
extensionData.manifest.optional_permissions = [
|
|
"webRequest",
|
|
"webRequestBlocking",
|
|
];
|
|
xpi = AddonTestUtils.createTempWebExtensionFile(extensionData);
|
|
await AddonTestUtils.manuallyInstall(xpi);
|
|
|
|
await promiseStartupManager();
|
|
await extension.awaitStartup();
|
|
// Upgrades start the background when the extension is loaded, so
|
|
// primed listeners are cleared already and background events are
|
|
// already completed.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
persisted: true,
|
|
});
|
|
|
|
await extension.unload();
|
|
await promiseShutdownManager();
|
|
});
|
|
|
|
// Utility to install builtin addon
|
|
async function installBuiltinExtension(extensionData) {
|
|
let xpi = await AddonTestUtils.createTempWebExtensionFile(extensionData);
|
|
|
|
// The built-in location requires a resource: URL that maps to a
|
|
// jar: or file: URL. This would typically be something bundled
|
|
// into omni.ja but for testing we just use a temp file.
|
|
let base = Services.io.newURI(`jar:file:${xpi.path}!/`);
|
|
let resProto = Services.io
|
|
.getProtocolHandler("resource")
|
|
.QueryInterface(Ci.nsIResProtocolHandler);
|
|
resProto.setSubstitution("ext-test", base);
|
|
return AddonManager.installBuiltinAddon("resource://ext-test/");
|
|
}
|
|
|
|
function promisePostponeInstall(install) {
|
|
return new Promise((resolve, reject) => {
|
|
let listener = {
|
|
onInstallFailed: () => {
|
|
install.removeListener(listener);
|
|
reject(new Error("extension installation should not have failed"));
|
|
},
|
|
onInstallEnded: () => {
|
|
install.removeListener(listener);
|
|
reject(
|
|
new Error(
|
|
`extension installation should not have ended for ${install.addon.id}`
|
|
)
|
|
);
|
|
},
|
|
onInstallPostponed: () => {
|
|
install.removeListener(listener);
|
|
resolve();
|
|
},
|
|
};
|
|
|
|
install.addListener(listener);
|
|
install.install();
|
|
});
|
|
}
|
|
|
|
// Tests that moving permission to optional retains permission and that the
|
|
// persistent listeners are used as expected.
|
|
add_task(
|
|
async function test_persistent_listener_after_builtin_location_upgrade() {
|
|
let id = "permission-builtin-upgrade@test";
|
|
let extensionData = {
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
browser_specific_settings: { gecko: { id } },
|
|
permissions: [
|
|
"webRequest",
|
|
"webRequestBlocking",
|
|
"http://example.com/",
|
|
],
|
|
},
|
|
|
|
async background() {
|
|
browser.runtime.onUpdateAvailable.addListener(() => {
|
|
browser.test.sendMessage("postponed");
|
|
});
|
|
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] },
|
|
["blocking"]
|
|
);
|
|
},
|
|
};
|
|
await promiseStartupManager();
|
|
// If we use an extension wrapper via ExtensionTestUtils.expectExtension
|
|
// it will continue to handle messages even after the update, resulting
|
|
// in errors when it receives additional messages without any awaitMessage.
|
|
let promiseExtension = AddonTestUtils.promiseWebExtensionStartup(id);
|
|
await installBuiltinExtension(extensionData);
|
|
let extv1 = await promiseExtension;
|
|
assertPersistentListeners(
|
|
{ extension: extv1 },
|
|
"webRequest",
|
|
"onBeforeRequest",
|
|
{
|
|
primed: false,
|
|
}
|
|
);
|
|
|
|
// Prepare an update for the extension.
|
|
extensionData.manifest.version = "2.0";
|
|
let xpi = AddonTestUtils.createTempWebExtensionFile(extensionData);
|
|
let install = await AddonManager.getInstallForFile(xpi);
|
|
|
|
// Install the update and wait for the onUpdateAvailable event to complete.
|
|
let promiseUpdate = new Promise(resolve =>
|
|
extv1.once("test-message", (kind, msg) => {
|
|
if (msg == "postponed") {
|
|
resolve();
|
|
}
|
|
})
|
|
);
|
|
await Promise.all([promisePostponeInstall(install), promiseUpdate]);
|
|
await promiseShutdownManager();
|
|
|
|
// restarting allows upgrade to proceed
|
|
let extension = ExtensionTestUtils.expectExtension(id);
|
|
await promiseStartupManager();
|
|
await extension.awaitStartup();
|
|
// Upgrades start the background when the extension is loaded, so
|
|
// primed listeners are cleared already and background events are
|
|
// already completed.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
persisted: true,
|
|
});
|
|
|
|
await extension.unload();
|
|
|
|
// remove the builtin addon which will have restarted now.
|
|
let addon = await AddonManager.getAddonByID(id);
|
|
await addon.uninstall();
|
|
|
|
await promiseShutdownManager();
|
|
}
|
|
);
|
|
|
|
// Tests that moving permission to optional during a staged upgrade retains permission
|
|
// and that the persistent listeners are used as expected.
|
|
add_task(async function test_persistent_listener_after_staged_upgrade() {
|
|
AddonManager.checkUpdateSecurity = false;
|
|
let id = "persistent-staged-upgrade@test";
|
|
|
|
// register an update file.
|
|
AddonTestUtils.registerJSON(server, "/test_update.json", {
|
|
addons: {
|
|
"persistent-staged-upgrade@test": {
|
|
updates: [
|
|
{
|
|
version: "2.0",
|
|
update_link:
|
|
"http://example.com/addons/test_settings_staged_restart.xpi",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
});
|
|
|
|
let extensionData = {
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "2.0",
|
|
browser_specific_settings: {
|
|
gecko: { id, update_url: `http://example.com/test_update.json` },
|
|
},
|
|
permissions: ["http://example.com/"],
|
|
optional_permissions: ["webRequest", "webRequestBlocking"],
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] },
|
|
["blocking"]
|
|
);
|
|
browser.webRequest.onSendHeaders.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-sendheaders");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] }
|
|
);
|
|
// Force a staged updated.
|
|
browser.runtime.onUpdateAvailable.addListener(async details => {
|
|
if (details && details.version) {
|
|
// This should be the version of the pending update.
|
|
browser.test.assertEq("2.0", details.version, "correct version");
|
|
browser.test.sendMessage("delay");
|
|
}
|
|
});
|
|
},
|
|
};
|
|
|
|
// Prepare the update first.
|
|
server.registerFile(
|
|
`/addons/test_settings_staged_restart.xpi`,
|
|
AddonTestUtils.createTempWebExtensionFile(extensionData)
|
|
);
|
|
|
|
// Prepare the extension that will be updated.
|
|
extensionData.manifest.version = "1.0";
|
|
extensionData.manifest.permissions = [
|
|
"webRequest",
|
|
"webRequestBlocking",
|
|
"http://example.com/",
|
|
];
|
|
delete extensionData.manifest.optional_permissions;
|
|
extensionData.background = function () {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] },
|
|
["blocking"]
|
|
);
|
|
browser.webRequest.onBeforeSendHeaders.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-beforesendheaders");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] }
|
|
);
|
|
browser.webRequest.onSendHeaders.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-sendheaders");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] }
|
|
);
|
|
// Force a staged updated.
|
|
browser.runtime.onUpdateAvailable.addListener(async details => {
|
|
if (details && details.version) {
|
|
// This should be the version of the pending update.
|
|
browser.test.assertEq("2.0", details.version, "correct version");
|
|
browser.test.sendMessage("delay");
|
|
}
|
|
});
|
|
};
|
|
|
|
await promiseStartupManager();
|
|
let extension = ExtensionTestUtils.loadExtension(extensionData);
|
|
await extension.startup();
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
});
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeSendHeaders", {
|
|
primed: false,
|
|
});
|
|
assertPersistentListeners(extension, "webRequest", "onSendHeaders", {
|
|
primed: false,
|
|
});
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
await extension.awaitMessage("got-request");
|
|
await extension.awaitMessage("got-beforesendheaders");
|
|
await extension.awaitMessage("got-sendheaders");
|
|
ok(true, "Initial version received webRequest event");
|
|
|
|
let addon = await AddonManager.getAddonByID(id);
|
|
Assert.equal(addon.version, "1.0", "1.0 is loaded");
|
|
|
|
let update = await AddonTestUtils.promiseFindAddonUpdates(addon);
|
|
let install = update.updateAvailable;
|
|
Assert.ok(install, `install is available ${update.error}`);
|
|
|
|
await AddonTestUtils.promiseCompleteAllInstalls([install]);
|
|
|
|
Assert.equal(
|
|
install.state,
|
|
AddonManager.STATE_POSTPONED,
|
|
"update is staged for install"
|
|
);
|
|
await extension.awaitMessage("delay");
|
|
|
|
await promiseShutdownManager();
|
|
|
|
// restarting allows upgrade to proceed
|
|
await promiseStartupManager();
|
|
await extension.awaitStartup();
|
|
|
|
// Upgrades start the background when the extension is loaded, so
|
|
// primed listeners are cleared already and background events are
|
|
// already completed.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
persisted: true,
|
|
});
|
|
// this was removed in the upgrade background, should not be persisted.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeSendHeaders", {
|
|
primed: false,
|
|
persisted: false,
|
|
});
|
|
assertPersistentListeners(extension, "webRequest", "onSendHeaders", {
|
|
primed: false,
|
|
persisted: true,
|
|
});
|
|
|
|
await extension.unload();
|
|
await promiseShutdownManager();
|
|
AddonManager.checkUpdateSecurity = true;
|
|
});
|
|
|
|
// Tests that removing the permission releases the persistent listener.
|
|
add_task(async function test_persistent_listener_after_permission_removal() {
|
|
AddonManager.checkUpdateSecurity = false;
|
|
let id = "persistent-staged-remove@test";
|
|
|
|
// register an update file.
|
|
AddonTestUtils.registerJSON(server, "/test_remove.json", {
|
|
addons: {
|
|
"persistent-staged-remove@test": {
|
|
updates: [
|
|
{
|
|
version: "2.0",
|
|
update_link:
|
|
"http://example.com/addons/test_settings_staged_remove.xpi",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
});
|
|
|
|
let extensionData = {
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "2.0",
|
|
browser_specific_settings: {
|
|
gecko: { id, update_url: `http://example.com/test_remove.json` },
|
|
},
|
|
permissions: ["tabs", "http://example.com/"],
|
|
},
|
|
|
|
background() {
|
|
browser.test.sendMessage("loaded");
|
|
},
|
|
};
|
|
|
|
// Prepare the update first.
|
|
server.registerFile(
|
|
`/addons/test_settings_staged_remove.xpi`,
|
|
AddonTestUtils.createTempWebExtensionFile(extensionData)
|
|
);
|
|
|
|
await promiseStartupManager();
|
|
let extension = ExtensionTestUtils.loadExtension({
|
|
useAddonManager: "permanent",
|
|
manifest: {
|
|
version: "1.0",
|
|
browser_specific_settings: {
|
|
gecko: { id, update_url: `http://example.com/test_remove.json` },
|
|
},
|
|
permissions: ["webRequest", "webRequestBlocking", "http://example.com/"],
|
|
},
|
|
|
|
background() {
|
|
browser.webRequest.onBeforeRequest.addListener(
|
|
() => {
|
|
browser.test.sendMessage("got-request");
|
|
},
|
|
{ urls: ["http://example.com/data/file_sample.html"] },
|
|
["blocking"]
|
|
);
|
|
// Force a staged updated.
|
|
browser.runtime.onUpdateAvailable.addListener(async details => {
|
|
if (details && details.version) {
|
|
// This should be the version of the pending update.
|
|
browser.test.assertEq("2.0", details.version, "correct version");
|
|
browser.test.sendMessage("delay");
|
|
}
|
|
});
|
|
},
|
|
});
|
|
|
|
await extension.startup();
|
|
|
|
await ExtensionTestUtils.fetch(
|
|
"http://example.com/",
|
|
"http://example.com/data/file_sample.html"
|
|
);
|
|
await extension.awaitMessage("got-request");
|
|
ok(true, "Initial version received webRequest event");
|
|
|
|
let addon = await AddonManager.getAddonByID(id);
|
|
Assert.equal(addon.version, "1.0", "1.0 is loaded");
|
|
|
|
let update = await AddonTestUtils.promiseFindAddonUpdates(addon);
|
|
let install = update.updateAvailable;
|
|
Assert.ok(install, `install is available ${update.error}`);
|
|
|
|
await AddonTestUtils.promiseCompleteAllInstalls([install]);
|
|
|
|
Assert.equal(
|
|
install.state,
|
|
AddonManager.STATE_POSTPONED,
|
|
"update is staged for install"
|
|
);
|
|
await extension.awaitMessage("delay");
|
|
|
|
await promiseShutdownManager();
|
|
|
|
// restarting allows upgrade to proceed
|
|
await promiseStartupManager({ lateStartup: false });
|
|
await extension.awaitStartup();
|
|
await extension.awaitMessage("loaded");
|
|
|
|
// Upgrades start the background when the extension is loaded, so
|
|
// primed listeners are cleared already and background events are
|
|
// already completed.
|
|
assertPersistentListeners(extension, "webRequest", "onBeforeRequest", {
|
|
primed: false,
|
|
persisted: false,
|
|
});
|
|
|
|
await extension.unload();
|
|
await promiseShutdownManager();
|
|
AddonManager.checkUpdateSecurity = true;
|
|
});
|