From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../browser_protectionsUI_cookie_banner.js | 475 +++++++++++++++++++++ 1 file changed, 475 insertions(+) create mode 100644 browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js (limited to 'browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js') diff --git a/browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js b/browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js new file mode 100644 index 0000000000..1d71f718fb --- /dev/null +++ b/browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js @@ -0,0 +1,475 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests the cookie banner handling section in the protections panel. + */ + +const { TelemetryTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/TelemetryTestUtils.sys.mjs" +); +const { sinon } = ChromeUtils.importESModule( + "resource://testing-common/Sinon.sys.mjs" +); + +const { MODE_DISABLED, MODE_REJECT, MODE_REJECT_OR_ACCEPT, MODE_UNSET } = + Ci.nsICookieBannerService; + +const exampleRules = JSON.stringify([ + { + id: "4b18afb0-76db-4f9e-a818-ed9a783fae6a", + cookies: {}, + click: { + optIn: "#foo", + presence: "#bar", + }, + domains: ["example.com"], + }, +]); + +/** + * Determines whether the cookie banner section in the protections panel should + * be visible with the given configuration. + * @param {*} options - Configuration to test. + * @param {Number} options.featureMode - nsICookieBannerService::Modes value for + * normal browsing. + * @param {Number} options.featureModePBM - nsICookieBannerService::Modes value + * for private browsing. + * @param {boolean} options.visibilityPref - State of the cookie banner UI + * visibility pref. + * @param {boolean} options.testPBM - Whether the window is in private browsing + * mode (true) or not (false). + * @returns {boolean} Whether the section should be visible for the given + * config. + */ +function cookieBannerSectionIsVisible({ + featureMode, + featureModePBM, + detectOnly, + visibilityPref, + testPBM, +}) { + if (!visibilityPref) { + return false; + } + if (detectOnly) { + return false; + } + + return ( + (testPBM && featureModePBM != MODE_DISABLED) || + (!testPBM && featureMode != MODE_DISABLED) + ); +} + +/** + * Runs a visibility test of the cookie banner section in the protections panel. + * @param {*} options - Test options. + * @param {Window} options.win - Browser window to use for testing. It's + * browsing mode should match the testPBM variable. + * @param {Number} options.featureMode - nsICookieBannerService::Modes value for + * normal browsing. + * @param {Number} options.featureModePBM - nsICookieBannerService::Modes value + * for private browsing. + * @param {boolean} options.visibilityPref - State of the cookie banner UI + * visibility pref. + * @param {boolean} options.testPBM - Whether the window is in private browsing + * mode (true) or not (false). + * @returns {Promise} Resolves once the test is complete. + */ +async function testSectionVisibility({ + win, + featureMode, + featureModePBM, + visibilityPref, + testPBM, +}) { + info( + "testSectionVisibility " + + JSON.stringify({ featureMode, featureModePBM, visibilityPref, testPBM }) + ); + // initialize the pref environment + await SpecialPowers.pushPrefEnv({ + set: [ + ["cookiebanners.service.mode", featureMode], + ["cookiebanners.service.mode.privateBrowsing", featureModePBM], + ["cookiebanners.ui.desktop.enabled", visibilityPref], + ], + }); + + // Open a tab with example.com so the protections panel can be opened. + await BrowserTestUtils.withNewTab( + { gBrowser: win.gBrowser, url: "https://example.com" }, + async () => { + await openProtectionsPanel(null, win); + + // Get panel elements to test + let el = { + section: win.document.getElementById( + "protections-popup-cookie-banner-section" + ), + sectionSeparator: win.document.getElementById( + "protections-popup-cookie-banner-section-separator" + ), + switch: win.document.getElementById( + "protections-popup-cookie-banner-switch" + ), + }; + + let expectVisible = cookieBannerSectionIsVisible({ + featureMode, + featureModePBM, + visibilityPref, + testPBM, + }); + is( + BrowserTestUtils.is_visible(el.section), + expectVisible, + `Cookie banner section should be ${ + expectVisible ? "visible" : "not visible" + }.` + ); + is( + BrowserTestUtils.is_visible(el.sectionSeparator), + expectVisible, + `Cookie banner section separator should be ${ + expectVisible ? "visible" : "not visible" + }.` + ); + is( + BrowserTestUtils.is_visible(el.switch), + expectVisible, + `Cookie banner switch should be ${ + expectVisible ? "visible" : "not visible" + }.` + ); + } + ); + + await SpecialPowers.popPrefEnv(); +} + +/** + * Tests cookie banner section visibility state in different configurations. + */ +add_task(async function test_section_visibility() { + // Test all combinations of cookie banner service modes and normal and + // private browsing. + + for (let testPBM of [false, true]) { + let win = window; + // Open a new private window to test the panel in for testing PBM, otherwise + // reuse the existing window. + if (testPBM) { + win = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + win.focus(); + } + + for (let featureMode of [ + MODE_DISABLED, + MODE_REJECT, + MODE_REJECT_OR_ACCEPT, + ]) { + for (let featureModePBM of [ + MODE_DISABLED, + MODE_REJECT, + MODE_REJECT_OR_ACCEPT, + ]) { + for (let detectOnly of [false, true]) { + // Testing detect only mode for normal browsing is sufficient. + if (detectOnly && featureModePBM != MODE_DISABLED) { + continue; + } + await testSectionVisibility({ + win, + featureMode, + featureModePBM, + detectOnly, + testPBM, + visibilityPref: true, + }); + } + } + } + + if (testPBM) { + await BrowserTestUtils.closeWindow(win); + } + } +}); + +/** + * Tests that the cookie banner section is only visible if enabled by UI pref. + */ +add_task(async function test_section_visibility_pref() { + for (let visibilityPref of [false, true]) { + await testSectionVisibility({ + win: window, + featureMode: MODE_REJECT, + featureModePBM: MODE_DISABLED, + testPBM: false, + visibilityPref, + }); + } +}); + +/** + * Test the state of the per-site exception switch in the cookie banner section + * and whether a matching per-site exception is set. + * @param {*} options + * @param {Window} options.win - Chrome window to test exception for (selected + * tab). + * @param {boolean} options.isPBM - Whether the given window is in private + * browsing mode. + * @param {string} options.expectedSwitchState - Whether the switch is expected to be + * "on" (CBH enabled), "off" (user added exception), or "unsupported" (no rules for site). + */ +function assertSwitchAndPrefState({ win, isPBM, expectedSwitchState }) { + let el = { + section: win.document.getElementById( + "protections-popup-cookie-banner-section" + ), + switch: win.document.getElementById( + "protections-popup-cookie-banner-switch" + ), + labelON: win.document.querySelector( + "#protections-popup-cookie-banner-detected" + ), + labelOFF: win.document.querySelector( + "#protections-popup-cookie-banner-site-disabled" + ), + labelUNDETECTED: win.document.querySelector( + "#protections-popup-cookie-banner-undetected" + ), + }; + + let currentURI = win.gBrowser.currentURI; + let pref = Services.cookieBanners.getDomainPref(currentURI, isPBM); + if (expectedSwitchState == "on") { + ok(el.section.dataset.state == "detected", "CBH switch is set to ON"); + + ok(BrowserTestUtils.is_visible(el.labelON), "ON label should be visible"); + ok( + !BrowserTestUtils.is_visible(el.labelOFF), + "OFF label should not be visible" + ); + ok( + !BrowserTestUtils.is_visible(el.labelUNDETECTED), + "UNDETECTED label should not be visible" + ); + + is( + pref, + MODE_UNSET, + `There should be no per-site exception for ${currentURI.spec}.` + ); + } else if (expectedSwitchState === "off") { + ok(el.section.dataset.state == "site-disabled", "CBH switch is set to OFF"); + + ok( + !BrowserTestUtils.is_visible(el.labelON), + "ON label should not be visible" + ); + ok(BrowserTestUtils.is_visible(el.labelOFF), "OFF label should be visible"); + ok( + !BrowserTestUtils.is_visible(el.labelUNDETECTED), + "UNDETECTED label should not be visible" + ); + + is( + pref, + MODE_DISABLED, + `There should be a per-site exception for ${currentURI.spec}.` + ); + } else { + ok(el.section.dataset.state == "undetected", "CBH not supported for site"); + + ok( + !BrowserTestUtils.is_visible(el.labelON), + "ON label should not be visible" + ); + ok( + !BrowserTestUtils.is_visible(el.labelOFF), + "OFF label should not be visible" + ); + ok( + BrowserTestUtils.is_visible(el.labelUNDETECTED), + "UNDETECTED label should be visible" + ); + } +} + +/** + * Test the telemetry associated with the cookie banner toggle. To be called + * after interacting with the toggle. + * @param {*} options + * @param {boolean|null} - Expected telemetry state matching the button state. + * button on = true = cookieb_toggle_on event. Pass null to expect no event + * recorded. + */ +function assertTelemetryState({ expectEnabled = null } = {}) { + info("Test telemetry state."); + + let events = []; + const CATEGORY = "security.ui.protectionspopup"; + const METHOD = "click"; + + if (expectEnabled != null) { + events.push({ + category: CATEGORY, + method: METHOD, + object: expectEnabled ? "cookieb_toggle_on" : "cookieb_toggle_off", + }); + } + + // Assert event state and clear event list. + TelemetryTestUtils.assertEvents(events, { + category: CATEGORY, + method: METHOD, + }); +} + +/** + * Test the cookie banner enable / disable by clicking the switch, then + * clicking the on/off button in the cookie banner subview. Assumes the + * protections panel is already open. + * + * @param {boolean} enable - Whether we want to enable or disable. + * @param {Window} win - Current chrome window under test. + */ +async function toggleCookieBannerHandling(enable, win) { + let switchEl = win.document.getElementById( + "protections-popup-cookie-banner-switch" + ); + let enableButton = win.document.getElementById( + "protections-popup-cookieBannerView-enable-button" + ); + let disableButton = win.document.getElementById( + "protections-popup-cookieBannerView-disable-button" + ); + let subView = win.document.getElementById( + "protections-popup-cookieBannerView" + ); + + let subViewShownPromise = BrowserTestUtils.waitForEvent(subView, "ViewShown"); + switchEl.click(); + await subViewShownPromise; + + if (enable) { + ok(BrowserTestUtils.is_visible(enableButton), "Enable button is visible"); + enableButton.click(); + } else { + ok(BrowserTestUtils.is_visible(disableButton), "Disable button is visible"); + disableButton.click(); + } +} + +function waitForProtectionsPopupHide(win = window) { + return BrowserTestUtils.waitForEvent( + win.document.getElementById("protections-popup"), + "popuphidden" + ); +} + +/** + * Tests the cookie banner section per-site preference toggle. + */ +add_task(async function test_section_toggle() { + // initialize the pref environment + await SpecialPowers.pushPrefEnv({ + set: [ + ["cookiebanners.service.mode", MODE_REJECT_OR_ACCEPT], + ["cookiebanners.service.mode.privateBrowsing", MODE_REJECT_OR_ACCEPT], + ["cookiebanners.ui.desktop.enabled", true], + ["cookiebanners.listService.testRules", exampleRules], + ["cookiebanners.listService.testSkipRemoteSettings", true], + ], + }); + + Services.cookieBanners.resetRules(false); + await BrowserTestUtils.waitForCondition( + () => !!Services.cookieBanners.rules.length, + "waiting for Services.cookieBanners.rules.length to be greater than 0" + ); + + // Test both normal and private browsing windows. For normal windows we reuse + // the existing one, for private windows we need to open a new window. + for (let testPBM of [false, true]) { + let win = window; + if (testPBM) { + win = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + } + + await BrowserTestUtils.withNewTab( + { gBrowser: win.gBrowser, url: "https://example.com" }, + async () => { + let clearSiteDataSpy = sinon.spy(window.SiteDataManager, "remove"); + + await openProtectionsPanel(null, win); + let switchEl = win.document.getElementById( + "protections-popup-cookie-banner-switch" + ); + info("Testing initial switch ON state."); + assertSwitchAndPrefState({ + win, + isPBM: testPBM, + switchEl, + expectedSwitchState: "on", + }); + assertTelemetryState(); + + info("Testing switch state after toggle OFF"); + let closePromise = waitForProtectionsPopupHide(win); + await toggleCookieBannerHandling(false, win); + await closePromise; + if (testPBM) { + Assert.ok( + clearSiteDataSpy.notCalled, + "clearSiteData should not be called in private browsing mode" + ); + } else { + Assert.ok( + clearSiteDataSpy.calledOnce, + "clearSiteData should be called in regular browsing mode" + ); + } + clearSiteDataSpy.restore(); + + await openProtectionsPanel(null, win); + assertSwitchAndPrefState({ + win, + isPBM: testPBM, + switchEl, + expectedSwitchState: "off", + }); + assertTelemetryState({ expectEnabled: false }); + + info("Testing switch state after toggle ON."); + closePromise = waitForProtectionsPopupHide(win); + await toggleCookieBannerHandling(true, win); + await closePromise; + + await openProtectionsPanel(null, win); + assertSwitchAndPrefState({ + win, + isPBM: testPBM, + switchEl, + expectedSwitchState: "on", + }); + assertTelemetryState({ expectEnabled: true }); + } + ); + + if (testPBM) { + await BrowserTestUtils.closeWindow(win); + } + } + + await SpecialPowers.popPrefEnv(); +}); -- cgit v1.2.3