summaryrefslogtreecommitdiffstats
path: root/browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js')
-rw-r--r--browser/base/content/test/protectionsUI/browser_protectionsUI_cookie_banner.js475
1 files changed, 475 insertions, 0 deletions
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();
+});