test_addon_reload.js (3403B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { AddonManager } = ChromeUtils.importESModule( 7 "resource://gre/modules/AddonManager.sys.mjs" 8 ); 9 10 function promiseAddonEvent(event) { 11 return new Promise(resolve => { 12 const listener = { 13 [event](...args) { 14 AddonManager.removeAddonListener(listener); 15 resolve(args); 16 }, 17 }; 18 19 AddonManager.addAddonListener(listener); 20 }); 21 } 22 23 function promiseWebExtensionStartup() { 24 const { Management } = ChromeUtils.importESModule( 25 "resource://gre/modules/Extension.sys.mjs" 26 ); 27 28 return new Promise(resolve => { 29 const listener = (evt, extension) => { 30 Management.off("ready", listener); 31 resolve(extension); 32 }; 33 34 Management.on("ready", listener); 35 }); 36 } 37 38 async function reloadAddon(addonFront) { 39 // The add-on will be re-installed after a successful reload. 40 const onInstalled = promiseAddonEvent("onInstalled"); 41 await addonFront.reload(); 42 await onInstalled; 43 } 44 45 function getSupportFile(path) { 46 const allowMissing = false; 47 return do_get_file(path, allowMissing); 48 } 49 50 add_task(async function testReloadExitedAddon() { 51 await startupAddonsManager(); 52 53 DevToolsServer.init(); 54 DevToolsServer.registerAllActors(); 55 56 const client = new DevToolsClient(DevToolsServer.connectPipe()); 57 await client.connect(); 58 59 // Install our main add-on to trigger reloads on. 60 const addonFile = getSupportFile("addons/web-extension"); 61 const [installedAddon] = await Promise.all([ 62 AddonManager.installTemporaryAddon(addonFile), 63 promiseWebExtensionStartup(), 64 ]); 65 66 // Install a decoy add-on. 67 const addonFile2 = getSupportFile("addons/web-extension2"); 68 const [installedAddon2] = await Promise.all([ 69 AddonManager.installTemporaryAddon(addonFile2), 70 promiseWebExtensionStartup(), 71 ]); 72 73 const addonFront = await client.mainRoot.getAddon({ id: installedAddon.id }); 74 75 await Promise.all([reloadAddon(addonFront), promiseWebExtensionStartup()]); 76 77 // Uninstall the decoy add-on, which should cause its actor to exit. 78 const onUninstalled = promiseAddonEvent("onUninstalled"); 79 installedAddon2.uninstall(); 80 await onUninstalled; 81 82 // Try to re-list all add-ons after a reload. 83 // This was throwing an exception because of the exited actor. 84 const newAddonFront = await client.mainRoot.getAddon({ 85 id: installedAddon.id, 86 }); 87 equal(newAddonFront.id, addonFront.id); 88 89 // The fronts should be the same after the reload 90 equal(newAddonFront, addonFront); 91 92 const onAddonListChanged = client.mainRoot.once("addonListChanged"); 93 94 // Install an upgrade version of the first add-on. 95 const addonUpgradeFile = getSupportFile("addons/web-extension-upgrade"); 96 const [upgradedAddon] = await Promise.all([ 97 AddonManager.installTemporaryAddon(addonUpgradeFile), 98 promiseWebExtensionStartup(), 99 ]); 100 101 // Waiting for addonListChanged unsolicited event 102 await onAddonListChanged; 103 104 // re-list all add-ons after an upgrade. 105 const upgradedAddonFront = await client.mainRoot.getAddon({ 106 id: upgradedAddon.id, 107 }); 108 equal(upgradedAddonFront.id, addonFront.id); 109 // The fronts should be the same after the upgrade. 110 equal(upgradedAddonFront, addonFront); 111 112 // The addon metadata has been updated. 113 equal(upgradedAddonFront.name, "Test Addons Actor Upgrade"); 114 115 await close(client); 116 });