diff options
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js')
-rw-r--r-- | toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js b/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js new file mode 100644 index 0000000000..cfa49c334b --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_storage_tab.js @@ -0,0 +1,245 @@ +"use strict"; + +const { ExtensionStorageIDB } = ChromeUtils.importESModule( + "resource://gre/modules/ExtensionStorageIDB.sys.mjs" +); + +async function test_multiple_pages() { + let extension = ExtensionTestUtils.loadExtension({ + async background() { + function awaitMessage(expectedMsg, api = "test") { + return new Promise(resolve => { + browser[api].onMessage.addListener(function listener(msg) { + if (msg === expectedMsg) { + browser[api].onMessage.removeListener(listener); + resolve(); + } + }); + }); + } + + let tabReady = awaitMessage("tab-ready", "runtime"); + + try { + let storage = browser.storage.local; + + browser.test.sendMessage( + "load-page", + browser.runtime.getURL("tab.html") + ); + await awaitMessage("page-loaded"); + await tabReady; + + let result = await storage.get("key"); + browser.test.assertEq(undefined, result.key, "Key should be undefined"); + + await browser.runtime.sendMessage("tab-set-key"); + + result = await storage.get("key"); + browser.test.assertEq( + JSON.stringify({ foo: { bar: "baz" } }), + JSON.stringify(result.key), + "Key should be set to the value from the tab" + ); + + browser.test.sendMessage("remove-page"); + await awaitMessage("page-removed"); + + result = await storage.get("key"); + browser.test.assertEq( + JSON.stringify({ foo: { bar: "baz" } }), + JSON.stringify(result.key), + "Key should still be set to the value from the tab" + ); + + browser.test.notifyPass("storage-multiple"); + } catch (e) { + browser.test.fail(`Error: ${e} :: ${e.stack}`); + browser.test.notifyFail("storage-multiple"); + } + }, + + files: { + "tab.html": `<!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <script src="tab.js"></script> + </head> + </html>`, + + "tab.js"() { + browser.test.log("tab"); + browser.runtime.onMessage.addListener(msg => { + if (msg == "tab-set-key") { + return browser.storage.local.set({ key: { foo: { bar: "baz" } } }); + } + }); + + browser.runtime.sendMessage("tab-ready"); + }, + }, + + manifest: { + permissions: ["storage"], + }, + }); + + let contentPage; + extension.onMessage("load-page", async url => { + contentPage = await ExtensionTestUtils.loadContentPage(url, { extension }); + extension.sendMessage("page-loaded"); + }); + extension.onMessage("remove-page", async url => { + await contentPage.close(); + extension.sendMessage("page-removed"); + }); + + await extension.startup(); + await extension.awaitFinish("storage-multiple"); + await extension.unload(); +} + +add_task(async function test_storage_local_file_backend_from_tab() { + return runWithPrefs( + [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, false]], + test_multiple_pages + ); +}); + +add_task(async function test_storage_local_idb_backend_from_tab() { + return runWithPrefs( + [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, true]], + test_multiple_pages + ); +}); + +async function test_storage_local_call_from_destroying_context() { + let extension = ExtensionTestUtils.loadExtension({ + async background() { + let numberOfChanges = 0; + browser.storage.onChanged.addListener((changes, areaName) => { + if (areaName !== "local") { + browser.test.fail( + `Received unexpected storage changes for "${areaName}"` + ); + } + + numberOfChanges++; + }); + + browser.test.onMessage.addListener(async ({ msg, values }) => { + switch (msg) { + case "storage-set": { + await browser.storage.local.set(values); + browser.test.sendMessage("storage-set:done"); + break; + } + case "storage-get": { + const res = await browser.storage.local.get(); + browser.test.sendMessage("storage-get:done", res); + break; + } + case "storage-changes": { + browser.test.sendMessage("storage-changes-count", numberOfChanges); + break; + } + default: + browser.test.fail(`Received unexpected message: ${msg}`); + } + }); + + browser.test.sendMessage( + "ext-page-url", + browser.runtime.getURL("tab.html") + ); + }, + files: { + "tab.html": `<!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + <script src="tab.js"></script> + </head> + </html>`, + + "tab.js"() { + browser.test.log("Extension tab - calling storage.local API method"); + // Call the storage.local API from a tab that is going to be quickly closed. + browser.storage.local.set({ + "test-key-from-destroying-context": "testvalue2", + }); + // Navigate away from the extension page, so that the storage.local API call will be unable + // to send the call to the caller context (because it has been destroyed in the meantime). + window.location = "about:blank"; + }, + }, + manifest: { + permissions: ["storage"], + }, + }); + + await extension.startup(); + const url = await extension.awaitMessage("ext-page-url"); + + let contentPage = await ExtensionTestUtils.loadContentPage(url, { + extension, + }); + let expectedBackgroundPageData = { + "test-key-from-background-page": "test-value", + }; + let expectedTabData = { "test-key-from-destroying-context": "testvalue2" }; + + info( + "Call storage.local.set from the background page and wait it to be completed" + ); + extension.sendMessage({ + msg: "storage-set", + values: expectedBackgroundPageData, + }); + await extension.awaitMessage("storage-set:done"); + + info( + "Call storage.local.get from the background page and wait it to be completed" + ); + extension.sendMessage({ msg: "storage-get" }); + let res = await extension.awaitMessage("storage-get:done"); + + Assert.deepEqual( + res, + { + ...expectedBackgroundPageData, + ...expectedTabData, + }, + "Got the expected data set in the storage.local backend" + ); + + extension.sendMessage({ msg: "storage-changes" }); + equal( + await extension.awaitMessage("storage-changes-count"), + 2, + "Got the expected number of storage.onChanged event received" + ); + + contentPage.close(); + + await extension.unload(); +} + +add_task( + async function test_storage_local_file_backend_destroyed_context_promise() { + return runWithPrefs( + [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, false]], + test_storage_local_call_from_destroying_context + ); + } +); + +add_task( + async function test_storage_local_idb_backend_destroyed_context_promise() { + return runWithPrefs( + [[ExtensionStorageIDB.BACKEND_ENABLED_PREF, true]], + test_storage_local_call_from_destroying_context + ); + } +); |