browser_sanitizeDialog_v2.js (26996B)
1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /** 8 * Tests the sanitize dialog (a.k.a. the clear recent history dialog). 9 * See bug 480169. 10 * 11 * The purpose of this test is not to fully flex the sanitize timespan code; 12 * browser/base/content/test/sanitize/browser_sanitize-timespans.js does that. This 13 * test checks the UI of the dialog and makes sure it's correctly connected to 14 * the sanitize timespan code. 15 * 16 * Some of this code, especially the history creation parts, was taken from 17 * browser/base/content/test/sanitize/browser_sanitize-timespans.js. 18 */ 19 ChromeUtils.defineESModuleGetters(this, { 20 PlacesTestUtils: "resource://testing-common/PlacesTestUtils.sys.mjs", 21 Timer: "resource://gre/modules/Timer.sys.mjs", 22 PermissionTestUtils: "resource://testing-common/PermissionTestUtils.sys.mjs", 23 Downloads: "resource://gre/modules/Downloads.sys.mjs", 24 }); 25 26 /** 27 * Ensures that the specified URIs are either cleared or not. 28 * 29 * @param aURIs 30 * Array of page URIs 31 * @param aShouldBeCleared 32 * True if each visit to the URI should be cleared, false otherwise 33 */ 34 async function promiseHistoryClearedState(aURIs, aShouldBeCleared) { 35 for (let uri of aURIs) { 36 let visited = await PlacesUtils.history.hasVisits(uri); 37 Assert.equal( 38 visited, 39 !aShouldBeCleared, 40 `history visit ${uri.spec} should ${ 41 aShouldBeCleared ? "no longer" : "still" 42 } exist` 43 ); 44 } 45 } 46 47 /** 48 * Ensures that the given pref is the expected value. 49 * 50 * @param {string} aPrefName 51 * The pref's sub-branch under the privacy branch 52 * @param {boolean} aExpectedVal 53 * The pref's expected value 54 * @param {string} aMsg 55 * Passed to is() 56 */ 57 function boolPrefIs(aPrefName, aExpectedVal, aMsg) { 58 is(Services.prefs.getBoolPref("privacy." + aPrefName), aExpectedVal, aMsg); 59 } 60 61 /** 62 * Checks to see if the download with the specified path exists. 63 * 64 * @param aPath 65 * The path of the download to check 66 * @return True if the download exists, false otherwise 67 */ 68 async function downloadExists(aPath) { 69 let publicList = await Downloads.getList(Downloads.PUBLIC); 70 let listArray = await publicList.getAll(); 71 return listArray.some(i => i.target.path == aPath); 72 } 73 74 /** 75 * Ensures that the specified downloads are either cleared or not. 76 * 77 * @param aDownloadIDs 78 * Array of download database IDs 79 * @param aShouldBeCleared 80 * True if each download should be cleared, false otherwise 81 */ 82 async function ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) { 83 let niceStr = aShouldBeCleared ? "no longer" : "still"; 84 for (let id of aDownloadIDs) { 85 is( 86 await downloadExists(id), 87 !aShouldBeCleared, 88 "download " + id + " should " + niceStr + " exist" 89 ); 90 } 91 } 92 93 /** 94 * Checks if a form entry exists. 95 */ 96 async function formNameExists(name) { 97 return !!(await FormHistory.count({ fieldname: name })); 98 } 99 100 /** 101 * Adds a form entry to history. 102 * 103 * @param aMinutesAgo 104 * The entry will be added this many minutes ago 105 */ 106 function promiseAddFormEntryWithMinutesAgo(aMinutesAgo) { 107 let name = aMinutesAgo + "-minutes-ago"; 108 109 // Artifically age the entry to the proper vintage. 110 let timestamp = nowUSec - aMinutesAgo * kUsecPerMin; 111 112 return FormHistory.update({ 113 op: "add", 114 fieldname: name, 115 value: "dummy", 116 firstUsed: timestamp, 117 }); 118 } 119 120 /** 121 * Adds a download to history. 122 * 123 * @param aMinutesAgo 124 * The download will be downloaded this many minutes ago 125 */ 126 async function addDownloadWithMinutesAgo(aExpectedPathList, aMinutesAgo) { 127 let publicList = await Downloads.getList(Downloads.PUBLIC); 128 129 let name = "fakefile-" + aMinutesAgo + "-minutes-ago"; 130 let download = await Downloads.createDownload({ 131 source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", 132 target: name, 133 }); 134 download.startTime = new Date(nowMSec - aMinutesAgo * kMsecPerMin); 135 download.canceled = true; 136 publicList.add(download); 137 138 ok( 139 await downloadExists(name), 140 "Sanity check: download " + name + " should exist after creating it" 141 ); 142 143 aExpectedPathList.push(name); 144 } 145 146 add_setup(async function () { 147 requestLongerTimeout(3); 148 await blankSlate(); 149 registerCleanupFunction(async function () { 150 await blankSlate(); 151 await PlacesTestUtils.promiseAsyncUpdates(); 152 }); 153 await SpecialPowers.pushPrefEnv({ 154 set: [["privacy.sanitize.useOldClearHistoryDialog", false]], 155 }); 156 157 // open preferences to trigger an updateSites() 158 await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); 159 BrowserTestUtils.removeTab(gBrowser.selectedTab); 160 }); 161 162 /** 163 * Ensures that the given pref is the expected value. 164 * 165 * @param aPrefName 166 * The pref's sub-branch under the privacy branch 167 * @param aExpectedVal 168 * The pref's expected value 169 * @param aMsg 170 * Passed to is() 171 */ 172 function intPrefIs(aPrefName, aExpectedVal, aMsg) { 173 is(Services.prefs.getIntPref("privacy." + aPrefName), aExpectedVal, aMsg); 174 } 175 176 /** 177 * Creates a visit time. 178 * 179 * @param aMinutesAgo 180 * The visit will be visited this many minutes ago 181 */ 182 function visitTimeForMinutesAgo(aMinutesAgo) { 183 return nowUSec - aMinutesAgo * kUsecPerMin; 184 } 185 186 /** 187 * 188 * Opens dialog in the provided context and selects the checkboxes 189 * as sent in the parameters 190 * 191 * @param {object} context the dialog is opened in, timespan to select, 192 * if browsingHistoryAndDownloads, cookiesAndStorage, cache or siteSettings 193 * are checked 194 */ 195 async function performActionsOnDialog({ 196 context = "browser", 197 timespan = Sanitizer.TIMESPAN_HOUR, 198 browsingHistoryAndDownloads = true, 199 cookiesAndStorage = true, 200 cache = false, 201 siteSettings = false, 202 formData = false, 203 }) { 204 let dh = new ClearHistoryDialogHelper({ mode: context }); 205 dh.onload = function () { 206 this.selectDuration(timespan); 207 this.checkPrefCheckbox( 208 "browsingHistoryAndDownloads", 209 browsingHistoryAndDownloads 210 ); 211 this.checkPrefCheckbox("cookiesAndStorage", cookiesAndStorage); 212 this.checkPrefCheckbox("cache", cache); 213 this.checkPrefCheckbox("siteSettings", siteSettings); 214 this.checkPrefCheckbox("formdata", formData); 215 this.acceptDialog(); 216 }; 217 dh.open(); 218 await dh.promiseClosed; 219 } 220 221 /** 222 * Initializes the dialog to its default state. 223 */ 224 add_task(async function default_state() { 225 let dh = new ClearHistoryDialogHelper(); 226 dh.onload = function () { 227 // Select "Last Hour" 228 this.selectDuration(Sanitizer.TIMESPAN_HOUR); 229 this.acceptDialog(); 230 }; 231 dh.open(); 232 await dh.promiseClosed; 233 }); 234 235 /** 236 * Cancels the dialog, makes sure history not cleared. 237 */ 238 add_task(async function test_cancel() { 239 // Add history (within the past hour) 240 let uris = []; 241 let places = []; 242 let pURI; 243 for (let i = 0; i < 30; i++) { 244 pURI = makeURI("https://" + i + "-minutes-ago.com/"); 245 places.push({ uri: pURI, visitDate: visitTimeForMinutesAgo(i) }); 246 uris.push(pURI); 247 } 248 await PlacesTestUtils.addVisits(places); 249 250 let dh = new ClearHistoryDialogHelper(); 251 dh.onload = function () { 252 this.selectDuration(Sanitizer.TIMESPAN_HOUR); 253 this.checkPrefCheckbox("browsingHistoryAndDownloads", false); 254 this.cancelDialog(); 255 }; 256 dh.onunload = async function () { 257 await promiseHistoryClearedState(uris, false); 258 await blankSlate(); 259 await promiseHistoryClearedState(uris, true); 260 }; 261 dh.open(); 262 await dh.promiseClosed; 263 }); 264 265 // test remembering user options for various entry points 266 add_task(async function test_pref_remembering() { 267 let dh = new ClearHistoryDialogHelper({ mode: "clearSiteData" }); 268 dh.onload = function () { 269 this.checkPrefCheckbox("cookiesAndStorage", false); 270 this.checkPrefCheckbox("siteSettings", true); 271 272 this.acceptDialog(); 273 }; 274 dh.open(); 275 await dh.promiseClosed; 276 277 // validate if prefs are remembered 278 dh = new ClearHistoryDialogHelper({ mode: "clearSiteData" }); 279 dh.onload = function () { 280 this.validateCheckbox("cookiesAndStorage", false); 281 this.validateCheckbox("siteSettings", true); 282 283 this.checkPrefCheckbox("cookiesAndStorage", true); 284 this.checkPrefCheckbox("siteSettings", false); 285 286 // we will test cancelling the dialog, to make sure it doesn't remember 287 // the prefs when cancelled 288 this.cancelDialog(); 289 }; 290 dh.open(); 291 await dh.promiseClosed; 292 293 // validate if prefs did not change since we cancelled the dialog 294 dh = new ClearHistoryDialogHelper({ mode: "clearSiteData" }); 295 dh.onload = function () { 296 this.validateCheckbox("cookiesAndStorage", false); 297 this.validateCheckbox("siteSettings", true); 298 299 this.cancelDialog(); 300 }; 301 dh.open(); 302 await dh.promiseClosed; 303 304 if (!settingsRedesignHistoryEnabled()) { 305 // test rememebering prefs from the clear history context 306 // since clear history and clear site data have seperate remembering 307 // of prefs 308 dh = new ClearHistoryDialogHelper({ mode: "clearHistory" }); 309 dh.onload = function () { 310 this.checkPrefCheckbox("cookiesAndStorage", true); 311 this.checkPrefCheckbox("siteSettings", false); 312 this.checkPrefCheckbox("cache", false); 313 314 this.acceptDialog(); 315 }; 316 dh.open(); 317 await dh.promiseClosed; 318 } 319 320 // validate if prefs are remembered across both clear history and browser 321 dh = new ClearHistoryDialogHelper({ mode: "browser" }); 322 dh.onload = function () { 323 this.validateCheckbox("cookiesAndStorage", true); 324 this.validateCheckbox("siteSettings", false); 325 if (!settingsRedesignHistoryEnabled()) { 326 this.validateCheckbox("cache", false); 327 } 328 329 this.cancelDialog(); 330 }; 331 dh.open(); 332 await dh.promiseClosed; 333 }); 334 335 /** 336 * Ensures that the "Everything" duration option works. 337 */ 338 add_task(async function test_everything() { 339 // Add history. 340 let uris = []; 341 let places = []; 342 let pURI; 343 // within past hour, within past two hours, within past four hours and 344 // outside past four hours 345 [10, 70, 130, 250].forEach(function (aValue) { 346 pURI = makeURI("https://" + aValue + "-minutes-ago.com/"); 347 places.push({ uri: pURI, visitDate: visitTimeForMinutesAgo(aValue) }); 348 uris.push(pURI); 349 }); 350 351 let promiseSanitized = promiseSanitizationComplete(); 352 353 await PlacesTestUtils.addVisits(places); 354 let dh = new ClearHistoryDialogHelper(); 355 dh.onload = function () { 356 is( 357 this.isWarningPanelVisible(), 358 false, 359 "Warning panel should be hidden after previously accepting dialog " + 360 "with a predefined timespan" 361 ); 362 this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); 363 this.checkPrefCheckbox("browsingHistoryAndDownloads", true); 364 this.acceptDialog(); 365 }; 366 dh.onunload = async function () { 367 await promiseSanitized; 368 intPrefIs( 369 "sanitize.timeSpan", 370 Sanitizer.TIMESPAN_EVERYTHING, 371 "timeSpan pref should be everything after accepting dialog " + 372 "with everything selected" 373 ); 374 375 await promiseHistoryClearedState(uris, true); 376 }; 377 dh.open(); 378 await dh.promiseClosed; 379 }); 380 381 /** 382 * Ensures that the "Everything" warning is visible on dialog open after 383 * the previous test. 384 */ 385 add_task(async function test_everything_warning() { 386 // Add history. 387 let uris = []; 388 let places = []; 389 let pURI; 390 // within past hour, within past two hours, within past four hours and 391 // outside past four hours 392 [10, 70, 130, 250].forEach(function (aValue) { 393 pURI = makeURI("https://" + aValue + "-minutes-ago.com/"); 394 places.push({ uri: pURI, visitDate: visitTimeForMinutesAgo(aValue) }); 395 uris.push(pURI); 396 }); 397 398 let promiseSanitized = promiseSanitizationComplete(); 399 400 await PlacesTestUtils.addVisits(places); 401 let dh = new ClearHistoryDialogHelper(); 402 dh.onload = function () { 403 is( 404 this.isWarningPanelVisible(), 405 true, 406 "Warning panel should be visible after previously accepting dialog " + 407 "with clearing everything" 408 ); 409 this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); 410 this.checkPrefCheckbox("browsingHistoryAndDownloads", true); 411 this.acceptDialog(); 412 }; 413 dh.onunload = async function () { 414 intPrefIs( 415 "sanitize.timeSpan", 416 Sanitizer.TIMESPAN_EVERYTHING, 417 "timeSpan pref should be everything after accepting dialog " + 418 "with everything selected" 419 ); 420 421 await promiseSanitized; 422 423 await promiseHistoryClearedState(uris, true); 424 }; 425 dh.open(); 426 await dh.promiseClosed; 427 }); 428 429 /** 430 * Tests that the clearing button gets disabled if no checkboxes are checked 431 * and enabled when at least one checkbox is checked 432 */ 433 add_task(async function testAcceptButtonDisabled() { 434 let dh = new ClearHistoryDialogHelper(); 435 dh.onload = async function () { 436 let clearButton = this.win.document 437 .querySelector("dialog") 438 .getButton("accept"); 439 this.uncheckAllCheckboxes(); 440 await new Promise(resolve => SimpleTest.executeSoon(resolve)); 441 is(clearButton.disabled, true, "Clear button should be disabled"); 442 443 this.checkPrefCheckbox("cache", true); 444 await new Promise(resolve => SimpleTest.executeSoon(resolve)); 445 is(clearButton.disabled, false, "Clear button should not be disabled"); 446 447 this.cancelDialog(); 448 }; 449 dh.open(); 450 await dh.promiseClosed; 451 }); 452 453 /** 454 * Tests to see if the warning box is hidden when opened in the clear on shutdown context 455 */ 456 add_task(async function testWarningBoxInClearOnShutdown() { 457 let dh = new ClearHistoryDialogHelper({ mode: "clearSiteData" }); 458 dh.onload = function () { 459 this.selectDuration(Sanitizer.TIMESPAN_EVERYTHING); 460 is( 461 BrowserTestUtils.isVisible(this.getWarningPanel()), 462 true, 463 `warning panel should be visible` 464 ); 465 this.acceptDialog(); 466 }; 467 dh.open(); 468 await dh.promiseClosed; 469 470 dh = new ClearHistoryDialogHelper({ mode: "clearOnShutdown" }); 471 dh.onload = function () { 472 is( 473 BrowserTestUtils.isVisible(this.getWarningPanel()), 474 false, 475 `warning panel should not be visible` 476 ); 477 478 this.cancelDialog(); 479 }; 480 dh.open(); 481 await dh.promiseClosed; 482 }); 483 484 /** 485 * Checks if clearing history and downloads for the simple timespan 486 * behaves as expected 487 */ 488 add_task(async function test_history_downloads_checked() { 489 // Add downloads (within the past hour). 490 let downloadIDs = []; 491 for (let i = 0; i < 5; i++) { 492 await addDownloadWithMinutesAgo(downloadIDs, i); 493 } 494 // Add downloads (over an hour ago). 495 let olderDownloadIDs = []; 496 for (let i = 0; i < 5; i++) { 497 await addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i); 498 } 499 500 // Add history (within the past hour). 501 let uris = []; 502 let places = []; 503 let pURI; 504 for (let i = 0; i < 30; i++) { 505 pURI = makeURI("https://" + i + "-minutes-ago.com/"); 506 places.push({ uri: pURI, visitDate: visitTimeForMinutesAgo(i) }); 507 uris.push(pURI); 508 } 509 // Add history (over an hour ago). 510 let olderURIs = []; 511 for (let i = 0; i < 5; i++) { 512 pURI = makeURI("https://" + (61 + i) + "-minutes-ago.com/"); 513 places.push({ uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i) }); 514 olderURIs.push(pURI); 515 } 516 let promiseSanitized = promiseSanitizationComplete(); 517 518 await PlacesTestUtils.addVisits(places); 519 520 let dh = new ClearHistoryDialogHelper(); 521 dh.onload = function () { 522 this.selectDuration(Sanitizer.TIMESPAN_HOUR); 523 this.checkPrefCheckbox("browsingHistoryAndDownloads", true); 524 this.acceptDialog(); 525 }; 526 dh.onunload = async function () { 527 intPrefIs( 528 "sanitize.timeSpan", 529 Sanitizer.TIMESPAN_HOUR, 530 "timeSpan pref should be hour after accepting dialog with " + 531 "hour selected" 532 ); 533 534 await promiseSanitized; 535 536 // History visits and downloads within one hour should be cleared. 537 await promiseHistoryClearedState(uris, true); 538 await ensureDownloadsClearedState(downloadIDs, true); 539 540 // Visits and downloads > 1 hour should still exist. 541 await promiseHistoryClearedState(olderURIs, false); 542 await ensureDownloadsClearedState(olderDownloadIDs, false); 543 544 // OK, done, cleanup after ourselves. 545 await blankSlate(); 546 await promiseHistoryClearedState(olderURIs, true); 547 await ensureDownloadsClearedState(olderDownloadIDs, true); 548 }; 549 dh.open(); 550 await dh.promiseClosed; 551 }); 552 553 /** 554 * The next three tests checks that when a certain history item cannot be 555 * cleared then the checkbox should be both disabled and unchecked. 556 * In addition, we ensure that this behavior does not modify the preferences. 557 */ 558 add_task(async function test_cannot_clear_history() { 559 // Add form entries 560 let formEntries = [await promiseAddFormEntryWithMinutesAgo(10)]; 561 562 let promiseSanitized = promiseSanitizationComplete(); 563 564 // Add history. 565 let pURI = makeURI("https://" + 10 + "-minutes-ago.com/"); 566 await PlacesTestUtils.addVisits({ 567 uri: pURI, 568 visitDate: visitTimeForMinutesAgo(10), 569 }); 570 let uris = [pURI]; 571 572 let dh = new ClearHistoryDialogHelper(); 573 dh.onload = function () { 574 var cb = this.win.document.querySelectorAll( 575 "checkbox[id='browsingHistoryAndDownloads']" 576 ); 577 ok( 578 cb.length == 1 && !cb[0].disabled, 579 "There is history, checkbox to clear history should be enabled." 580 ); 581 582 this.checkPrefCheckbox("formdata", true); 583 this.checkPrefCheckbox("browsingHistoryAndDownloads", true); 584 this.acceptDialog(); 585 }; 586 dh.onunload = async function () { 587 await promiseSanitized; 588 589 await promiseHistoryClearedState(uris, true); 590 591 let exists = await formNameExists(formEntries[0]); 592 ok(!exists, "form entry " + formEntries[0] + " should no longer exist"); 593 }; 594 dh.open(); 595 await dh.promiseClosed; 596 }); 597 598 add_task(async function test_no_history_to_clear() { 599 let promiseSanitized = promiseSanitizationComplete(); 600 let dh = new ClearHistoryDialogHelper(); 601 dh.onload = function () { 602 var cb = this.win.document.querySelectorAll( 603 "checkbox[id='browsingHistoryAndDownloads']" 604 ); 605 ok( 606 cb.length == 1 && !cb[0].disabled && cb[0].checked, 607 "There is no history, but history checkbox should always be enabled " + 608 "and will be checked from previous preference." 609 ); 610 611 this.acceptDialog(); 612 }; 613 dh.open(); 614 await dh.promiseClosed; 615 await promiseSanitized; 616 }); 617 618 add_task(async function test_form_entries() { 619 let formEntry = await promiseAddFormEntryWithMinutesAgo(10); 620 621 let promiseSanitized = promiseSanitizationComplete(); 622 623 let dh = new ClearHistoryDialogHelper(); 624 dh.onload = function () { 625 var cb = this.win.document.querySelectorAll("checkbox[id='formdata']"); 626 is(cb.length, 1, "There is only one checkbox for form data"); 627 ok(!cb[0].disabled, "The checkbox is enabled"); 628 ok(cb[0].checked, "The checkbox is checked"); 629 630 this.acceptDialog(); 631 }; 632 dh.onunload = async function () { 633 await promiseSanitized; 634 let exists = await formNameExists(formEntry); 635 ok(!exists, "form entry " + formEntry + " should no longer exist"); 636 }; 637 dh.open(); 638 await dh.promiseClosed; 639 }); 640 641 // test the case when we open the dialog through the clear on shutdown settings 642 add_task(async function test_clear_on_shutdown() { 643 await SpecialPowers.pushPrefEnv({ 644 set: [["privacy.sanitize.sanitizeOnShutdown", true]], 645 }); 646 647 let dh = new ClearHistoryDialogHelper({ mode: "clearOnShutdown" }); 648 dh.onload = async function () { 649 this.uncheckAllCheckboxes(); 650 this.checkPrefCheckbox("browsingHistoryAndDownloads", false); 651 this.checkPrefCheckbox("cookiesAndStorage", true); 652 this.acceptDialog(); 653 }; 654 dh.open(); 655 await dh.promiseClosed; 656 657 // Add downloads (within the past hour). 658 let downloadIDs = []; 659 for (let i = 0; i < 5; i++) { 660 await addDownloadWithMinutesAgo(downloadIDs, i); 661 } 662 // Add downloads (over an hour ago). 663 let olderDownloadIDs = []; 664 for (let i = 0; i < 5; i++) { 665 await addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i); 666 } 667 668 boolPrefIs( 669 "clearOnShutdown_v2.browsingHistoryAndDownloads", 670 false, 671 "clearOnShutdown_v2 history should be false" 672 ); 673 674 boolPrefIs( 675 "clearOnShutdown_v2.cookiesAndStorage", 676 true, 677 "clearOnShutdown_v2 cookies should be true" 678 ); 679 680 boolPrefIs( 681 "clearOnShutdown_v2.cache", 682 false, 683 "clearOnShutdown_v2 cache should be false" 684 ); 685 686 await createDummyDataForHost("example.org"); 687 await createDummyDataForHost("example.com"); 688 689 ok( 690 await SiteDataTestUtils.hasIndexedDB("https://example.org"), 691 "We have indexedDB data for example.org" 692 ); 693 ok( 694 await SiteDataTestUtils.hasIndexedDB("https://example.com"), 695 "We have indexedDB data for example.com" 696 ); 697 698 // Cleaning up 699 await Sanitizer.runSanitizeOnShutdown(); 700 701 // Data for example.org should be cleared 702 ok( 703 !(await SiteDataTestUtils.hasIndexedDB("https://example.org")), 704 "We don't have indexedDB data for example.org" 705 ); 706 // Data for example.com should be cleared 707 ok( 708 !(await SiteDataTestUtils.hasIndexedDB("https://example.com")), 709 "We don't have indexedDB data for example.com" 710 ); 711 712 // Downloads shouldn't have cleared 713 await ensureDownloadsClearedState(downloadIDs, false); 714 await ensureDownloadsClearedState(olderDownloadIDs, false); 715 716 dh = new ClearHistoryDialogHelper({ mode: "clearOnShutdown" }); 717 dh.onload = async function () { 718 this.uncheckAllCheckboxes(); 719 this.checkPrefCheckbox("browsingHistoryAndDownloads", true); 720 this.acceptDialog(); 721 }; 722 dh.open(); 723 await dh.promiseClosed; 724 725 boolPrefIs( 726 "clearOnShutdown_v2.browsingHistoryAndDownloads", 727 true, 728 "clearOnShutdown_v2 history should be true" 729 ); 730 731 boolPrefIs( 732 "clearOnShutdown_v2.cookiesAndStorage", 733 false, 734 "clearOnShutdown_v2 cookies should be false" 735 ); 736 737 boolPrefIs( 738 "clearOnShutdown_v2.cache", 739 false, 740 "clearOnShutdown_v2 cache should be false" 741 ); 742 743 ok( 744 await SiteDataTestUtils.hasIndexedDB("https://example.org"), 745 "We have indexedDB data for example.org" 746 ); 747 ok( 748 await SiteDataTestUtils.hasIndexedDB("https://example.com"), 749 "We have indexedDB data for example.com" 750 ); 751 752 // Cleaning up 753 await Sanitizer.runSanitizeOnShutdown(); 754 755 // Data for example.org should not be cleared 756 ok( 757 await SiteDataTestUtils.hasIndexedDB("https://example.org"), 758 "We have indexedDB data for example.org" 759 ); 760 // Data for example.com should not be cleared 761 ok( 762 await SiteDataTestUtils.hasIndexedDB("https://example.com"), 763 "We have indexedDB data for example.com" 764 ); 765 766 // downloads should have cleared 767 await ensureDownloadsClearedState(downloadIDs, true); 768 await ensureDownloadsClearedState(olderDownloadIDs, true); 769 770 // Clean up 771 await SiteDataTestUtils.clear(); 772 }); 773 774 if (!settingsRedesignHistoryEnabled()) { 775 add_task(async function testClearHistoryCheckboxStatesAfterMigration() { 776 await SpecialPowers.pushPrefEnv({ 777 set: [ 778 ["privacy.cpd.history", false], 779 ["privacy.cpd.formdata", true], 780 ["privacy.cpd.cookies", true], 781 ["privacy.cpd.offlineApps", false], 782 ["privacy.cpd.sessions", false], 783 ["privacy.cpd.siteSettings", false], 784 ["privacy.cpd.cache", true], 785 // Set cookiesAndStorage to verify that the pref is flipped in the test 786 ["privacy.clearHistory.cookiesAndStorage", false], 787 // We set the old migrate pref to false to simulate a user who has not migrated to the new dialog. 788 // we should follow the user's old prefs with "cpd." prefix in this case. 789 ["privacy.sanitize.cpd.hasMigratedToNewPrefs2", false], 790 ["privacy.sanitize.cpd.hasMigratedToNewPrefs3", false], 791 ], 792 }); 793 794 let dh = new ClearHistoryDialogHelper({ mode: "clearHistory" }); 795 dh.onload = function () { 796 this.validateCheckbox("cookiesAndStorage", true); 797 this.validateCheckbox("browsingHistoryAndDownloads", false); 798 this.validateCheckbox("formdata", true); 799 this.validateCheckbox("cache", true); 800 this.validateCheckbox("siteSettings", false); 801 802 this.checkPrefCheckbox("siteSettings", true); 803 this.checkPrefCheckbox("cookiesAndStorage", false); 804 this.acceptDialog(); 805 }; 806 dh.open(); 807 await dh.promiseClosed; 808 809 is( 810 Services.prefs.getBoolPref("privacy.sanitize.cpd.hasMigratedToNewPrefs3"), 811 true, 812 "Migration is complete for cpd branch" 813 ); 814 815 // make sure the migration doesn't run again 816 dh = new ClearHistoryDialogHelper({ mode: "clearHistory" }); 817 dh.onload = function () { 818 this.validateCheckbox("siteSettings", true); 819 this.validateCheckbox("cookiesAndStorage", false); 820 this.cancelDialog(); 821 }; 822 dh.open(); 823 await dh.promiseClosed; 824 }); 825 826 add_task(async function testClearHistoryCheckboxStatesAfterMigration3() { 827 await SpecialPowers.pushPrefEnv({ 828 set: [ 829 ["privacy.cpd.history", false], 830 ["privacy.cpd.formdata", true], 831 ["privacy.cpd.cookies", true], 832 ["privacy.cpd.offlineApps", false], 833 ["privacy.cpd.sessions", false], 834 ["privacy.cpd.siteSettings", true], 835 ["privacy.cpd.cache", true], 836 // Verify that prefs not in not touched in migration from v2 837 ["privacy.clearHistory.cookiesAndStorage", false], 838 ["privacy.clearHistory.siteSettings", false], 839 ["privacy.clearHistory.cache", false], 840 // Verify that formData and browsingHistoryAndDownloads inherit this value 841 ["privacy.clearHistory.historyFormDataAndDownloads", true], 842 // migrate from v2 to v3, dont redo the v1 to v2 migration 843 ["privacy.sanitize.cpd.hasMigratedToNewPrefs2", true], 844 ["privacy.sanitize.cpd.hasMigratedToNewPrefs3", false], 845 ], 846 }); 847 848 let dh = new ClearHistoryDialogHelper({ mode: "clearHistory" }); 849 dh.onload = function () { 850 // migration to v3 shouldn't modify these values 851 this.validateCheckbox("cookiesAndStorage", false); 852 this.validateCheckbox("siteSettings", false); 853 this.validateCheckbox("cache", false); 854 855 // migration to v3 should set them initially to true from historyFormDataAndDownloads pref 856 this.validateCheckbox("browsingHistoryAndDownloads", true); 857 this.validateCheckbox("formdata", true); 858 859 // flip two prefs to open to verify migration doesn't happen again and checkboxes retain their value 860 this.checkPrefCheckbox("siteSettings", true); 861 this.checkPrefCheckbox("browsingHistoryAndDownloads", false); 862 this.acceptDialog(); 863 }; 864 dh.open(); 865 await dh.promiseClosed; 866 867 is( 868 Services.prefs.getBoolPref("privacy.sanitize.cpd.hasMigratedToNewPrefs3"), 869 true, 870 "Migration is complete for cpd branch" 871 ); 872 873 // make sure the migration doesn't run again 874 dh = new ClearHistoryDialogHelper({ mode: "clearHistory" }); 875 dh.onload = function () { 876 this.validateCheckbox("siteSettings", true); 877 this.validateCheckbox("browsingHistoryAndDownloads", false); 878 this.cancelDialog(); 879 }; 880 dh.open(); 881 await dh.promiseClosed; 882 }); 883 }