Last active
June 12, 2019 17:42
-
-
Save biancadanforth/0fa493144437bce56a9b9e4d490bd791 to your computer and use it in GitHub Desktop.
temporary backup for bug 1542035 adding rest of test coverage for issue #4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Any copyright is dedicated to the Public Domain. | |
http://creativecommons.org/publicdomain/zero/1.0/ */ | |
/* globals browser */ | |
"use strict"; | |
const { | |
AddonTestUtils, | |
} = ChromeUtils.import("resource://testing-common/AddonTestUtils.jsm"); | |
const { | |
FileUtils, | |
} = ChromeUtils.import("resource://gre/modules/FileUtils.jsm"); | |
const { | |
ExtensionTestUtils, | |
} = ChromeUtils.import("resource://testing-common/ExtensionXPCShellUtils.jsm"); | |
const { | |
createAppInfo, | |
promiseStartupManager, | |
} = AddonTestUtils; | |
const LEAVE_UUID_PREF = "extensions.webextensions.keepUuidOnUninstall"; | |
const LEAVE_STORAGE_PREF = "extensions.webextensions.keepStorageOnUninstall"; | |
const EXTENSION_STORAGE_ENABLED_PREF = "devtools.storage.extensionStorage.enabled"; | |
AddonTestUtils.init(this); | |
createAppInfo("[email protected]", "XPCShell", "1", "42"); | |
ExtensionTestUtils.init(this); | |
// This storage actor is gated behind a pref, so make sure it is enabled first | |
Services.prefs.setBoolPref(EXTENSION_STORAGE_ENABLED_PREF, true); | |
registerCleanupFunction(() => { | |
Services.prefs.clearUserPref(EXTENSION_STORAGE_ENABLED_PREF); | |
}); | |
/** | |
* Starts up and connects the Debugger server to the DevTools client (both in the main | |
* process) by listening over an nsIPipe, so that they can send remote debugging | |
* protocol messages to each other. | |
* | |
* @return {Promise} Resolves with a client object when the debugger has started up. | |
*/ | |
async function startDebugger() { | |
DebuggerServer.init(); | |
DebuggerServer.registerAllActors(); | |
const transport = DebuggerServer.connectPipe(); | |
const client = new DebuggerClient(transport); | |
await client.connect(); | |
return client; | |
} | |
/** | |
* Set up the equivalent of an `about:debugging` toolbox for a given extension, minus | |
* the toolbox. | |
* | |
* @param {String} id - The id for the extension to be targeted by the toolbox. | |
* @return {Object} Resolves with the web extension actor front and target objects when | |
* the debugger has been connected to the extension. | |
*/ | |
async function setupExtensionDebugging(id) { | |
const client = await startDebugger(); | |
const front = await client.mainRoot.getAddon({id}); | |
// Starts a DevTools server in the extension child process. | |
const target = await front.connect(); | |
return {front, target}; | |
} | |
/** | |
* Loads and starts up a test extension given the provided extension configuration. | |
* | |
* @param {Object} extConfig - The extension configuration object | |
* @return {ExtensionWrapper} extension - Resolves with an extension object once the | |
* extension has started up. | |
*/ | |
async function startupExtension(extConfig) { | |
const extension = ExtensionTestUtils.loadExtension(extConfig); | |
await extension.startup(); | |
return extension; | |
} | |
/** | |
* Opens the addon debugger's storage panel | |
* | |
* @param {String} - id, The addon id | |
* @return {Object} - Resolves with the web extension actor target and extensionStorage | |
* store objects when the panel has been opened. | |
*/ | |
async function openAddonStoragePanel(id) { | |
const {target} = await setupExtensionDebugging(id); | |
const storageFront = await target.getFront("storage"); | |
const stores = await storageFront.listStores(); | |
const extensionStorage = stores.extensionStorage || null; | |
return {target, extensionStorage}; | |
} | |
/** | |
* Builds the extension configuration object passed into ExtensionTestUtils.loadExtension | |
* | |
* @param {Object} options - Options, if any, to add to the configuration | |
* @param {Function} options.background - A function comprising the test extension's | |
* background script if provided | |
* @param {Object} options.files - An object whose keys correspond to file names and | |
* values map to the file contents | |
* @param {Object} options.manifest - An object representing the extension's manifest | |
* @return {Object} - The extension configuration object | |
*/ | |
function getExtensionConfig(options = {}) { | |
const {manifest, ...otherOptions} = options; | |
const baseConfig = { | |
manifest: { | |
...manifest, | |
permissions: ["storage"], | |
}, | |
useAddonManager: "temporary", | |
}; | |
return { | |
...baseConfig, | |
...otherOptions, | |
}; | |
} | |
/** | |
* An extension script that can be used in any extension context (e.g. as a background | |
* script or as an extension page script loaded in a tab). | |
*/ | |
async function extensionScriptWithMessageListener() { | |
browser.test.onMessage.addListener(async (msg, ...args) => { | |
let value = null; | |
switch (msg) { | |
case "storage-local-set": | |
await browser.storage.local.set(args[0]); | |
break; | |
case "storage-local-get": | |
value = (await browser.storage.local.get(args[0]))[args[0]]; | |
break; | |
case "storage-local-remove": | |
await browser.storage.local.remove(args[0]); | |
break; | |
case "storage-local-clear": | |
await browser.storage.local.clear(); | |
break; | |
default: | |
browser.test.fail(`Unexpected test message: ${msg}`); | |
} | |
browser.test.sendMessage(`${msg}:done`, value); | |
}); | |
browser.test.sendMessage("extension-origin", window.location.origin); | |
} | |
/** | |
* Shared files for a test extension that has no background page but adds storage | |
* items via a transient extension page in a tab | |
*/ | |
const ext_no_bg = { | |
files: { | |
"extension_page_in_tab.html": `<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
</head> | |
<body> | |
<h1>Extension Page in a Tab</h1> | |
<script src="extension_page_in_tab.js"></script> | |
</body> | |
</html>`, | |
"extension_page_in_tab.js": extensionScriptWithMessageListener, | |
}, | |
}; | |
/** | |
* Shutdown procedure common to all tasks. | |
* | |
* @param {Object} extension - The test extension | |
* @param {Object} target - The web extension actor targeted by the DevTools client | |
*/ | |
async function shutdown(extension, target) { | |
if (target) { | |
await target.destroy(); | |
} | |
await extension.unload(); | |
} | |
/** | |
* Mocks the missing 'storage/permanent' directory needed by the "indexedDB" | |
* storage actor's 'preListStores' method (called when 'listStores' is called). This | |
* directory exists in a full browser i.e. mochitest. | |
*/ | |
function createMissingIndexedDBDirs() { | |
const dir = (Services.dirsvc.get("ProfD", Ci.nsIFile)).clone(); | |
dir.append("storage"); | |
if (!dir.exists()) { | |
dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); | |
} | |
dir.append("permanent"); | |
if (!dir.exists()) { | |
dir.create(dir.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); | |
} | |
Assert.ok(dir.exists(), "Should have a 'storage/permanent' dir in the profile dir"); | |
} | |
add_task(async function setup() { | |
await promiseStartupManager(); | |
createMissingIndexedDBDirs(); | |
}); | |
add_task(async function test_extension_store_exists() { | |
const extension = await startupExtension(getExtensionConfig()); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
ok(extensionStorage, "Should have an extensionStorage store"); | |
await shutdown(extension, target); | |
}); | |
add_task(async function test_extension_origin_matches_debugger_target() { | |
async function background() { | |
browser.test.sendMessage("extension-origin", window.location.origin); | |
} | |
const extension = await startupExtension(getExtensionConfig({background})); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const {hosts} = extensionStorage; | |
const expectedHost = await extension.awaitMessage("extension-origin"); | |
ok(expectedHost in hosts, | |
"Should have the expected extension host in the extensionStorage store"); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: Bg page adds item while storage panel is open. | |
* - Load extension with background page. | |
* - Open the add-on debugger storage panel. | |
* - With the panel still open, add an item from the background page. | |
* - The data in the panel should match the item added by the extension. | |
*/ | |
add_task(async function test_panel_live_updates() { | |
const extension = await startupExtension( | |
getExtensionConfig({background: extensionScriptWithMessageListener}), | |
); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const host = await extension.awaitMessage("extension-origin"); | |
let {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual(data, [], "Got the expected results on empty storage.local"); | |
info("Waiting for extension to bulk add 50 items to storage local"); | |
const bulkStorageItems = {}; | |
// limited by MAX_STORE_OBJECT_COUNT in devtools/server/actors/storage.js | |
const numItems = 44; | |
for (let i = 1; i <= numItems; i++) { | |
bulkStorageItems[i] = i; | |
} | |
extension.sendMessage("storage-local-set", { | |
...bulkStorageItems, | |
a: 123, | |
b: [4, 5], | |
c: {d: 678}, | |
d: true, | |
e: "hi", | |
f: null, | |
}); | |
await extension.awaitMessage("storage-local-set:done"); | |
info("Confirming items added by extension match items in extensionStorage store"); | |
const bulkStorageObjects = []; | |
for (const [name, value] of Object.entries(bulkStorageItems)) { | |
bulkStorageObjects.push({ | |
area: "local", | |
name, | |
value: {str: String(value)}, | |
editable: true, | |
}); | |
} | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[ | |
...bulkStorageObjects, | |
{area: "local", name: "a", value: {str: "123"}, editable: true}, | |
{area: "local", name: "b", value: {str: "[4,5]"}, editable: true}, | |
{area: "local", name: "c", value: {str: "{\"d\":678}"}, editable: true}, | |
{area: "local", name: "d", value: {str: "true"}, editable: true}, | |
{area: "local", name: "e", value: {str: "hi"}, editable: true}, | |
{area: "local", name: "f", value: {str: "null"}, editable: true}, | |
], | |
"Got the expected results on populated storage.local" | |
); | |
info("Waiting for extension to edit a few storage item values"); | |
extension.sendMessage("storage-local-set", { | |
a: ["c", "d"], | |
b: 456, | |
c: false, | |
}); | |
await extension.awaitMessage("storage-local-set:done"); | |
info("Confirming items edited by extension match items in extensionStorage store"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[ | |
...bulkStorageObjects, | |
{area: "local", name: "a", value: {str: "[\"c\",\"d\"]"}, editable: true}, | |
{area: "local", name: "b", value: {str: "456"}, editable: true}, | |
{area: "local", name: "c", value: {str: "false"}, editable: true}, | |
{area: "local", name: "d", value: {str: "true"}, editable: true}, | |
{area: "local", name: "e", value: {str: "hi"}, editable: true}, | |
{area: "local", name: "f", value: {str: "null"}, editable: true}, | |
], | |
"Got the expected results on populated storage.local" | |
); | |
info("Waiting for extension to remove a few storage item values"); | |
extension.sendMessage("storage-local-remove", ["d", "e", "f"]); | |
await extension.awaitMessage("storage-local-remove:done"); | |
info("Confirming items removed by extension were removed in extensionStorage store"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[ | |
...bulkStorageObjects, | |
{area: "local", name: "a", value: {str: "[\"c\",\"d\"]"}, editable: true}, | |
{area: "local", name: "b", value: {str: "456"}, editable: true}, | |
{area: "local", name: "c", value: {str: "false"}, editable: true}, | |
], | |
"Got the expected results on populated storage.local" | |
); | |
info("Waiting for extension to remove all remaining storage items"); | |
extension.sendMessage("storage-local-clear"); | |
await extension.awaitMessage("storage-local-clear:done"); | |
info("Confirming extensionStorage store was cleared"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[], | |
"Got the expected results on populated storage.local" | |
); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: No bg page. Transient page adds item before storage panel opened. | |
* - Load extension with no background page. | |
* - Open an extension page in a tab that adds a local storage item. | |
* - With the extension page still open, open the add-on storage panel. | |
* - The data in the storage panel should match the items added by the extension. | |
*/ | |
add_task(async function test_panel_data_matches_extension_with_transient_page_open() { | |
const extension = await startupExtension(getExtensionConfig({files: ext_no_bg.files})); | |
const url = extension.extension.baseURI.resolve("extension_page_in_tab.html"); | |
const contentPage = await ExtensionTestUtils.loadContentPage(url, {extension}); | |
const host = await extension.awaitMessage("extension-origin"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
await contentPage.close(); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: No bg page. Transient page adds item then closes before storage panel opened. | |
* - Load extension with no background page. | |
* - Open an extension page in a tab that adds a local storage item. | |
* - Close all extension pages. | |
* - Open the add-on storage panel. | |
* - The data in the storage panel should match the item added by the extension. | |
*/ | |
add_task(async function test_panel_data_matches_extension_with_no_pages_open() { | |
const extension = await startupExtension(getExtensionConfig({files: ext_no_bg.files})); | |
const url = extension.extension.baseURI.resolve("extension_page_in_tab.html"); | |
const contentPage = await ExtensionTestUtils.loadContentPage(url, {extension}); | |
const host = await extension.awaitMessage("extension-origin"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
await contentPage.close(); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: No bg page. Storage panel live updates when a transient page adds an item. | |
* - Load extension with no background page. | |
* - Open the add-on storage panel. | |
* - With the storage panel still open, open an extension page in a new tab that adds an | |
* item. | |
* - Assert: | |
* - The data in the storage panel should live update to match the item added by the | |
* extension. | |
* - If an extension page adds the same data again, the data in the storage panel should | |
* not change. | |
*/ | |
add_task(async function test_panel_data_live_updates_for_extension_without_bg_page() { | |
const extension = await startupExtension(getExtensionConfig({files: ext_no_bg.files})); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const url = extension.extension.baseURI.resolve("extension_page_in_tab.html"); | |
const contentPage = await ExtensionTestUtils.loadContentPage(url, {extension}); | |
const host = await extension.awaitMessage("extension-origin"); | |
let {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual(data, [], "Got the expected results on empty storage.local"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"The results are unchanged when an extension page adds duplicate items" | |
); | |
await contentPage.close(); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: Bg page adds item while storage panel is open. Panel edits item's value. | |
* - Load extension with background page. | |
* - Open the add-on storage panel. | |
* - With the storage panel still open, add item from the background page. | |
* - Edit the value of the item in the storage panel | |
* - Assert: | |
* - The data in the storage panel should match the item added by the extension. | |
* - The storage actor is correctly parsing and setting the string representation of | |
* the value in the storage local database when the item's value is edited in the | |
* storage panel | |
*/ | |
add_task(async function test_editing_items_in_panel_parses_supported_values_correctly() { | |
const extension = await startupExtension( | |
getExtensionConfig({background: extensionScriptWithMessageListener}), | |
); | |
const host = await extension.awaitMessage("extension-origin"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
const oldItem = {a: 123}; | |
const key = Object.keys(oldItem)[0]; | |
const oldValue = oldItem[key]; | |
// A tuple representing information for a new value entered into the panel for oldItem: | |
// [ | |
// value, | |
// editItem string representation of value, | |
// toStoreObject string representation of value, | |
// ] | |
const valueInfo = [ | |
[true, "true", "true"], | |
["hi", "hi", "hi"], | |
[456, "456", "456"], | |
[{b: 789}, "{b: 789}", "{\"b\":789}"], | |
[[1, 2, 3], "[1, 2, 3]", "[1,2,3]"], | |
[null, "null", "null"], | |
]; | |
for (const [value, editItemValueStr, toStoreObjectValueStr] of valueInfo) { | |
info("Setting a storage item through the extension"); | |
extension.sendMessage("storage-local-set", oldItem); | |
await extension.awaitMessage("storage-local-set:done"); | |
info("Editing the storage item in the panel with a new value of a different type"); | |
// When the user edits an item in the panel, they are entering a string into a | |
// textbox. This string is parsed by the storage actor's editItem method. | |
await extensionStorage.editItem({ | |
host, | |
field: "value", | |
items: {name: key, value: editItemValueStr}, | |
oldValue, | |
}); | |
info("Verifying item in the storage actor matches the item edited in the panel"); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: key, value: {str: toStoreObjectValueStr}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
// The view layer is separate from the database layer; therefore while values are | |
// stringified (via toStoreObject) for display in the client, the value (and its type) | |
// in the database is unchanged. | |
info("Verifying the expected new value matches the value fetched in the extension"); | |
extension.sendMessage("storage-local-get", key); | |
const extValue = await extension.awaitMessage("storage-local-get:done"); | |
Assert.deepEqual( | |
value, | |
extValue, | |
`The string value ${editItemValueStr} was correctly parsed to ${value}` | |
); | |
} | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: Storage panel shows extension storage data added prior to extension startup | |
* - Load extension that adds a storage item | |
* - Uninstall the extension | |
* - Reinstall the extension | |
* - Open the add-on storage panel. | |
* - The data in the storage panel should match the data added the first time the extension | |
* was installed | |
* Related test case: Storage panel shows extension storage data when an extension that has | |
* already migrated to the IndexedDB storage backend prior to extension startup adds | |
* another storage item. | |
* - (Building from previous steps) | |
* - The reinstalled extension adds a storage item | |
* - The data in the storage panel should live update with both items: the item added from | |
* the first and the item added from the reinstall. | |
*/ | |
add_task(async function test_panel_data_matches_data_added_prior_to_ext_startup() { | |
// The pref to leave the addonid->uuid mapping around after uninstall so that we can | |
// re-attach to the same storage | |
Services.prefs.setBoolPref(LEAVE_UUID_PREF, true); | |
// The pref to prevent cleaning up storage on uninstall | |
Services.prefs.setBoolPref(LEAVE_STORAGE_PREF, true); | |
let extension = await startupExtension( | |
getExtensionConfig({background: extensionScriptWithMessageListener}), | |
); | |
const host = await extension.awaitMessage("extension-origin"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
await shutdown(extension); | |
// Reinstall the same extension | |
extension = await startupExtension( | |
getExtensionConfig({background: extensionScriptWithMessageListener}) | |
); | |
await extension.awaitMessage("extension-origin"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
let {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
// Related test case | |
extension.sendMessage("storage-local-set", {b: 456}); | |
await extension.awaitMessage("storage-local-set:done"); | |
data = (await extensionStorage.getStoreObjects(host)).data; | |
Assert.deepEqual( | |
data, | |
[ | |
{area: "local", name: "a", value: {str: "123"}, editable: true}, | |
{area: "local", name: "b", value: {str: "456"}, editable: true}, | |
], | |
"Got the expected results on populated storage.local" | |
); | |
Services.prefs.setBoolPref(LEAVE_STORAGE_PREF, false); | |
Services.prefs.setBoolPref(LEAVE_UUID_PREF, false); | |
await shutdown(extension, target); | |
}); | |
add_task(function cleanup_for_test_panel_data_matches_data_added_prior_to_ext_startup() { | |
Services.prefs.clearUserPref(LEAVE_UUID_PREF); | |
Services.prefs.clearUserPref(LEAVE_STORAGE_PREF); | |
}); | |
/** | |
* Test case: Bg page adds an item to storage. With storage panel open, reload extension. | |
* - Load extension with background page that adds a storage item on message. | |
* - Open the add-on storage panel. | |
* - With the storage panel still open, reload the extension. | |
* - The data in the storage panel should match the item added prior to reloading. | |
*/ | |
add_task(async function test_panel_live_reload() { | |
const EXTENSION_ID = "[email protected]"; | |
let manifest = { | |
version: "1.0", | |
applications: { | |
gecko: { | |
id: EXTENSION_ID, | |
}, | |
}, | |
}; | |
info("Loading extension version 1.0"); | |
const extension = await startupExtension( | |
getExtensionConfig({ | |
manifest, | |
background: extensionScriptWithMessageListener, | |
}) | |
); | |
info("Waiting for message from test extension"); | |
const host = await extension.awaitMessage("extension-origin"); | |
info("Adding storage item"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
manifest = { | |
...manifest, | |
version: "2.0", | |
}; | |
// "Reload" is most similar to an upgrade, as e.g. storage data is preserved | |
info("Update to version 2.0"); | |
await extension.upgrade( | |
getExtensionConfig({ | |
manifest, | |
background: extensionScriptWithMessageListener, | |
}), | |
); | |
await extension.awaitMessage("extension-origin"); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: Transient page adds an item to storage. With storage panel open, | |
* reload extension. | |
* - Load extension with no background page. | |
* - Open transient page that adds a storage item on message. | |
* - Open the add-on storage panel. | |
* - With the storage panel still open, reload the extension. | |
* - The data in the storage panel should match the item added prior to reloading. | |
*/ | |
add_task(async function test_panel_live_reload_for_extension_without_bg_page() { | |
const EXTENSION_ID = "[email protected]"; | |
let manifest = { | |
version: "1.0", | |
applications: { | |
gecko: { | |
id: EXTENSION_ID, | |
}, | |
}, | |
}; | |
info("Loading and starting extension version 1.0"); | |
const extension = await startupExtension(getExtensionConfig({ | |
manifest, | |
files: ext_no_bg.files, | |
})); | |
info("Opening extension page in a tab"); | |
const url = extension.extension.baseURI.resolve("extension_page_in_tab.html"); | |
const contentPage = await ExtensionTestUtils.loadContentPage(url, {extension}); | |
const host = await extension.awaitMessage("extension-origin"); | |
info("Waiting for extension page in a tab to add storage item"); | |
extension.sendMessage("storage-local-set", {a: 123}); | |
await extension.awaitMessage("storage-local-set:done"); | |
await contentPage.close(); | |
info("Opening storage panel"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
manifest = { | |
...manifest, | |
version: "2.0", | |
}; | |
// "Reload" is most similar to an upgrade, as e.g. storage data is preserved | |
info("Updating extension to version 2.0"); | |
await extension.upgrade( | |
getExtensionConfig({ | |
manifest, | |
files: ext_no_bg.files, | |
}) | |
); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[{area: "local", name: "a", value: {str: "123"}, editable: true}], | |
"Got the expected results on populated storage.local" | |
); | |
await shutdown(extension, target); | |
}); | |
/** | |
* Test case: Bg page auto adds item(s). With storage panel open, reload extension. | |
* - Load extension with background page that automatically adds a storage item on startup. | |
* - Open the add-on storage panel. | |
* - With the storage panel still open, reload the extension. | |
* - The data in the storage panel should match the item(s) added by the reloaded | |
* extension. | |
*/ | |
add_task(async function test_panel_live_reload_when_extension_auto_adds_items() { | |
async function background() { | |
await browser.storage.local.set({a: {b: 123}, c: {d: 456}}); | |
browser.test.sendMessage("extension-origin", window.location.origin); | |
} | |
const EXTENSION_ID = "[email protected]"; | |
let manifest = { | |
version: "1.0", | |
applications: { | |
gecko: { | |
id: EXTENSION_ID, | |
}, | |
}, | |
}; | |
info("Loading and starting extension version 1.0"); | |
const extension = await startupExtension(getExtensionConfig({manifest, background})); | |
info("Waiting for message from test extension"); | |
const host = await extension.awaitMessage("extension-origin"); | |
info("Opening storage panel"); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
manifest = { | |
...manifest, | |
version: "2.0", | |
}; | |
// "Reload" is most similar to an upgrade, as e.g. storage data is preserved | |
info("Update to version 2.0"); | |
await extension.upgrade( | |
getExtensionConfig({ | |
manifest, | |
background, | |
}), | |
); | |
await extension.awaitMessage("extension-origin"); | |
const {data} = await extensionStorage.getStoreObjects(host); | |
Assert.deepEqual( | |
data, | |
[ | |
{area: "local", name: "a", value: {str: "{\"b\":123}"}, editable: true}, | |
{area: "local", name: "c", value: {str: "{\"d\":456}"}, editable: true}, | |
], | |
"Got the expected results on populated storage.local" | |
); | |
await shutdown(extension, target); | |
}); | |
/* | |
* This task should be last, as it sets a pref to disable the extensionStorage | |
* storage actor. Since this pref is set at the beginning of the file, it | |
* already will be cleared via registerCleanupFunction when the test finishes. | |
*/ | |
add_task(async function test_extensionStorage_store_disabled_on_pref() { | |
Services.prefs.setBoolPref(EXTENSION_STORAGE_ENABLED_PREF, false); | |
const extension = await startupExtension(getExtensionConfig()); | |
const {target, extensionStorage} = await openAddonStoragePanel(extension.id); | |
ok( | |
extensionStorage === null, | |
"Should not have an extensionStorage store when pref disabled" | |
); | |
await shutdown(extension, target); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment