diff options
Diffstat (limited to 'browser/components/preferences/tests')
8 files changed, 466 insertions, 40 deletions
diff --git a/browser/components/preferences/tests/browser.toml b/browser/components/preferences/tests/browser.toml index 9e619ce4be..523110dbc9 100644 --- a/browser/components/preferences/tests/browser.toml +++ b/browser/components/preferences/tests/browser.toml @@ -10,6 +10,11 @@ support-files = [ "addons/set_homepage.xpi", "addons/set_newtab.xpi", ] +skip-if = [ + "os == 'linux' && os_version == '18.04' && asan", # manifest runs too long + "os == 'linux' && os_version == '18.04' && tsan", # manifest runs too long + "win11_2009 && asan", # manifest runs too long +] ["browser_about_settings.js"] @@ -276,7 +281,6 @@ support-files = [ "subdialog.xhtml", "subdialog2.xhtml", ] -fail-if = ["a11y_checks"] # Bug 1854636 clicked label.dialogTitle, vbox#dialogTemplate.dialogOverlay may not be focusable ["browser_sync_chooseWhatToSync.js"] diff --git a/browser/components/preferences/tests/browser_applications_selection.js b/browser/components/preferences/tests/browser_applications_selection.js index 683ce76a89..23f0e00af8 100644 --- a/browser/components/preferences/tests/browser_applications_selection.js +++ b/browser/components/preferences/tests/browser_applications_selection.js @@ -335,10 +335,12 @@ add_task(async function sortingCheck() { "Number of items should not change." ); for (let i = 0; i < siteItems.length - 1; ++i) { - let aType = siteItems[i].getAttribute("actionDescription").toLowerCase(); - let bType = siteItems[i + 1] - .getAttribute("actionDescription") - .toLowerCase(); + let aType = ( + siteItems[i].getAttribute("actionDescription") || "" + ).toLowerCase(); + let bType = ( + siteItems[i + 1].getAttribute("actionDescription") || "" + ).toLowerCase(); let result = 0; if (aType > bType) { result = 1; @@ -375,10 +377,12 @@ add_task(async function sortingCheck() { "Number of items should not change." ); for (let i = 0; i < siteItems.length - 1; ++i) { - let aType = siteItems[i].getAttribute("typeDescription").toLowerCase(); - let bType = siteItems[i + 1] - .getAttribute("typeDescription") - .toLowerCase(); + let aType = ( + siteItems[i].getAttribute("typeDescription") || "" + ).toLowerCase(); + let bType = ( + siteItems[i + 1].getAttribute("typeDescription") || "" + ).toLowerCase(); let result = 0; if (aType > bType) { result = 1; diff --git a/browser/components/preferences/tests/browser_contentblocking.js b/browser/components/preferences/tests/browser_contentblocking.js index 3d33f2ed7d..c178233a72 100644 --- a/browser/components/preferences/tests/browser_contentblocking.js +++ b/browser/components/preferences/tests/browser_contentblocking.js @@ -1021,7 +1021,7 @@ add_task(async function testDisableTPCheckBoxDisablesEmailTP() { // Verify the checkbox is unchecked after clicking. is( tpCheckbox.getAttribute("checked"), - "", + null, "Tracking protection checkbox is unchecked" ); diff --git a/browser/components/preferences/tests/browser_privacy_dnsoverhttps.js b/browser/components/preferences/tests/browser_privacy_dnsoverhttps.js index 48469cfce4..ebe9c41127 100644 --- a/browser/components/preferences/tests/browser_privacy_dnsoverhttps.js +++ b/browser/components/preferences/tests/browser_privacy_dnsoverhttps.js @@ -16,6 +16,10 @@ ChromeUtils.defineESModuleGetters(this, { DoHTestUtils: "resource://testing-common/DoHTestUtils.sys.mjs", }); +const { MockRegistrar } = ChromeUtils.importESModule( + "resource://testing-common/MockRegistrar.sys.mjs" +); + const TRR_MODE_PREF = "network.trr.mode"; const TRR_URI_PREF = "network.trr.uri"; const TRR_CUSTOM_URI_PREF = "network.trr.custom_uri"; @@ -106,6 +110,164 @@ function waitForPrefObserver(name) { }); } +// Mock parental controls service in order to enable it +let parentalControlsService = { + parentalControlsEnabled: true, + QueryInterface: ChromeUtils.generateQI(["nsIParentalControlsService"]), +}; +let mockParentalControlsServiceCid = undefined; + +async function setMockParentalControlEnabled(aEnabled) { + if (mockParentalControlsServiceCid != undefined) { + MockRegistrar.unregister(mockParentalControlsServiceCid); + mockParentalControlsServiceCid = undefined; + } + if (aEnabled) { + mockParentalControlsServiceCid = MockRegistrar.register( + "@mozilla.org/parental-controls-service;1", + parentalControlsService + ); + } + Services.dns.reloadParentalControlEnabled(); +} + +add_task(async function testParentalControls() { + async function withConfiguration(configuration, fn) { + info("testParentalControls"); + + await resetPrefs(); + Services.prefs.setIntPref(TRR_MODE_PREF, configuration.trr_mode); + await setMockParentalControlEnabled(configuration.parentalControlsState); + + await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); + let doc = gBrowser.selectedBrowser.contentDocument; + let statusElement = doc.getElementById("dohStatus"); + + await TestUtils.waitForCondition(() => { + return ( + document.l10n.getAttributes(statusElement).args.status == + configuration.wait_for_doh_status + ); + }); + + await fn({ + statusElement, + }); + + gBrowser.removeCurrentTab(); + await setMockParentalControlEnabled(false); + } + + info("Check parental controls disabled, TRR off"); + await withConfiguration( + { + parentalControlsState: false, + trr_mode: 0, + wait_for_doh_status: "Off", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Off", + "expecting status off" + ); + } + ); + + info("Check parental controls enabled, TRR off"); + await withConfiguration( + { + parentalControlsState: true, + trr_mode: 0, + wait_for_doh_status: "Off", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Off", + "expecting status off" + ); + } + ); + + // Enable the rollout. + await DoHTestUtils.loadRemoteSettingsConfig({ + providers: "example", + rolloutEnabled: true, + steeringEnabled: false, + steeringProviders: "", + autoDefaultEnabled: false, + autoDefaultProviders: "", + id: "global", + }); + + info("Check parental controls disabled, TRR first"); + await withConfiguration( + { + parentalControlsState: false, + trr_mode: 2, + wait_for_doh_status: "Active", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Active", + "expecting status active" + ); + } + ); + + info("Check parental controls enabled, TRR first"); + await withConfiguration( + { + parentalControlsState: true, + trr_mode: 2, + wait_for_doh_status: "Not active (TRR_PARENTAL_CONTROL)", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Not active (TRR_PARENTAL_CONTROL)", + "expecting status not active" + ); + } + ); + + info("Check parental controls disabled, TRR only"); + await withConfiguration( + { + parentalControlsState: false, + trr_mode: 3, + wait_for_doh_status: "Active", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Active", + "expecting status active" + ); + } + ); + + info("Check parental controls enabled, TRR only"); + await withConfiguration( + { + parentalControlsState: true, + trr_mode: 3, + wait_for_doh_status: "Not active (TRR_PARENTAL_CONTROL)", + }, + async res => { + is( + document.l10n.getAttributes(res.statusElement).args.status, + "Not active (TRR_PARENTAL_CONTROL)", + "expecting status not active" + ); + } + ); + + await resetPrefs(); +}); + async function testWithProperties(props, startTime) { info( Date.now() - diff --git a/browser/components/preferences/tests/browser_subdialogs.js b/browser/components/preferences/tests/browser_subdialogs.js index 8763ae9146..b604ac0a7f 100644 --- a/browser/components/preferences/tests/browser_subdialogs.js +++ b/browser/components/preferences/tests/browser_subdialogs.js @@ -173,7 +173,7 @@ async function close_subdialog_and_test_generic_end_state( ); Assert.equal( frame.getAttribute("style"), - "", + null, "inline styles should be cleared" ); Assert.equal( @@ -407,17 +407,29 @@ add_task(async function background_click_should_close_dialog() { // Clicking on an inactive part of dialog itself should not close the dialog. // Click the dialog title bar here to make sure nothing happens. info("clicking the dialog title bar"); + // We intentionally turn off this a11y check, because the following click + // is purposefully targeting a non-interactive element to confirm the opened + // dialog won't be dismissed. It is not meant to be interactive and is not + // expected to be accessible, therefore this rule check shall be ignored by + // a11y_checks suite. + AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false }); BrowserTestUtils.synthesizeMouseAtCenter( ".dialogTitle", {}, tab.linkedBrowser ); + AccessibilityUtils.resetEnv(); // Close the dialog by clicking on the overlay background. Simulate a click // at point (2,2) instead of (0,0) so we are sure we're clicking on the // overlay background instead of some boundary condition that a real user // would never click. info("clicking the overlay background"); + // We intentionally turn off this a11y check, because the following click + // is purposefully targeting a non-interactive element to dismiss the opened + // dialog with a mouse which can be done by assistive technology and keyboard + // by pressing `Esc` key, this rule check shall be ignored by a11y_checks. + AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false }); await close_subdialog_and_test_generic_end_state( tab.linkedBrowser, function () { @@ -432,6 +444,7 @@ add_task(async function background_click_should_close_dialog() { 0, { runClosingFnOutsideOfContentTask: true } ); + AccessibilityUtils.resetEnv(); }); add_task(async function escape_should_close_dialog() { diff --git a/browser/components/preferences/tests/siteData/browser.toml b/browser/components/preferences/tests/siteData/browser.toml index 9f4f8306e1..b7e6ba1b6d 100644 --- a/browser/components/preferences/tests/siteData/browser.toml +++ b/browser/components/preferences/tests/siteData/browser.toml @@ -10,6 +10,8 @@ support-files = [ ["browser_clearSiteData.js"] +["browser_clearSiteData_v2.js"] + ["browser_siteData.js"] ["browser_siteData2.js"] diff --git a/browser/components/preferences/tests/siteData/browser_clearSiteData.js b/browser/components/preferences/tests/siteData/browser_clearSiteData.js index 7ae1fda453..4924dccfea 100644 --- a/browser/components/preferences/tests/siteData/browser_clearSiteData.js +++ b/browser/components/preferences/tests/siteData/browser_clearSiteData.js @@ -7,10 +7,6 @@ const { PermissionTestUtils } = ChromeUtils.importESModule( "resource://testing-common/PermissionTestUtils.sys.mjs" ); -let useOldClearHistoryDialog = Services.prefs.getBoolPref( - "privacy.sanitize.useOldClearHistoryDialog" -); - async function testClearData(clearSiteData, clearCache) { PermissionTestUtils.add( TEST_QUOTA_USAGE_ORIGIN, @@ -64,9 +60,7 @@ async function testClearData(clearSiteData, clearCache) { let doc = gBrowser.selectedBrowser.contentDocument; let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); - let url = useOldClearHistoryDialog - ? "chrome://browser/content/preferences/dialogs/clearSiteData.xhtml" - : "chrome://browser/content/sanitize_v2.xhtml"; + let url = "chrome://browser/content/preferences/dialogs/clearSiteData.xhtml"; let dialogOpened = promiseLoadSubDialog(url); clearSiteDataButton.doCommand(); let dialogWin = await dialogOpened; @@ -78,10 +72,8 @@ async function testClearData(clearSiteData, clearCache) { // since we've had cache intermittently changing under our feet. let [, convertedCacheUnit] = DownloadUtils.convertByteUnits(cacheUsage); - let cookiesCheckboxId = useOldClearHistoryDialog - ? "clearSiteData" - : "cookiesAndStorage"; - let cacheCheckboxId = useOldClearHistoryDialog ? "clearCache" : "cache"; + let cookiesCheckboxId = "clearSiteData"; + let cacheCheckboxId = "clearCache"; let clearSiteDataCheckbox = dialogWin.document.getElementById(cookiesCheckboxId); let clearCacheCheckbox = dialogWin.document.getElementById(cacheCheckboxId); @@ -106,28 +98,13 @@ async function testClearData(clearSiteData, clearCache) { clearSiteDataCheckbox.checked = clearSiteData; clearCacheCheckbox.checked = clearCache; - if (!useOldClearHistoryDialog) { - // The new clear history dialog has a seperate checkbox for site settings - let siteSettingsCheckbox = - dialogWin.document.getElementById("siteSettings"); - siteSettingsCheckbox.checked = clearSiteData; - // select clear everything to match the old dialog boxes behaviour for this test - let timespanSelection = dialogWin.document.getElementById( - "sanitizeDurationChoice" - ); - timespanSelection.value = 0; - } // Some additional promises/assertions to wait for // when deleting site data. let acceptPromise; let updatePromise; let cookiesClearedPromise; if (clearSiteData) { - // the new clear history dialog does not have a extra prompt - // to clear site data after clicking clear - if (useOldClearHistoryDialog) { - acceptPromise = BrowserTestUtils.promiseAlertDialogOpen("accept"); - } + acceptPromise = BrowserTestUtils.promiseAlertDialogOpen("accept"); updatePromise = promiseSiteDataManagerSitesUpdated(); cookiesClearedPromise = promiseCookiesCleared(); } @@ -137,7 +114,7 @@ async function testClearData(clearSiteData, clearCache) { let clearButton = dialogWin.document .querySelector("dialog") .getButton("accept"); - if (!clearSiteData && !clearCache && useOldClearHistoryDialog) { + if (!clearSiteData && !clearCache) { // Simulate user input on one of the checkboxes to trigger the event listener for // disabling the clearButton. clearCacheCheckbox.doCommand(); @@ -158,7 +135,7 @@ async function testClearData(clearSiteData, clearCache) { // For site data we display an extra warning dialog, make sure // to accept it. - if (clearSiteData && useOldClearHistoryDialog) { + if (clearSiteData) { await acceptPromise; } @@ -222,6 +199,12 @@ async function testClearData(clearSiteData, clearCache) { await SiteDataManager.removeAll(); } +add_setup(function () { + SpecialPowers.pushPrefEnv({ + set: [["privacy.sanitize.useOldClearHistoryDialog", true]], + }); +}); + // Test opening the "Clear All Data" dialog and cancelling. add_task(async function () { await testClearData(false, false); diff --git a/browser/components/preferences/tests/siteData/browser_clearSiteData_v2.js b/browser/components/preferences/tests/siteData/browser_clearSiteData_v2.js new file mode 100644 index 0000000000..8cb8be25b3 --- /dev/null +++ b/browser/components/preferences/tests/siteData/browser_clearSiteData_v2.js @@ -0,0 +1,258 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const { PermissionTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/PermissionTestUtils.sys.mjs" +); + +async function testClearData(clearSiteData, clearCache) { + PermissionTestUtils.add( + TEST_QUOTA_USAGE_ORIGIN, + "persistent-storage", + Services.perms.ALLOW_ACTION + ); + + // Open a test site which saves into appcache. + await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_OFFLINE_URL); + BrowserTestUtils.removeTab(gBrowser.selectedTab); + + // Fill indexedDB with test data. + // Don't wait for the page to load, to register the content event handler as quickly as possible. + // If this test goes intermittent, we might have to tell the page to wait longer before + // firing the event. + BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_QUOTA_USAGE_URL, false); + await BrowserTestUtils.waitForContentEvent( + gBrowser.selectedBrowser, + "test-indexedDB-done", + false, + null, + true + ); + BrowserTestUtils.removeTab(gBrowser.selectedTab); + + // Register some service workers. + await loadServiceWorkerTestPage(TEST_SERVICE_WORKER_URL); + await promiseServiceWorkerRegisteredFor(TEST_SERVICE_WORKER_URL); + + await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); + + // Test the initial states. + let cacheUsage = await SiteDataManager.getCacheSize(); + let quotaUsage = await SiteDataTestUtils.getQuotaUsage( + TEST_QUOTA_USAGE_ORIGIN + ); + let totalUsage = await SiteDataManager.getTotalUsage(); + Assert.greater(cacheUsage, 0, "The cache usage should not be 0"); + Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); + Assert.greater(totalUsage, 0, "The total usage should not be 0"); + + let initialSizeLabelValue = await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [], + async function () { + let sizeLabel = content.document.getElementById("totalSiteDataSize"); + return sizeLabel.textContent; + } + ); + + let doc = gBrowser.selectedBrowser.contentDocument; + let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); + + let url = "chrome://browser/content/sanitize_v2.xhtml"; + let dialogOpened = promiseLoadSubDialog(url); + clearSiteDataButton.doCommand(); + let dialogWin = await dialogOpened; + + // Convert the usage numbers in the same way the UI does it to assert + // that they're displayed in the dialog. + let [convertedTotalUsage] = DownloadUtils.convertByteUnits(totalUsage); + // For cache we just assert that the right unit (KB, probably) is displayed, + // since we've had cache intermittently changing under our feet. + let [, convertedCacheUnit] = DownloadUtils.convertByteUnits(cacheUsage); + + let cookiesCheckboxId = "cookiesAndStorage"; + let cacheCheckboxId = "cache"; + let clearSiteDataCheckbox = + dialogWin.document.getElementById(cookiesCheckboxId); + let clearCacheCheckbox = dialogWin.document.getElementById(cacheCheckboxId); + // The usage details are filled asynchronously, so we assert that they're present by + // waiting for them to be filled in. + await Promise.all([ + TestUtils.waitForCondition( + () => + clearSiteDataCheckbox.label && + clearSiteDataCheckbox.label.includes(convertedTotalUsage), + "Should show the quota usage" + ), + TestUtils.waitForCondition( + () => + clearCacheCheckbox.label && + clearCacheCheckbox.label.includes(convertedCacheUnit), + "Should show the cache usage" + ), + ]); + + // Check the boxes according to our test input. + clearSiteDataCheckbox.checked = clearSiteData; + clearCacheCheckbox.checked = clearCache; + + // select clear everything to match the old dialog boxes behaviour for this test + let timespanSelection = dialogWin.document.getElementById( + "sanitizeDurationChoice" + ); + timespanSelection.value = 1; + + // Some additional promises/assertions to wait for + // when deleting site data. + let updatePromise; + if (clearSiteData) { + // the new clear history dialog does not have a extra prompt + // to clear site data after clicking clear + updatePromise = promiseSiteDataManagerSitesUpdated(); + } + + let dialogClosed = BrowserTestUtils.waitForEvent(dialogWin, "unload"); + + let clearButton = dialogWin.document + .querySelector("dialog") + .getButton("accept"); + let cancelButton = dialogWin.document + .querySelector("dialog") + .getButton("cancel"); + + if (!clearSiteData && !clearCache) { + // Cancel, since we can't delete anything. + cancelButton.click(); + } else { + // Delete stuff! + clearButton.click(); + } + + await dialogClosed; + + if (clearCache) { + TestUtils.waitForCondition(async function () { + let usage = await SiteDataManager.getCacheSize(); + return usage == 0; + }, "The cache usage should be removed"); + } else { + Assert.greater( + await SiteDataManager.getCacheSize(), + 0, + "The cache usage should not be 0" + ); + } + + if (clearSiteData) { + await updatePromise; + await promiseServiceWorkersCleared(); + + TestUtils.waitForCondition(async function () { + let usage = await SiteDataManager.getTotalUsage(); + return usage == 0; + }, "The total usage should be removed"); + } else { + quotaUsage = await SiteDataTestUtils.getQuotaUsage(TEST_QUOTA_USAGE_ORIGIN); + totalUsage = await SiteDataManager.getTotalUsage(); + Assert.greater(quotaUsage, 0, "The quota usage should not be 0"); + Assert.greater(totalUsage, 0, "The total usage should not be 0"); + } + + if (clearCache || clearSiteData) { + // Check that the size label in about:preferences updates after we cleared data. + await SpecialPowers.spawn( + gBrowser.selectedBrowser, + [{ initialSizeLabelValue }], + async function (opts) { + let sizeLabel = content.document.getElementById("totalSiteDataSize"); + await ContentTaskUtils.waitForCondition( + () => sizeLabel.textContent != opts.initialSizeLabelValue, + "Site data size label should have updated." + ); + } + ); + } + + let permission = PermissionTestUtils.getPermissionObject( + TEST_QUOTA_USAGE_ORIGIN, + "persistent-storage" + ); + is( + clearSiteData ? permission : permission.capability, + clearSiteData ? null : Services.perms.ALLOW_ACTION, + "Should have the correct permission state." + ); + + BrowserTestUtils.removeTab(gBrowser.selectedTab); + await SiteDataManager.removeAll(); +} + +add_setup(function () { + SpecialPowers.pushPrefEnv({ + set: [["privacy.sanitize.useOldClearHistoryDialog", false]], + }); + + // The tests in this file all test specific interactions with the new clear + // history dialog and can't be split up. + requestLongerTimeout(2); +}); + +// Test opening the "Clear All Data" dialog and cancelling. +add_task(async function testNoSiteDataNoCacheClearing() { + await testClearData(false, false); +}); + +// Test opening the "Clear All Data" dialog and removing all site data. +add_task(async function testSiteDataClearing() { + await testClearData(true, false); +}); + +// Test opening the "Clear All Data" dialog and removing all cache. +add_task(async function testCacheClearing() { + await testClearData(false, true); +}); + +// Test opening the "Clear All Data" dialog and removing everything. +add_task(async function testSiteDataAndCacheClearing() { + await testClearData(true, true); +}); + +// Test clearing persistent storage +add_task(async function testPersistentStorage() { + PermissionTestUtils.add( + TEST_QUOTA_USAGE_ORIGIN, + "persistent-storage", + Services.perms.ALLOW_ACTION + ); + + await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true }); + + let doc = gBrowser.selectedBrowser.contentDocument; + let clearSiteDataButton = doc.getElementById("clearSiteDataButton"); + + let url = "chrome://browser/content/sanitize_v2.xhtml"; + let dialogOpened = promiseLoadSubDialog(url); + clearSiteDataButton.doCommand(); + let dialogWin = await dialogOpened; + let dialogClosed = BrowserTestUtils.waitForEvent(dialogWin, "unload"); + + let timespanSelection = dialogWin.document.getElementById( + "sanitizeDurationChoice" + ); + timespanSelection.value = 1; + let clearButton = dialogWin.document + .querySelector("dialog") + .getButton("accept"); + clearButton.click(); + await dialogClosed; + + let permission = PermissionTestUtils.getPermissionObject( + TEST_QUOTA_USAGE_ORIGIN, + "persistent-storage" + ); + is(permission, null, "Should have the correct permission state."); + + BrowserTestUtils.removeTab(gBrowser.selectedTab); +}); |