1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
<!DOCTYPE HTML>
<html>
<head>
<title>WebExtension test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="text/javascript">
"use strict";
// Test that storage used by a webextension (through localStorage,
// indexedDB, and browser.storage.local) gets cleaned up when the
// extension is uninstalled.
add_task(async function test_uninstall() {
function writeData() {
localStorage.setItem("hello", "world");
let idbPromise = new Promise((resolve, reject) => {
let req = indexedDB.open("test");
req.onerror = e => {
reject(new Error(`indexedDB open failed with ${e.errorCode}`));
};
req.onupgradeneeded = e => {
let db = e.target.result;
db.createObjectStore("store", {keyPath: "name"});
};
req.onsuccess = e => {
let db = e.target.result;
let transaction = db.transaction("store", "readwrite");
let addreq = transaction.objectStore("store")
.add({name: "hello", value: "world"});
addreq.onerror = addreqError => {
reject(new Error(`add to indexedDB failed with ${addreqError.errorCode}`));
};
addreq.onsuccess = () => {
resolve();
};
};
});
let browserStoragePromise = browser.storage.local.set({hello: "world"});
Promise.all([idbPromise, browserStoragePromise]).then(() => {
browser.test.sendMessage("finished");
});
}
function readData() {
let matchLocalStorage = (localStorage.getItem("hello") == "world");
let idbPromise = new Promise((resolve, reject) => {
let req = indexedDB.open("test");
req.onerror = e => {
reject(new Error(`indexedDB open failed with ${e.errorCode}`));
};
req.onupgradeneeded = e => {
// no database, data is not present
resolve(false);
};
req.onsuccess = e => {
let db = e.target.result;
let transaction = db.transaction("store", "readwrite");
let addreq = transaction.objectStore("store").get("hello");
addreq.onerror = addreqError => {
reject(new Error(`read from indexedDB failed with ${addreqError.errorCode}`));
};
addreq.onsuccess = () => {
let match = (addreq.result.value == "world");
resolve(match);
};
};
});
let browserStoragePromise = browser.storage.local.get("hello").then(result => {
return (Object.keys(result).length == 1 && result.hello == "world");
});
Promise.all([idbPromise, browserStoragePromise])
.then(([matchIDB, matchBrowserStorage]) => {
let result = {matchLocalStorage, matchIDB, matchBrowserStorage};
browser.test.sendMessage("results", result);
});
}
const ID = "storage.cleanup@tests.mozilla.org";
// Use a test-only pref to leave the addonid->uuid mapping around after
// uninstall so that we can re-attach to the same storage. Also set
// the pref to prevent cleaning up storage on uninstall so we can test
// that the "keep uuid" logic works correctly. Do the storage flag in
// a separate prefEnv so we can pop it below, leaving the uuid flag set.
await SpecialPowers.pushPrefEnv({
set: [["extensions.webextensions.keepUuidOnUninstall", true]],
});
await SpecialPowers.pushPrefEnv({
set: [["extensions.webextensions.keepStorageOnUninstall", true]],
});
let extension = ExtensionTestUtils.loadExtension({
background: writeData,
manifest: {
applications: {gecko: {id: ID}},
permissions: ["storage"],
},
useAddonManager: "temporary",
});
await extension.startup();
await extension.awaitMessage("finished");
await extension.unload();
// Check that we can still see data we wrote to storage but clear the
// "leave storage" flag so our storaged gets cleared on uninstall.
// This effectively tests the keepUuidOnUninstall logic, which ensures
// that when we read storage again and check that it is cleared, that
// it is actually a meaningful test!
await SpecialPowers.popPrefEnv();
extension = ExtensionTestUtils.loadExtension({
background: readData,
manifest: {
applications: {gecko: {id: ID}},
permissions: ["storage"],
},
useAddonManager: "temporary",
});
await extension.startup();
let results = await extension.awaitMessage("results");
is(results.matchLocalStorage, true, "localStorage data is still present");
is(results.matchIDB, true, "indexedDB data is still present");
is(results.matchBrowserStorage, true, "browser.storage.local data is still present");
await extension.unload();
// Read again. This time, our data should be gone.
extension = ExtensionTestUtils.loadExtension({
background: readData,
manifest: {
applications: {gecko: {id: ID}},
permissions: ["storage"],
},
useAddonManager: "temporary",
});
await extension.startup();
results = await extension.awaitMessage("results");
is(results.matchLocalStorage, false, "localStorage data was cleared");
is(results.matchIDB, false, "indexedDB data was cleared");
is(results.matchBrowserStorage, false, "browser.storage.local data was cleared");
await extension.unload();
});
</script>
</body>
</html>
|