test_webextension_descriptor.js (5038B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { ExtensionTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/ExtensionXPCShellUtils.sys.mjs" 8 ); 9 10 const DistinctDevToolsServer = getDistinctDevToolsServer(); 11 ExtensionTestUtils.init(this); 12 13 add_setup(async () => { 14 Services.prefs.setBoolPref("extensions.blocklist.enabled", false); 15 await startupAddonsManager(); 16 17 // We intentionally generate install-time manifest warnings, so don't trigger 18 // the special test-only mode of converting them to errors. 19 Services.prefs.setBoolPref( 20 "extensions.webextensions.warnings-as-errors", 21 false 22 ); 23 24 DistinctDevToolsServer.init(); 25 DistinctDevToolsServer.registerAllActors(); 26 }); 27 28 // Verifies: 29 // - listAddons 30 // - WebExtensionDescriptorActor output 31 // Also a regression test for bug 1837185, that AddonManager.sys.mjs and 32 // ExtensionParent.sys.mjs are imported from the correct loader. 33 add_task(async function test_listAddons_and_WebExtensionDescriptor() { 34 const transport = DistinctDevToolsServer.connectPipe(); 35 const client = new DevToolsClient(transport); 36 await client.connect(); 37 38 const getRootResponse = await client.mainRoot.getRoot(); 39 40 ok(getRootResponse, "received a response after calling RootActor::getRoot"); 41 ok(getRootResponse.addonsActor, "getRoot returned an addonsActor id"); 42 43 const ADDON_ID = "with@warning"; 44 const extension = ExtensionTestUtils.loadExtension({ 45 useAddonManager: "permanent", 46 manifest: { 47 name: "DummyExtensionWithUnknownManifestKey", 48 unknown_manifest_key: "this is an unknown manifest key", 49 browser_specific_settings: { gecko: { id: ADDON_ID } }, 50 }, 51 background: `browser.test.sendMessage("background_started");`, 52 }); 53 await extension.startup(); 54 await extension.awaitMessage("background_started"); 55 56 // listAddons: addon after new install. 57 { 58 const listAddonsResponse = await client.mainRoot.listAddons(); 59 const addon = listAddonsResponse.find(a => a.id === ADDON_ID); 60 ok(addon, "listAddons() returns a list of add-ons including with@warning"); 61 62 // Inspect all raw properties of the message, to make sure that we always 63 // have full coverage for all current and future properties. 64 const { actor, url, warnings, ...addonMinusSomeKeys } = addon._form; 65 const actorPattern = /^server\d+\.conn\d+\.webExtensionDescriptor\d+$/; 66 ok(actorPattern.test(actor), `actor is webExtensionDescriptor: ${actor}`); 67 // We don't care about the exact path, just a dummy check: 68 ok(url.endsWith(".xpi"), `url is path to the xpi file`); 69 70 deepEqual( 71 warnings, 72 [ 73 "Reading manifest: Warning processing unknown_manifest_key: An unexpected property was found in the WebExtension manifest.", 74 ], 75 "Can retrieve warnings." 76 ); 77 78 // Verify that the other remaining keys have a meaningful value. 79 // This is mainly to have some form of verification on the value of the 80 // properties. If this check ever fails, double-check whether the proposed 81 // change makes sense and if it does just update the test expectation here. 82 deepEqual( 83 addonMinusSomeKeys, 84 { 85 backgroundScriptStatus: undefined, 86 debuggable: true, 87 hidden: false, 88 iconDataURL: undefined, 89 iconURL: null, 90 id: ADDON_ID, 91 isSystem: false, 92 isWebExtension: true, 93 manifestURL: `moz-extension://${extension.uuid}/manifest.json`, 94 name: "DummyExtensionWithUnknownManifestKey", 95 persistentBackgroundScript: true, 96 temporarilyInstalled: false, 97 traits: { 98 supportsReloadDescriptor: true, 99 watcher: true, 100 }, 101 }, 102 "WebExtensionDescriptorActor content matches the add-on" 103 ); 104 } 105 106 await extension.upgrade({ 107 manifest: { 108 name: "Updated_extension", 109 new_unknown_manifest_key: "different warning than before", 110 browser_specific_settings: { gecko: { id: ADDON_ID } }, 111 }, 112 background: `browser.test.sendMessage("updated_done");`, 113 }); 114 await extension.awaitMessage("updated_done"); 115 116 // listAddons: addon after update. 117 { 118 const listAddonsResponse = await client.mainRoot.listAddons(); 119 const addon = listAddonsResponse.find(a => a.id === ADDON_ID); 120 ok(addon, "listAddons() should still list the add-on after update"); 121 equal(addon.name, "Updated_extension", "Got updated name"); 122 deepEqual( 123 addon.warnings, 124 [ 125 "Reading manifest: Warning processing new_unknown_manifest_key: An unexpected property was found in the WebExtension manifest.", 126 ], 127 "Can retrieve new warnings for updated add-on." 128 ); 129 } 130 131 await extension.unload(); 132 133 // listAddons: addon after removal - gone. 134 { 135 const listAddonsResponse = await client.mainRoot.listAddons(); 136 const addon = listAddonsResponse.find(a => a.id === ADDON_ID); 137 deepEqual(addon, null, "Add-on should be gone after removal"); 138 } 139 140 await client.close(); 141 });