browser_storage_delete_usercontextid.js (7117B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 // Test deleting storage items with userContextId. 8 9 // The items that will be deleted. 10 const TEST_CASES = [ 11 [["localStorage", "http://test1.example.org"], "ls1", "name"], 12 [["sessionStorage", "http://test1.example.org"], "ss1", "name"], 13 [ 14 ["cookies", "http://test1.example.org"], 15 getCookieId("c1", "test1.example.org", "/browser"), 16 "name", 17 ], 18 [ 19 ["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], 20 1, 21 "name", 22 ], 23 [ 24 ["Cache", "http://test1.example.org", "plop"], 25 MAIN_DOMAIN + "404_cached_file.js", 26 "url", 27 ], 28 ]; 29 30 // The storage items that should exist for default userContextId 31 const storageItemsForDefault = [ 32 [ 33 ["cookies", "http://test1.example.org"], 34 [ 35 getCookieId("c1", "test1.example.org", "/browser"), 36 getCookieId("cs2", ".example.org", "/"), 37 getCookieId("c3", "test1.example.org", "/"), 38 getCookieId("c4", ".example.org", "/"), 39 getCookieId("uc1", ".example.org", "/"), 40 getCookieId("uc2", ".example.org", "/"), 41 ], 42 ], 43 [ 44 ["cookies", "https://sectest1.example.org"], 45 [ 46 getCookieId("uc1", ".example.org", "/"), 47 getCookieId("uc2", ".example.org", "/"), 48 getCookieId("cs2", ".example.org", "/"), 49 getCookieId("c4", ".example.org", "/"), 50 getCookieId( 51 "sc1", 52 "sectest1.example.org", 53 "/browser/devtools/client/storage/test" 54 ), 55 getCookieId( 56 "sc2", 57 "sectest1.example.org", 58 "/browser/devtools/client/storage/test" 59 ), 60 ], 61 ], 62 [ 63 ["localStorage", "http://test1.example.org"], 64 ["key", "ls1", "ls2"], 65 ], 66 [["localStorage", "http://sectest1.example.org"], ["iframe-u-ls1"]], 67 [["localStorage", "https://sectest1.example.org"], ["iframe-s-ls1"]], 68 [ 69 ["sessionStorage", "http://test1.example.org"], 70 ["key", "ss1"], 71 ], 72 [ 73 ["sessionStorage", "http://sectest1.example.org"], 74 ["iframe-u-ss1", "iframe-u-ss2"], 75 ], 76 [["sessionStorage", "https://sectest1.example.org"], ["iframe-s-ss1"]], 77 [ 78 ["indexedDB", "http://test1.example.org"], 79 ["idb1 (default)", "idb2 (default)"], 80 ], 81 [ 82 ["indexedDB", "http://test1.example.org", "idb1 (default)"], 83 ["obj1", "obj2"], 84 ], 85 [["indexedDB", "http://test1.example.org", "idb2 (default)"], ["obj3"]], 86 [ 87 ["indexedDB", "http://test1.example.org", "idb1 (default)", "obj1"], 88 [1, 2, 3], 89 ], 90 [["indexedDB", "http://test1.example.org", "idb1 (default)", "obj2"], [1]], 91 [["indexedDB", "http://test1.example.org", "idb2 (default)", "obj3"], []], 92 [["indexedDB", "http://sectest1.example.org"], []], 93 [ 94 ["indexedDB", "https://sectest1.example.org"], 95 ["idb-s1 (default)", "idb-s2 (default)"], 96 ], 97 [ 98 ["indexedDB", "https://sectest1.example.org", "idb-s1 (default)"], 99 ["obj-s1"], 100 ], 101 [ 102 ["indexedDB", "https://sectest1.example.org", "idb-s2 (default)"], 103 ["obj-s2"], 104 ], 105 [ 106 ["indexedDB", "https://sectest1.example.org", "idb-s1 (default)", "obj-s1"], 107 [6, 7], 108 ], 109 [ 110 ["indexedDB", "https://sectest1.example.org", "idb-s2 (default)", "obj-s2"], 111 [16], 112 ], 113 [ 114 ["Cache", "http://test1.example.org", "plop"], 115 [ 116 MAIN_DOMAIN + "404_cached_file.js", 117 MAIN_DOMAIN + "browser_storage_basic.js", 118 ], 119 ], 120 ]; 121 122 /** 123 * Test that the desired number of tree items are present 124 */ 125 function testTree(tests) { 126 const doc = gPanelWindow.document; 127 for (const [item] of tests) { 128 ok( 129 doc.querySelector("[data-id='" + JSON.stringify(item) + "']"), 130 `Tree item ${item.toSource()} should be present in the storage tree` 131 ); 132 } 133 } 134 135 /** 136 * Test that correct table entries are shown for each of the tree item 137 */ 138 async function testTables(tests) { 139 const doc = gPanelWindow.document; 140 // Expand all nodes so that the synthesized click event actually works 141 gUI.tree.expandAll(); 142 143 // First tree item is already selected so no clicking and waiting for update 144 for (const id of tests[0][1]) { 145 ok( 146 doc.querySelector(".table-widget-cell[data-id='" + id + "']"), 147 "Table item " + id + " should be present" 148 ); 149 } 150 151 // Click rest of the tree items and wait for the table to be updated 152 for (const [treeItem, items] of tests.slice(1)) { 153 await selectTreeItem(treeItem); 154 155 // Check whether correct number of items are present in the table 156 is( 157 doc.querySelectorAll( 158 ".table-widget-column:first-of-type .table-widget-cell" 159 ).length, 160 items.length, 161 "Number of items in table is correct" 162 ); 163 164 // Check if all the desired items are present in the table 165 for (const id of items) { 166 ok( 167 doc.querySelector(".table-widget-cell[data-id='" + id + "']"), 168 "Table item " + id + " should be present" 169 ); 170 } 171 } 172 } 173 174 add_task(async function () { 175 // storage-listings.html explicitly mixes secure and insecure frames. 176 // We should not enforce https for tests using this page. 177 await pushPref("dom.security.https_first", false); 178 179 // First, open a tab with the default userContextId and setup its storages. 180 const tabDefault = await openTab(MAIN_DOMAIN + "storage-listings.html"); 181 182 // Second, start testing for userContextId 1. 183 // We use the same item name as the default page has to see deleting items 184 // from userContextId 1 will affect default one or not. 185 await openTabAndSetupStorage(MAIN_DOMAIN + "storage-listings.html", { 186 userContextId: 1, 187 }); 188 189 const contextMenu = gPanelWindow.document.getElementById( 190 "storage-table-popup" 191 ); 192 const menuDeleteItem = contextMenu.querySelector( 193 "#storage-table-popup-delete" 194 ); 195 196 for (const [treeItem, rowName, cellToClick] of TEST_CASES) { 197 const treeItemName = treeItem.join(" > "); 198 199 info(`Selecting tree item ${treeItemName}`); 200 await selectTreeItem(treeItem); 201 202 const row = getRowCells(rowName); 203 ok( 204 gUI.table.items.has(rowName), 205 `There is a row '${rowName}' in ${treeItemName}` 206 ); 207 208 const eventWait = gUI.once("store-objects-edit"); 209 210 await waitForContextMenu(contextMenu, row[cellToClick], () => { 211 info(`Opened context menu in ${treeItemName}, row '${rowName}'`); 212 contextMenu.activateItem(menuDeleteItem); 213 const truncatedRowName = String(rowName) 214 .replace(SEPARATOR_GUID, "-") 215 .substr(0, 16); 216 ok( 217 JSON.parse( 218 menuDeleteItem.getAttribute("data-l10n-args") 219 ).itemName.includes(truncatedRowName), 220 `Context menu item label contains '${rowName}' (maybe truncated)` 221 ); 222 }); 223 224 await eventWait; 225 226 ok( 227 !gUI.table.items.has(rowName), 228 `There is no row '${rowName}' in ${treeItemName} after deletion` 229 ); 230 } 231 232 // Final, we see that the default tab is intact or not. 233 await BrowserTestUtils.switchTab(gBrowser, tabDefault); 234 await openStoragePanel(); 235 236 testTree(storageItemsForDefault); 237 await testTables(storageItemsForDefault); 238 });