browser_clearSiteData_v2.js (8885B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { PermissionTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/PermissionTestUtils.sys.mjs" 8 ); 9 10 async function testClearData(clearSiteData, clearCache) { 11 PermissionTestUtils.add( 12 TEST_QUOTA_USAGE_ORIGIN, 13 "persistent-storage", 14 Services.perms.ALLOW_ACTION 15 ); 16 17 // Open a test site which saves into appcache. 18 await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_OFFLINE_URL); 19 BrowserTestUtils.removeTab(gBrowser.selectedTab); 20 21 // Fill indexedDB with test data. 22 // Don't wait for the page to load, to register the content event handler as quickly as possible. 23 // If this test goes intermittent, we might have to tell the page to wait longer before 24 // firing the event. 25 BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL, false); 26 await BrowserTestUtils.waitForContentEvent( 27 gBrowser.selectedBrowser, 28 "test-indexedDB-done", 29 false, 30 null, 31 true 32 ); 33 BrowserTestUtils.removeTab(gBrowser.selectedTab); 34 35 // Register some service workers. 36 await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL); 37 await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL); 38 39 await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); 40 41 // Test the initial states. 42 let cacheUsage = await SiteDataManager.getCacheSize(); 43 let quotaUsage = await SiteDataTestUtils.getQuotaUsage( 44 TEST_QUOTA_USAGE_ORIGIN 45 ); 46 let totalUsage = await SiteDataManager.getTotalUsage(); 47 Assert.greater(cacheUsage, 0, "The cache usage should not be 0"); 48 Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); 49 Assert.greater(totalUsage, 0, "The total usage should not be 0"); 50 51 let initialSizeLabelValue = await SpecialPowers.spawn( 52 gBrowser.selectedBrowser, 53 [], 54 async function () { 55 let siteDataSizeItem = content.document.getElementById("siteDataSize"); 56 // The <strong> element contains the data size. 57 let usage = siteDataSizeItem.querySelector("strong"); 58 let siteDataSizeText = usage.textContent; 59 return siteDataSizeText; 60 } 61 ); 62 63 let doc = gBrowser.selectedBrowser.contentDocument; 64 let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); 65 66 let url = "chrome://browser/content/sanitize_v2.xhtml"; 67 let dialogOpened = promiseLoadSubDialog(url); 68 clearSiteDataButton.click(); 69 let dialogWin = await dialogOpened; 70 71 // Convert the usage numbers in the same way the UI does it to assert 72 // that they're displayed in the dialog. 73 let [convertedTotalUsage] = DownloadUtils.convertByteUnits(totalUsage); 74 // For cache we just assert that the right unit (KB, probably) is displayed, 75 // since we've had cache intermittently changing under our feet. 76 let [, convertedCacheUnit] = DownloadUtils.convertByteUnits(cacheUsage); 77 78 let cookiesCheckboxId = "cookiesAndStorage"; 79 let cacheCheckboxId = "cache"; 80 let clearSiteDataCheckbox = 81 dialogWin.document.getElementById(cookiesCheckboxId); 82 let clearCacheCheckbox = dialogWin.document.getElementById(cacheCheckboxId); 83 // The usage details are filled asynchronously, so we assert that they're present by 84 // waiting for them to be filled in. 85 await Promise.all([ 86 TestUtils.waitForCondition( 87 () => 88 clearSiteDataCheckbox.label && 89 clearSiteDataCheckbox.label.includes(convertedTotalUsage), 90 "Should show the quota usage" 91 ), 92 TestUtils.waitForCondition( 93 () => 94 clearCacheCheckbox.label && 95 clearCacheCheckbox.label.includes(convertedCacheUnit), 96 "Should show the cache usage" 97 ), 98 ]); 99 100 // Check the boxes according to our test input. 101 clearSiteDataCheckbox.checked = clearSiteData; 102 clearCacheCheckbox.checked = clearCache; 103 104 // select clear everything to match the old dialog boxes behaviour for this test 105 let timespanSelection = dialogWin.document.getElementById( 106 "sanitizeDurationChoice" 107 ); 108 timespanSelection.value = 1; 109 110 // Some additional promises/assertions to wait for 111 // when deleting site data. 112 let updatePromise; 113 if (clearSiteData) { 114 // the new clear history dialog does not have a extra prompt 115 // to clear site data after clicking clear 116 updatePromise = promiseSiteDataManagerSitesUpdated(); 117 } 118 119 let dialogClosed = BrowserTestUtils.waitForEvent(dialogWin, "unload"); 120 121 let clearButton = dialogWin.document 122 .querySelector("dialog") 123 .getButton("accept"); 124 let cancelButton = dialogWin.document 125 .querySelector("dialog") 126 .getButton("cancel"); 127 128 if (!clearSiteData && !clearCache) { 129 // Cancel, since we can't delete anything. 130 cancelButton.click(); 131 } else { 132 // Delete stuff! 133 clearButton.click(); 134 } 135 136 await dialogClosed; 137 138 if (clearCache) { 139 TestUtils.waitForCondition(async function () { 140 let usage = await SiteDataManager.getCacheSize(); 141 return usage == 0; 142 }, "The cache usage should be removed"); 143 } else { 144 Assert.greater( 145 await SiteDataManager.getCacheSize(), 146 0, 147 "The cache usage should not be 0" 148 ); 149 } 150 151 if (clearSiteData) { 152 await updatePromise; 153 await promiseServiceWorkersCleared(); 154 155 TestUtils.waitForCondition(async function () { 156 let usage = await SiteDataManager.getTotalUsage(); 157 return usage == 0; 158 }, "The total usage should be removed"); 159 } else { 160 quotaUsage = await SiteDataTestUtils.getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN); 161 totalUsage = await SiteDataManager.getTotalUsage(); 162 Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); 163 Assert.greater(totalUsage, 0, "The total usage should not be 0"); 164 } 165 166 if (clearCache || clearSiteData) { 167 // Check that the size label in about:preferences updates after we cleared data. 168 await SpecialPowers.spawn( 169 gBrowser.selectedBrowser, 170 [{ initialSizeLabelValue }], 171 async function (opts) { 172 let siteDataSizeItem = content.document.getElementById("siteDataSize"); 173 // The <strong> element contains the data size. 174 let usage = siteDataSizeItem.querySelector("strong"); 175 let siteDataSizeText = usage.textContent; 176 await ContentTaskUtils.waitForCondition(() => { 177 return siteDataSizeText != opts.initialSizeLabelValue; 178 }, "Site data size label should have updated."); 179 } 180 ); 181 } 182 183 let permission = PermissionTestUtils.getPermissionObject( 184 TEST_QUOTA_USAGE_ORIGIN, 185 "persistent-storage" 186 ); 187 is( 188 clearSiteData ? permission : permission.capability, 189 clearSiteData ? null : Services.perms.ALLOW_ACTION, 190 "Should have the correct permission state." 191 ); 192 193 BrowserTestUtils.removeTab(gBrowser.selectedTab); 194 await SiteDataManager.removeAll(); 195 } 196 197 add_setup(function () { 198 SpecialPowers.pushPrefEnv({ 199 set: [["privacy.sanitize.useOldClearHistoryDialog", false]], 200 }); 201 202 // The tests in this file all test specific interactions with the new clear 203 // history dialog and can't be split up. 204 requestLongerTimeout(2); 205 }); 206 207 // Test opening the "Clear All Data" dialog and cancelling. 208 add_task(async function testNoSiteDataNoCacheClearing() { 209 await testClearData(false, false); 210 }); 211 212 // Test opening the "Clear All Data" dialog and removing all site data. 213 add_task(async function testSiteDataClearing() { 214 await testClearData(true, false); 215 }); 216 217 // Test opening the "Clear All Data" dialog and removing all cache. 218 add_task(async function testCacheClearing() { 219 await testClearData(false, true); 220 }); 221 222 // Test opening the "Clear All Data" dialog and removing everything. 223 add_task(async function testSiteDataAndCacheClearing() { 224 await testClearData(true, true); 225 }); 226 227 // Test clearing persistent storage 228 add_task(async function testPersistentStorage() { 229 PermissionTestUtils.add( 230 TEST_QUOTA_USAGE_ORIGIN, 231 "persistent-storage", 232 Services.perms.ALLOW_ACTION 233 ); 234 235 await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); 236 237 let doc = gBrowser.selectedBrowser.contentDocument; 238 let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); 239 240 let url = "chrome://browser/content/sanitize_v2.xhtml"; 241 let dialogOpened = promiseLoadSubDialog(url); 242 clearSiteDataButton.click(); 243 let dialogWin = await dialogOpened; 244 let dialogClosed = BrowserTestUtils.waitForEvent(dialogWin, "unload"); 245 246 let timespanSelection = dialogWin.document.getElementById( 247 "sanitizeDurationChoice" 248 ); 249 timespanSelection.value = 1; 250 let clearButton = dialogWin.document 251 .querySelector("dialog") 252 .getButton("accept"); 253 clearButton.click(); 254 await dialogClosed; 255 256 let permission = PermissionTestUtils.getPermissionObject( 257 TEST_QUOTA_USAGE_ORIGIN, 258 "persistent-storage" 259 ); 260 is(permission, null, "Should have the correct permission state."); 261 262 BrowserTestUtils.removeTab(gBrowser.selectedTab); 263 });