tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_contentblocking.js (53103B)


      1 /* eslint-env webextensions */
      2 
      3 "use strict";
      4 
      5 const { Preferences } = ChromeUtils.importESModule(
      6  "resource://gre/modules/Preferences.sys.mjs"
      7 );
      8 
      9 const TP_PREF = "privacy.trackingprotection.enabled";
     10 const TP_PBM_PREF = "privacy.trackingprotection.pbmode.enabled";
     11 const NCB_PREF = "network.cookie.cookieBehavior";
     12 const NCBP_PREF = "network.cookie.cookieBehavior.pbmode";
     13 const CAT_PREF = "browser.contentblocking.category";
     14 const FP_PREF = "privacy.trackingprotection.fingerprinting.enabled";
     15 const STP_PREF = "privacy.trackingprotection.socialtracking.enabled";
     16 const CRYPTO_TP_PREF = "privacy.trackingprotection.cryptomining.enabled";
     17 const EMAIL_TP_PREF = "privacy.trackingprotection.emailtracking.enabled";
     18 const EMAIL_TP_PBM_PREF =
     19  "privacy.trackingprotection.emailtracking.pbmode.enabled";
     20 const CONSENTMANAGER_SKIP_PREF =
     21  "privacy.trackingprotection.consentmanager.skip.enabled";
     22 const CONSENTMANAGER_SKIP_PBM_PREF =
     23  "privacy.trackingprotection.consentmanager.skip.pbmode.enabled";
     24 const LEVEL2_PREF = "privacy.annotate_channels.strict_list.enabled";
     25 const REFERRER_PREF = "network.http.referer.disallowCrossSiteRelaxingDefault";
     26 const REFERRER_TOP_PREF =
     27  "network.http.referer.disallowCrossSiteRelaxingDefault.top_navigation";
     28 const OCSP_PREF = "privacy.partition.network_state.ocsp_cache";
     29 const QUERY_PARAM_STRIP_PREF = "privacy.query_stripping.enabled";
     30 const QUERY_PARAM_STRIP_PBM_PREF = "privacy.query_stripping.enabled.pbmode";
     31 const PREF_TEST_NOTIFICATIONS =
     32  "browser.safebrowsing.test-notifications.enabled";
     33 const STRICT_PREF = "browser.contentblocking.features.strict";
     34 const PRIVACY_PAGE = "about:preferences#privacy";
     35 const ISOLATE_UI_PREF =
     36  "browser.contentblocking.reject-and-isolate-cookies.preferences.ui.enabled";
     37 const FPI_PREF = "privacy.firstparty.isolate";
     38 const FPP_PREF = "privacy.fingerprintingProtection";
     39 const FPP_PBM_PREF = "privacy.fingerprintingProtection.pbmode";
     40 const THIRD_PARTY_COOKIE_DEPRECATION_PREF =
     41  "network.cookie.cookieBehavior.optInPartitioning";
     42 const BTP_PREF = "privacy.bounceTrackingProtection.mode";
     43 const LNA_PREF = "network.lna.blocking";
     44 const LNA_ETP_PREF = "network.lna.etp.enabled";
     45 
     46 const { EnterprisePolicyTesting, PoliciesPrefTracker } =
     47  ChromeUtils.importESModule(
     48    "resource://testing-common/EnterprisePolicyTesting.sys.mjs"
     49  );
     50 
     51 requestLongerTimeout(3);
     52 
     53 // Enable LNA ETP integration for all tests so lna rules are processed
     54 add_setup(async function () {
     55  await SpecialPowers.pushPrefEnv({
     56    set: [[LNA_ETP_PREF, true]],
     57  });
     58 });
     59 
     60 add_task(async function testListUpdate() {
     61  SpecialPowers.pushPrefEnv({ set: [[PREF_TEST_NOTIFICATIONS, true]] });
     62 
     63  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
     64  let doc = gBrowser.contentDocument;
     65 
     66  let fingerprintersCheckbox = doc.getElementById(
     67    "contentBlockingFingerprintersCheckbox"
     68  );
     69  let updateObserved = TestUtils.topicObserved("safebrowsing-update-attempt");
     70  fingerprintersCheckbox.click();
     71  let url = (await updateObserved)[1];
     72 
     73  ok(true, "Has tried to update after the fingerprinting checkbox was toggled");
     74  is(
     75    url,
     76    "http://127.0.0.1:8888/safebrowsing-dummy/update",
     77    "Using the correct list url to update"
     78  );
     79 
     80  let cryptominersCheckbox = doc.getElementById(
     81    "contentBlockingCryptominersCheckbox"
     82  );
     83  updateObserved = TestUtils.topicObserved("safebrowsing-update-attempt");
     84  cryptominersCheckbox.click();
     85  url = (await updateObserved)[1];
     86 
     87  ok(true, "Has tried to update after the cryptomining checkbox was toggled");
     88  is(
     89    url,
     90    "http://127.0.0.1:8888/safebrowsing-dummy/update",
     91    "Using the correct list url to update"
     92  );
     93 
     94  gBrowser.removeCurrentTab();
     95 });
     96 
     97 // Tests that the content blocking main category checkboxes have the correct default state.
     98 add_task(async function testContentBlockingMainCategory() {
     99  let prefs = [
    100    [TP_PREF, false],
    101    [TP_PBM_PREF, true],
    102    [STP_PREF, false],
    103    [NCB_PREF, Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER],
    104    [
    105      NCBP_PREF,
    106      Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    107    ],
    108    [ISOLATE_UI_PREF, true],
    109    [FPI_PREF, false],
    110    [FPP_PREF, false],
    111    [FPP_PBM_PREF, true],
    112  ];
    113 
    114  for (let pref of prefs) {
    115    switch (typeof pref[1]) {
    116      case "boolean":
    117        SpecialPowers.setBoolPref(pref[0], pref[1]);
    118        break;
    119      case "number":
    120        SpecialPowers.setIntPref(pref[0], pref[1]);
    121        break;
    122    }
    123  }
    124 
    125  let checkboxes = [
    126    "#contentBlockingTrackingProtectionCheckbox",
    127    "#contentBlockingBlockCookiesCheckbox",
    128    "#contentBlockingFingerprintingProtectionCheckbox",
    129  ];
    130 
    131  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    132  let doc = gBrowser.contentDocument;
    133 
    134  for (let selector of checkboxes) {
    135    let element = doc.querySelector(selector);
    136    ok(element, "checkbox " + selector + " exists");
    137    ok(element.hasAttribute("checked"), "checkbox " + selector + " is checked");
    138  }
    139 
    140  // Ensure the dependent controls of the tracking protection subsection behave properly.
    141  let tpCheckbox = doc.querySelector(checkboxes[0]);
    142 
    143  let dependentControls = ["#trackingProtectionMenu"];
    144  let alwaysEnabledControls = [
    145    "#trackingProtectionMenuDesc",
    146    ".content-blocking-category-name",
    147    "#changeBlockListLink",
    148  ];
    149 
    150  tpCheckbox.checked = true;
    151 
    152  // Select "Always" under "All Detected Trackers".
    153  let menu = doc.querySelector("#trackingProtectionMenu");
    154  let always = doc.querySelector(
    155    "#trackingProtectionMenu > menupopup > menuitem[value=always]"
    156  );
    157  let privateElement = doc.querySelector(
    158    "#trackingProtectionMenu > menupopup > menuitem[value=private]"
    159  );
    160  menu.selectedItem = always;
    161  ok(
    162    !privateElement.selected,
    163    "The Only in private windows item should not be selected"
    164  );
    165  ok(always.selected, "The Always item should be selected");
    166 
    167  // The first time, privacy-pane-tp-ui-updated won't be dispatched since the
    168  // assignment above is a no-op.
    169 
    170  // Ensure the dependent controls are enabled
    171  checkControlState(doc, dependentControls, true);
    172  checkControlState(doc, alwaysEnabledControls, true);
    173 
    174  let promise = TestUtils.topicObserved("privacy-pane-tp-ui-updated");
    175  tpCheckbox.click();
    176 
    177  await promise;
    178  ok(!tpCheckbox.checked, "The checkbox should now be unchecked");
    179 
    180  // Ensure the dependent controls are disabled
    181  checkControlState(doc, dependentControls, false);
    182  checkControlState(doc, alwaysEnabledControls, true);
    183 
    184  // Make sure the selection in the tracking protection submenu persists after
    185  // a few times of checking and unchecking All Detected Trackers.
    186  // Doing this in a loop in order to avoid typing in the unrolled version manually.
    187  // We need to go from the checked state of the checkbox to unchecked back to
    188  // checked again...
    189  for (let i = 0; i < 3; ++i) {
    190    promise = TestUtils.topicObserved("privacy-pane-tp-ui-updated");
    191    tpCheckbox.click();
    192 
    193    await promise;
    194    is(tpCheckbox.checked, i % 2 == 0, "The checkbox should now be unchecked");
    195    is(
    196      privateElement.selected,
    197      i % 2 == 0,
    198      "The Only in private windows item should be selected by default, when the checkbox is checked"
    199    );
    200    ok(!always.selected, "The Always item should no longer be selected");
    201  }
    202 
    203  let cookieMenu = doc.querySelector("#blockCookiesMenu");
    204  let cookieMenuTrackers = cookieMenu.querySelector(
    205    "menupopup > menuitem[value=trackers]"
    206  );
    207  let cookieMenuTrackersPlusIsolate = cookieMenu.querySelector(
    208    "menupopup > menuitem[value=trackers-plus-isolate]"
    209  );
    210  let cookieMenuUnvisited = cookieMenu.querySelector(
    211    "menupopup > menuitem[value=unvisited]"
    212  );
    213  let cookieMenuAllThirdParties = doc.querySelector(
    214    "menupopup > menuitem[value=all-third-parties]"
    215  );
    216  let cookieMenuAll = cookieMenu.querySelector(
    217    "menupopup > menuitem[value=always]"
    218  );
    219  // Select block trackers
    220  cookieMenuTrackers.click();
    221  ok(cookieMenuTrackers.selected, "The trackers item should be selected");
    222  is(
    223    Services.prefs.getIntPref(NCB_PREF),
    224    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
    225    `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER}`
    226  );
    227  is(
    228    Services.prefs.getIntPref(NCBP_PREF),
    229    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    230    `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    231  );
    232  // Select block trackers and isolate
    233  cookieMenuTrackersPlusIsolate.click();
    234  ok(
    235    cookieMenuTrackersPlusIsolate.selected,
    236    "The trackers plus isolate item should be selected"
    237  );
    238  is(
    239    Services.prefs.getIntPref(NCB_PREF),
    240    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    241    `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    242  );
    243  is(
    244    Services.prefs.getIntPref(NCBP_PREF),
    245    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    246    `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    247  );
    248  // Select block unvisited
    249  cookieMenuUnvisited.click();
    250  ok(cookieMenuUnvisited.selected, "The unvisited item should be selected");
    251  is(
    252    Services.prefs.getIntPref(NCB_PREF),
    253    Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN,
    254    `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN}`
    255  );
    256  is(
    257    Services.prefs.getIntPref(NCBP_PREF),
    258    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    259    `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    260  );
    261  // Select block all third party
    262  cookieMenuAllThirdParties.click();
    263  ok(
    264    cookieMenuAllThirdParties.selected,
    265    "The all-third-parties item should be selected"
    266  );
    267  is(
    268    Services.prefs.getIntPref(NCB_PREF),
    269    Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
    270    `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN}`
    271  );
    272  is(
    273    Services.prefs.getIntPref(NCBP_PREF),
    274    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    275    `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    276  );
    277  // Select block all third party
    278  cookieMenuAll.click();
    279  ok(cookieMenuAll.selected, "The all cookies item should be selected");
    280  is(
    281    Services.prefs.getIntPref(NCB_PREF),
    282    Ci.nsICookieService.BEHAVIOR_REJECT,
    283    `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT}`
    284  );
    285  is(
    286    Services.prefs.getIntPref(NCBP_PREF),
    287    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    288    `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    289  );
    290 
    291  gBrowser.removeCurrentTab();
    292 
    293  // Ensure the block-trackers-plus-isolate option only shows in the dropdown if the UI pref is set.
    294  Services.prefs.setBoolPref(ISOLATE_UI_PREF, false);
    295  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    296  doc = gBrowser.contentDocument;
    297  cookieMenuTrackersPlusIsolate = doc.querySelector(
    298    "#blockCookiesMenu menupopup > menuitem[value=trackers-plus-isolate]"
    299  );
    300  ok(
    301    cookieMenuTrackersPlusIsolate.hidden,
    302    "Trackers plus isolate option is hidden from the dropdown if the ui pref is not set."
    303  );
    304 
    305  gBrowser.removeCurrentTab();
    306 
    307  // Ensure the block-trackers-plus-isolate option only shows in the dropdown if FPI is disabled.
    308  SpecialPowers.setIntPref(
    309    NCB_PREF,
    310    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
    311  );
    312  SpecialPowers.setBoolPref(FPI_PREF, true);
    313 
    314  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    315  doc = gBrowser.contentDocument;
    316  cookieMenuTrackers = doc.querySelector(
    317    "#blockCookiesMenu menupopup > menuitem[value=trackers]"
    318  );
    319  cookieMenuTrackersPlusIsolate = doc.querySelector(
    320    "#blockCookiesMenu menupopup > menuitem[value=trackers-plus-isolate]"
    321  );
    322  ok(cookieMenuTrackers.selected, "The trackers item should be selected");
    323  ok(
    324    cookieMenuTrackersPlusIsolate.hidden,
    325    "Trackers plus isolate option is hidden from the dropdown if the FPI pref is set."
    326  );
    327  gBrowser.removeCurrentTab();
    328 
    329  for (let pref of prefs) {
    330    SpecialPowers.clearUserPref(pref[0]);
    331  }
    332 });
    333 
    334 // Tests that the content blocking "Standard" category radio sets the prefs to their default values.
    335 add_task(async function testContentBlockingStandardCategory() {
    336  let prefs = {
    337    [TP_PREF]: null,
    338    [TP_PBM_PREF]: null,
    339    [NCB_PREF]: null,
    340    [NCBP_PREF]: null,
    341    [FP_PREF]: null,
    342    [STP_PREF]: null,
    343    [CRYPTO_TP_PREF]: null,
    344    [EMAIL_TP_PREF]: null,
    345    [EMAIL_TP_PBM_PREF]: null,
    346    [CONSENTMANAGER_SKIP_PREF]: null,
    347    [CONSENTMANAGER_SKIP_PBM_PREF]: null,
    348    [LEVEL2_PREF]: null,
    349    [REFERRER_PREF]: null,
    350    [REFERRER_TOP_PREF]: null,
    351    [OCSP_PREF]: null,
    352    [QUERY_PARAM_STRIP_PREF]: null,
    353    [QUERY_PARAM_STRIP_PBM_PREF]: null,
    354    [FPP_PREF]: null,
    355    [FPP_PBM_PREF]: null,
    356    [THIRD_PARTY_COOKIE_DEPRECATION_PREF]: null,
    357    [BTP_PREF]: null,
    358    [LNA_PREF]: null,
    359  };
    360 
    361  for (let pref in prefs) {
    362    Services.prefs.clearUserPref(pref);
    363    switch (Services.prefs.getPrefType(pref)) {
    364      case Services.prefs.PREF_BOOL:
    365        prefs[pref] = Services.prefs.getBoolPref(pref);
    366        break;
    367      case Services.prefs.PREF_INT:
    368        prefs[pref] = Services.prefs.getIntPref(pref);
    369        break;
    370      case Services.prefs.PREF_STRING:
    371        prefs[pref] = Services.prefs.getCharPref(pref);
    372        break;
    373      default:
    374        ok(false, `Unknown pref type for ${pref}`);
    375    }
    376  }
    377 
    378  Services.prefs.setBoolPref(TP_PREF, true);
    379  Services.prefs.setBoolPref(TP_PBM_PREF, false);
    380  Services.prefs.setIntPref(
    381    NCB_PREF,
    382    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    383  );
    384  Services.prefs.setIntPref(
    385    NCBP_PREF,
    386    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    387  );
    388  Services.prefs.setBoolPref(STP_PREF, !Services.prefs.getBoolPref(STP_PREF));
    389  Services.prefs.setBoolPref(FP_PREF, !Services.prefs.getBoolPref(FP_PREF));
    390  Services.prefs.setBoolPref(
    391    CRYPTO_TP_PREF,
    392    !Services.prefs.getBoolPref(CRYPTO_TP_PREF)
    393  );
    394  Services.prefs.setBoolPref(
    395    EMAIL_TP_PREF,
    396    !Services.prefs.getBoolPref(EMAIL_TP_PREF)
    397  );
    398  Services.prefs.setBoolPref(
    399    EMAIL_TP_PBM_PREF,
    400    !Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF)
    401  );
    402  Services.prefs.setBoolPref(
    403    CONSENTMANAGER_SKIP_PREF,
    404    !Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PREF)
    405  );
    406  Services.prefs.setBoolPref(
    407    CONSENTMANAGER_SKIP_PBM_PREF,
    408    !Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PBM_PREF)
    409  );
    410  Services.prefs.setBoolPref(
    411    LEVEL2_PREF,
    412    !Services.prefs.getBoolPref(LEVEL2_PREF)
    413  );
    414  Services.prefs.setBoolPref(
    415    REFERRER_PREF,
    416    !Services.prefs.getBoolPref(REFERRER_PREF)
    417  );
    418  Services.prefs.setBoolPref(
    419    REFERRER_TOP_PREF,
    420    !Services.prefs.getBoolPref(REFERRER_TOP_PREF)
    421  );
    422  Services.prefs.setBoolPref(OCSP_PREF, !Services.prefs.getBoolPref(OCSP_PREF));
    423  Services.prefs.setBoolPref(
    424    QUERY_PARAM_STRIP_PREF,
    425    !Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PREF)
    426  );
    427  Services.prefs.setBoolPref(
    428    QUERY_PARAM_STRIP_PBM_PREF,
    429    !Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PBM_PREF)
    430  );
    431  Services.prefs.setBoolPref(FPP_PREF, !Services.prefs.getBoolPref(FPP_PREF));
    432  Services.prefs.setBoolPref(
    433    FPP_PBM_PREF,
    434    !Services.prefs.getBoolPref(FPP_PBM_PREF)
    435  );
    436  Services.prefs.setBoolPref(
    437    THIRD_PARTY_COOKIE_DEPRECATION_PREF,
    438    !Services.prefs.getBoolPref(THIRD_PARTY_COOKIE_DEPRECATION_PREF)
    439  );
    440  Services.prefs.setIntPref(
    441    BTP_PREF,
    442    Ci.nsIBounceTrackingProtection.MODE_ENABLED
    443  );
    444 
    445  for (let pref in prefs) {
    446    switch (Services.prefs.getPrefType(pref)) {
    447      case Services.prefs.PREF_BOOL:
    448        // Account for prefs that may have retained their default value
    449        if (Services.prefs.getBoolPref(pref) != prefs[pref]) {
    450          ok(
    451            Services.prefs.prefHasUserValue(pref),
    452            `modified the pref ${pref}`
    453          );
    454        }
    455        break;
    456      case Services.prefs.PREF_INT:
    457        if (Services.prefs.getIntPref(pref) != prefs[pref]) {
    458          ok(
    459            Services.prefs.prefHasUserValue(pref),
    460            `modified the pref ${pref}`
    461          );
    462        }
    463        break;
    464      case Services.prefs.PREF_STRING:
    465        if (Services.prefs.getCharPref(pref) != prefs[pref]) {
    466          ok(
    467            Services.prefs.prefHasUserValue(pref),
    468            `modified the pref ${pref}`
    469          );
    470        }
    471        break;
    472      default:
    473        ok(false, `Unknown pref type for ${pref}`);
    474    }
    475  }
    476 
    477  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    478  let doc = gBrowser.contentDocument;
    479 
    480  let standardRadioOption = doc.getElementById("standardRadio");
    481  standardRadioOption.click();
    482 
    483  // TP prefs are reset async to check for extensions controlling them.
    484  await TestUtils.waitForCondition(
    485    () => !Services.prefs.prefHasUserValue(TP_PREF)
    486  );
    487 
    488  for (let pref in prefs) {
    489    ok(!Services.prefs.prefHasUserValue(pref), `reset the pref ${pref}`);
    490  }
    491  is(
    492    Services.prefs.getStringPref(CAT_PREF),
    493    "standard",
    494    `${CAT_PREF} has been set to standard`
    495  );
    496 
    497  gBrowser.removeCurrentTab();
    498 });
    499 
    500 // Tests that the content blocking "Strict" category radio sets the prefs to the expected values.
    501 add_task(async function testContentBlockingStrictCategory() {
    502  Services.prefs.setBoolPref(TP_PREF, false);
    503  Services.prefs.setBoolPref(TP_PBM_PREF, false);
    504  Services.prefs.setBoolPref(EMAIL_TP_PREF, false);
    505  Services.prefs.setBoolPref(EMAIL_TP_PBM_PREF, false);
    506  Services.prefs.setBoolPref(CONSENTMANAGER_SKIP_PREF, false);
    507  Services.prefs.setBoolPref(CONSENTMANAGER_SKIP_PBM_PREF, false);
    508  Services.prefs.setBoolPref(LEVEL2_PREF, false);
    509  Services.prefs.setBoolPref(REFERRER_PREF, false);
    510  Services.prefs.setBoolPref(REFERRER_TOP_PREF, false);
    511  Services.prefs.setBoolPref(OCSP_PREF, false);
    512  Services.prefs.setBoolPref(QUERY_PARAM_STRIP_PREF, false);
    513  Services.prefs.setBoolPref(QUERY_PARAM_STRIP_PBM_PREF, false);
    514  Services.prefs.setBoolPref(FPP_PREF, false);
    515  Services.prefs.setBoolPref(FPP_PBM_PREF, false);
    516  Services.prefs.setIntPref(
    517    NCB_PREF,
    518    Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN
    519  );
    520  Services.prefs.setIntPref(
    521    NCBP_PREF,
    522    Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN
    523  );
    524  Services.prefs.setBoolPref(THIRD_PARTY_COOKIE_DEPRECATION_PREF, false);
    525  Services.prefs.setIntPref(
    526    BTP_PREF,
    527    Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN
    528  );
    529  Services.prefs.setBoolPref(LNA_PREF, false);
    530  let strict_pref = Services.prefs.getStringPref(STRICT_PREF).split(",");
    531 
    532  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    533  let doc = gBrowser.contentDocument;
    534 
    535  let strictRadioOption = doc.getElementById("strictRadio");
    536  strictRadioOption.click();
    537 
    538  // TP prefs are reset async to check for extensions controlling them.
    539  await TestUtils.waitForCondition(
    540    () => Services.prefs.getStringPref(CAT_PREF) == "strict"
    541  );
    542  // Depending on the definition of the STRICT_PREF, the dependant prefs may have been
    543  // set to varying values. Ensure they have been set according to this definition.
    544  for (let pref of strict_pref) {
    545    switch (pref) {
    546      case "tp":
    547        is(
    548          Services.prefs.getBoolPref(TP_PREF),
    549          true,
    550          `${TP_PREF} has been set to true`
    551        );
    552        break;
    553      case "-tp":
    554        is(
    555          Services.prefs.getBoolPref(TP_PREF),
    556          false,
    557          `${TP_PREF} has been set to false`
    558        );
    559        break;
    560      case "tpPrivate":
    561        is(
    562          Services.prefs.getBoolPref(TP_PBM_PREF),
    563          true,
    564          `${TP_PBM_PREF} has been set to true`
    565        );
    566        break;
    567      case "-tpPrivate":
    568        is(
    569          Services.prefs.getBoolPref(TP_PBM_PREF),
    570          false,
    571          `${TP_PBM_PREF} has been set to false`
    572        );
    573        break;
    574      case "fp":
    575        is(
    576          Services.prefs.getBoolPref(FP_PREF),
    577          true,
    578          `${FP_PREF} has been set to true`
    579        );
    580        break;
    581      case "-fp":
    582        is(
    583          Services.prefs.getBoolPref(FP_PREF),
    584          false,
    585          `${FP_PREF} has been set to false`
    586        );
    587        break;
    588      case "stp":
    589        is(
    590          Services.prefs.getBoolPref(STP_PREF),
    591          true,
    592          `${STP_PREF} has been set to true`
    593        );
    594        break;
    595      case "-stp":
    596        is(
    597          Services.prefs.getBoolPref(STP_PREF),
    598          false,
    599          `${STP_PREF} has been set to false`
    600        );
    601        break;
    602      case "cryptoTP":
    603        is(
    604          Services.prefs.getBoolPref(CRYPTO_TP_PREF),
    605          true,
    606          `${CRYPTO_TP_PREF} has been set to true`
    607        );
    608        break;
    609      case "-cryptoTP":
    610        is(
    611          Services.prefs.getBoolPref(CRYPTO_TP_PREF),
    612          false,
    613          `${CRYPTO_TP_PREF} has been set to false`
    614        );
    615        break;
    616      case "emailTP":
    617        is(
    618          Services.prefs.getBoolPref(EMAIL_TP_PREF),
    619          true,
    620          `${EMAIL_TP_PREF} has been set to true`
    621        );
    622        break;
    623      case "-emailTP":
    624        is(
    625          Services.prefs.getBoolPref(EMAIL_TP_PREF),
    626          false,
    627          `${EMAIL_TP_PREF} has been set to false`
    628        );
    629        break;
    630      case "emailTPPrivate":
    631        is(
    632          Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF),
    633          true,
    634          `${EMAIL_TP_PBM_PREF} has been set to true`
    635        );
    636        break;
    637      case "-emailTPPrivate":
    638        is(
    639          Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF),
    640          false,
    641          `${EMAIL_TP_PBM_PREF} has been set to false`
    642        );
    643        break;
    644      case "consentmanagerSkip":
    645        is(
    646          Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PREF),
    647          true,
    648          `${CONSENTMANAGER_SKIP_PREF} has been set to true`
    649        );
    650        break;
    651      case "-consentmanagerSkip":
    652        is(
    653          Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PREF),
    654          false,
    655          `${CONSENTMANAGER_SKIP_PREF} has been set to false`
    656        );
    657        break;
    658      case "consentmanagerSkipPrivate":
    659        is(
    660          Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PBM_PREF),
    661          true,
    662          `${CONSENTMANAGER_SKIP_PBM_PREF} has been set to true`
    663        );
    664        break;
    665      case "-consentmanagerSkipPrivate":
    666        is(
    667          Services.prefs.getBoolPref(CONSENTMANAGER_SKIP_PBM_PREF),
    668          false,
    669          `${CONSENTMANAGER_SKIP_PBM_PREF} has been set to false`
    670        );
    671        break;
    672      case "lvl2":
    673        is(
    674          Services.prefs.getBoolPref(LEVEL2_PREF),
    675          true,
    676          `${CRYPTO_TP_PREF} has been set to true`
    677        );
    678        break;
    679      case "-lvl2":
    680        is(
    681          Services.prefs.getBoolPref(LEVEL2_PREF),
    682          false,
    683          `${CRYPTO_TP_PREF} has been set to false`
    684        );
    685        break;
    686      case "rp":
    687        is(
    688          Services.prefs.getBoolPref(REFERRER_PREF),
    689          true,
    690          `${REFERRER_PREF} has been set to true`
    691        );
    692        break;
    693      case "-rp":
    694        is(
    695          Services.prefs.getBoolPref(REFERRER_PREF),
    696          false,
    697          `${REFERRER_PREF} has been set to false`
    698        );
    699        break;
    700      case "rpTop":
    701        is(
    702          Services.prefs.getBoolPref(REFERRER_TOP_PREF),
    703          true,
    704          `${REFERRER_TOP_PREF} has been set to true`
    705        );
    706        break;
    707      case "-rpTop":
    708        is(
    709          Services.prefs.getBoolPref(REFERRER_TOP_PREF),
    710          false,
    711          `${REFERRER_TOP_PREF} has been set to false`
    712        );
    713        break;
    714      case "ocsp":
    715        is(
    716          Services.prefs.getBoolPref(OCSP_PREF),
    717          true,
    718          `${OCSP_PREF} has been set to true`
    719        );
    720        break;
    721      case "-ocsp":
    722        is(
    723          Services.prefs.getBoolPref(OCSP_PREF),
    724          false,
    725          `${OCSP_PREF} has been set to false`
    726        );
    727        break;
    728      case "qps":
    729        is(
    730          Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PREF),
    731          true,
    732          `${QUERY_PARAM_STRIP_PREF} has been set to true`
    733        );
    734        break;
    735      case "-qps":
    736        is(
    737          Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PREF),
    738          false,
    739          `${QUERY_PARAM_STRIP_PREF} has been set to false`
    740        );
    741        break;
    742      case "qpsPBM":
    743        is(
    744          Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PBM_PREF),
    745          true,
    746          `${QUERY_PARAM_STRIP_PBM_PREF} has been set to true`
    747        );
    748        break;
    749      case "-qpsPBM":
    750        is(
    751          Services.prefs.getBoolPref(QUERY_PARAM_STRIP_PBM_PREF),
    752          false,
    753          `${QUERY_PARAM_STRIP_PBM_PREF} has been set to false`
    754        );
    755        break;
    756      case "fpp":
    757        is(
    758          Services.prefs.getBoolPref(FPP_PREF),
    759          true,
    760          `${FPP_PREF} has been set to true`
    761        );
    762        break;
    763      case "-fpp":
    764        is(
    765          Services.prefs.getBoolPref(FPP_PREF),
    766          false,
    767          `${FPP_PREF} has been set to false`
    768        );
    769        break;
    770      case "fppPrivate":
    771        is(
    772          Services.prefs.getBoolPref(FPP_PBM_PREF),
    773          true,
    774          `${FPP_PBM_PREF} has been set to true`
    775        );
    776        break;
    777      case "-fppPrivate":
    778        is(
    779          Services.prefs.getBoolPref(FPP_PBM_PREF),
    780          false,
    781          `${FPP_PBM_PREF} has been set to false`
    782        );
    783        break;
    784      case "cookieBehavior0":
    785        is(
    786          Services.prefs.getIntPref(NCB_PREF),
    787          Ci.nsICookieService.BEHAVIOR_ACCEPT,
    788          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_ACCEPT}`
    789        );
    790        break;
    791      case "cookieBehavior1":
    792        is(
    793          Services.prefs.getIntPref(NCB_PREF),
    794          Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
    795          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN}`
    796        );
    797        break;
    798      case "cookieBehavior2":
    799        is(
    800          Services.prefs.getIntPref(NCB_PREF),
    801          Ci.nsICookieService.BEHAVIOR_REJECT,
    802          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT}`
    803        );
    804        break;
    805      case "cookieBehavior3":
    806        is(
    807          Services.prefs.getIntPref(NCB_PREF),
    808          Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN,
    809          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN}`
    810        );
    811        break;
    812      case "cookieBehavior4":
    813        is(
    814          Services.prefs.getIntPref(NCB_PREF),
    815          Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
    816          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER}`
    817        );
    818        break;
    819      case "cookieBehavior5":
    820        is(
    821          Services.prefs.getIntPref(NCB_PREF),
    822          Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    823          `${NCB_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    824        );
    825        break;
    826      case "cookieBehaviorPBM0":
    827        is(
    828          Services.prefs.getIntPref(NCBP_PREF),
    829          Ci.nsICookieService.BEHAVIOR_ACCEPT,
    830          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_ACCEPT}`
    831        );
    832        break;
    833      case "cookieBehaviorPBM1":
    834        is(
    835          Services.prefs.getIntPref(NCBP_PREF),
    836          Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
    837          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN}`
    838        );
    839        break;
    840      case "cookieBehaviorPBM2":
    841        is(
    842          Services.prefs.getIntPref(NCBP_PREF),
    843          Ci.nsICookieService.BEHAVIOR_REJECT,
    844          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT}`
    845        );
    846        break;
    847      case "cookieBehaviorPBM3":
    848        is(
    849          Services.prefs.getIntPref(NCBP_PREF),
    850          Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN,
    851          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_LIMIT_FOREIGN}`
    852        );
    853        break;
    854      case "cookieBehaviorPBM4":
    855        is(
    856          Services.prefs.getIntPref(NCBP_PREF),
    857          Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER,
    858          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER}`
    859        );
    860        break;
    861      case "cookieBehaviorPBM5":
    862        is(
    863          Services.prefs.getIntPref(NCBP_PREF),
    864          Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN,
    865          `${NCBP_PREF} has been set to ${Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN}`
    866        );
    867        break;
    868      case "3pcd":
    869        is(
    870          Services.prefs.getBoolPref(THIRD_PARTY_COOKIE_DEPRECATION_PREF),
    871          true,
    872          `${THIRD_PARTY_COOKIE_DEPRECATION_PREF} has been set to true`
    873        );
    874        break;
    875      case "-3pcd":
    876        is(
    877          Services.prefs.getBoolPref(THIRD_PARTY_COOKIE_DEPRECATION_PREF),
    878          false,
    879          `${THIRD_PARTY_COOKIE_DEPRECATION_PREF} has been set to false`
    880        );
    881        break;
    882      case "btp":
    883        is(
    884          Services.prefs.getIntPref(BTP_PREF),
    885          Ci.nsIBounceTrackingProtection.MODE_ENABLED,
    886          `${BTP_PREF} has been set to MODE_ENABLED`
    887        );
    888        break;
    889      case "-btp":
    890        is(
    891          Services.prefs.getIntPref(BTP_PREF),
    892          Ci.nsIBounceTrackingProtection.MODE_ENABLED_DRY_RUN,
    893          `${BTP_PREF} has been set to MODE_ENABLED_DRY_RUN`
    894        );
    895        break;
    896      case "lna":
    897        is(
    898          Services.prefs.getBoolPref(LNA_PREF),
    899          true,
    900          `${LNA_PREF} has been set to true`
    901        );
    902        break;
    903      case "-lna":
    904        is(
    905          Services.prefs.getBoolPref(LNA_PREF),
    906          false,
    907          `${LNA_PREF} has been set to false`
    908        );
    909        break;
    910      default:
    911        ok(false, "unknown option was added to the strict pref");
    912        break;
    913    }
    914  }
    915 
    916  gBrowser.removeCurrentTab();
    917 });
    918 
    919 // Tests that the content blocking "Custom" category behaves as expected.
    920 add_task(async function testContentBlockingCustomCategory() {
    921  let untouchedPrefs = [
    922    TP_PREF,
    923    TP_PBM_PREF,
    924    NCB_PREF,
    925    NCBP_PREF,
    926    FP_PREF,
    927    STP_PREF,
    928    CRYPTO_TP_PREF,
    929    REFERRER_PREF,
    930    REFERRER_TOP_PREF,
    931    OCSP_PREF,
    932    QUERY_PARAM_STRIP_PREF,
    933    QUERY_PARAM_STRIP_PBM_PREF,
    934  ];
    935 
    936  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
    937  let doc = gBrowser.contentDocument;
    938  let strictRadioOption = doc.getElementById("strictRadio");
    939  let standardRadioOption = doc.getElementById("standardRadio");
    940  let customRadioOption = doc.getElementById("customRadio");
    941  let defaults = new Preferences({ defaultBranch: true });
    942 
    943  standardRadioOption.click();
    944  await TestUtils.waitForCondition(
    945    () => !Services.prefs.prefHasUserValue(TP_PREF)
    946  );
    947 
    948  customRadioOption.click();
    949  await TestUtils.waitForCondition(
    950    () => Services.prefs.getStringPref(CAT_PREF) == "custom"
    951  );
    952 
    953  // The custom option will only force change of some prefs, like CAT_PREF. All
    954  // other prefs should remain as they were for standard.
    955  for (let pref of untouchedPrefs) {
    956    ok(
    957      !Services.prefs.prefHasUserValue(pref),
    958      `the pref ${pref} remains as default value`
    959    );
    960  }
    961 
    962  is(
    963    Services.prefs.getStringPref(CAT_PREF),
    964    "custom",
    965    `${CAT_PREF} has been set to custom`
    966  );
    967 
    968  strictRadioOption.click();
    969  await TestUtils.waitForCondition(
    970    () => Services.prefs.getStringPref(CAT_PREF) == "strict"
    971  );
    972 
    973  // Changing the following prefs should necessarily set CAT_PREF to "custom"
    974  for (let pref of [
    975    FP_PREF,
    976    STP_PREF,
    977    CRYPTO_TP_PREF,
    978    TP_PREF,
    979    TP_PBM_PREF,
    980    REFERRER_PREF,
    981    REFERRER_TOP_PREF,
    982    OCSP_PREF,
    983    QUERY_PARAM_STRIP_PREF,
    984    QUERY_PARAM_STRIP_PBM_PREF,
    985  ]) {
    986    Services.prefs.setBoolPref(pref, !Services.prefs.getBoolPref(pref));
    987    await TestUtils.waitForCondition(
    988      () => Services.prefs.getStringPref(CAT_PREF) == "custom"
    989    );
    990    is(
    991      Services.prefs.getStringPref(CAT_PREF),
    992      "custom",
    993      `${CAT_PREF} has been set to custom`
    994    );
    995 
    996    strictRadioOption.click();
    997    await TestUtils.waitForCondition(
    998      () => Services.prefs.getStringPref(CAT_PREF) == "strict"
    999    );
   1000  }
   1001 
   1002  // Changing the NCB_PREF should necessarily set CAT_PREF to "custom"
   1003  let defaultNCB = defaults.get(NCB_PREF);
   1004  let nonDefaultNCB;
   1005  switch (defaultNCB) {
   1006    case Ci.nsICookieService.BEHAVIOR_ACCEPT:
   1007      nonDefaultNCB = Ci.nsICookieService.BEHAVIOR_REJECT;
   1008      break;
   1009    case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
   1010    case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN:
   1011      nonDefaultNCB = Ci.nsICookieService.BEHAVIOR_ACCEPT;
   1012      break;
   1013    default:
   1014      ok(
   1015        false,
   1016        "Unexpected default value found for " + NCB_PREF + ": " + defaultNCB
   1017      );
   1018      break;
   1019  }
   1020  Services.prefs.setIntPref(NCB_PREF, nonDefaultNCB);
   1021  await TestUtils.waitForCondition(() =>
   1022    Services.prefs.prefHasUserValue(NCB_PREF)
   1023  );
   1024  is(
   1025    Services.prefs.getStringPref(CAT_PREF),
   1026    "custom",
   1027    `${CAT_PREF} has been set to custom`
   1028  );
   1029 
   1030  strictRadioOption.click();
   1031  await TestUtils.waitForCondition(
   1032    () => Services.prefs.getStringPref(CAT_PREF) == "strict"
   1033  );
   1034 
   1035  // Changing the NCBP_PREF should necessarily set CAT_PREF to "custom"
   1036  let defaultNCBP = defaults.get(NCBP_PREF);
   1037  let nonDefaultNCBP;
   1038  switch (defaultNCBP) {
   1039    case Ci.nsICookieService.BEHAVIOR_ACCEPT:
   1040      nonDefaultNCBP = Ci.nsICookieService.BEHAVIOR_REJECT;
   1041      break;
   1042    case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER:
   1043    case Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN:
   1044      nonDefaultNCBP = Ci.nsICookieService.BEHAVIOR_ACCEPT;
   1045      break;
   1046    default:
   1047      ok(
   1048        false,
   1049        "Unexpected default value found for " + NCBP_PREF + ": " + defaultNCBP
   1050      );
   1051      break;
   1052  }
   1053  Services.prefs.setIntPref(NCBP_PREF, nonDefaultNCBP);
   1054  await TestUtils.waitForCondition(() =>
   1055    Services.prefs.prefHasUserValue(NCBP_PREF)
   1056  );
   1057  is(
   1058    Services.prefs.getStringPref(CAT_PREF),
   1059    "custom",
   1060    `${CAT_PREF} has been set to custom`
   1061  );
   1062 
   1063  for (let pref of untouchedPrefs) {
   1064    SpecialPowers.clearUserPref(pref);
   1065  }
   1066 
   1067  gBrowser.removeCurrentTab();
   1068 });
   1069 
   1070 function checkControlState(doc, controls, enabled) {
   1071  for (let selector of controls) {
   1072    for (let control of doc.querySelectorAll(selector)) {
   1073      is(
   1074        !control.hasAttribute("disabled"),
   1075        enabled,
   1076        `${selector} is ${enabled ? "enabled" : "disabled"}.`
   1077      );
   1078    }
   1079  }
   1080 }
   1081 
   1082 // Checks that the menulists for tracking protection and cookie blocking are disabled when all TP prefs are off.
   1083 add_task(async function testContentBlockingDependentTPControls() {
   1084  SpecialPowers.pushPrefEnv({
   1085    set: [
   1086      [TP_PREF, false],
   1087      [TP_PBM_PREF, false],
   1088      [NCB_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT],
   1089      [CAT_PREF, "custom"],
   1090    ],
   1091  });
   1092 
   1093  let disabledControls = ["#trackingProtectionMenu", "#blockCookiesMenu"];
   1094 
   1095  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1096  let doc = gBrowser.contentDocument;
   1097  checkControlState(doc, disabledControls, false);
   1098 
   1099  gBrowser.removeCurrentTab();
   1100 });
   1101 
   1102 // Checks that disabling tracking protection also disables email tracking protection.
   1103 add_task(async function testDisableTPCheckBoxDisablesEmailTP() {
   1104  SpecialPowers.pushPrefEnv({
   1105    set: [
   1106      [TP_PREF, false],
   1107      [TP_PBM_PREF, true],
   1108      [EMAIL_TP_PREF, false],
   1109      [EMAIL_TP_PBM_PREF, true],
   1110      [CAT_PREF, "custom"],
   1111    ],
   1112  });
   1113 
   1114  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1115  let doc = gBrowser.contentDocument;
   1116 
   1117  // Click the checkbox to disable TP and check if this disables Email TP.
   1118  let tpCheckbox = doc.getElementById(
   1119    "contentBlockingTrackingProtectionCheckbox"
   1120  );
   1121 
   1122  // Verify the initial check state of the tracking protection checkbox.
   1123  ok(
   1124    tpCheckbox.hasAttribute("checked"),
   1125    "Tracking protection checkbox is checked initially"
   1126  );
   1127 
   1128  tpCheckbox.click();
   1129 
   1130  // Verify the checkbox is unchecked after clicking.
   1131  is(
   1132    tpCheckbox.getAttribute("checked"),
   1133    null,
   1134    "Tracking protection checkbox is unchecked"
   1135  );
   1136 
   1137  // Verify the pref states.
   1138  is(
   1139    Services.prefs.getBoolPref(EMAIL_TP_PREF),
   1140    false,
   1141    `${EMAIL_TP_PREF} has been set to false`
   1142  );
   1143 
   1144  is(
   1145    Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF),
   1146    false,
   1147    `${EMAIL_TP_PBM_PREF} has been set to false`
   1148  );
   1149 
   1150  gBrowser.removeCurrentTab();
   1151 });
   1152 
   1153 // Checks that the email tracking prefs set properly with tracking protection
   1154 // drop downs.
   1155 add_task(async function testTPMenuForEmailTP() {
   1156  SpecialPowers.pushPrefEnv({
   1157    set: [
   1158      [TP_PREF, false],
   1159      [TP_PBM_PREF, true],
   1160      [EMAIL_TP_PREF, false],
   1161      [EMAIL_TP_PBM_PREF, true],
   1162      [CAT_PREF, "custom"],
   1163    ],
   1164  });
   1165 
   1166  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1167  let doc = gBrowser.contentDocument;
   1168 
   1169  let menu = doc.querySelector("#trackingProtectionMenu");
   1170  let always = doc.querySelector(
   1171    "#trackingProtectionMenu > menupopup > menuitem[value=always]"
   1172  );
   1173  let privateElement = doc.querySelector(
   1174    "#trackingProtectionMenu > menupopup > menuitem[value=private]"
   1175  );
   1176 
   1177  // Click the always option on the tracking protection drop down.
   1178  menu.selectedItem = always;
   1179  always.click();
   1180 
   1181  // Verify the pref states.
   1182  is(
   1183    Services.prefs.getBoolPref(EMAIL_TP_PREF),
   1184    true,
   1185    `${EMAIL_TP_PREF} has been set to true`
   1186  );
   1187 
   1188  is(
   1189    Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF),
   1190    true,
   1191    `${EMAIL_TP_PBM_PREF} has been set to true`
   1192  );
   1193 
   1194  // Click the private-only option on the tracking protection drop down.
   1195  menu.selectedItem = privateElement;
   1196  privateElement.click();
   1197 
   1198  // Verify the pref states.
   1199  is(
   1200    Services.prefs.getBoolPref(EMAIL_TP_PREF),
   1201    false,
   1202    `${EMAIL_TP_PREF} has been set to false`
   1203  );
   1204 
   1205  is(
   1206    Services.prefs.getBoolPref(EMAIL_TP_PBM_PREF),
   1207    true,
   1208    `${EMAIL_TP_PBM_PREF} has been set to true`
   1209  );
   1210 
   1211  gBrowser.removeCurrentTab();
   1212 });
   1213 
   1214 // Ensure the FPP checkbox in ETP custom works properly.
   1215 add_task(async function testFPPCustomCheckBox() {
   1216  // Set the FPP prefs to the default state.
   1217  SpecialPowers.pushPrefEnv({
   1218    set: [
   1219      [FPP_PREF, false],
   1220      [FPP_PBM_PREF, true],
   1221      [CAT_PREF, "custom"],
   1222    ],
   1223  });
   1224 
   1225  // Clear glean before testing.
   1226  Services.fog.testResetFOG();
   1227 
   1228  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1229  let doc = gBrowser.contentDocument;
   1230 
   1231  let fppCheckbox = doc.querySelector(
   1232    "#contentBlockingFingerprintingProtectionCheckbox"
   1233  );
   1234 
   1235  // Verify the default state of the FPP checkbox.
   1236  ok(fppCheckbox, "FPP checkbox exists");
   1237  ok(fppCheckbox.hasAttribute("checked"), "FPP checkbox is checked");
   1238 
   1239  let menu = doc.querySelector("#fingerprintingProtectionMenu");
   1240  let alwaysMenuItem = doc.querySelector(
   1241    "#fingerprintingProtectionMenu > menupopup > menuitem[value=always]"
   1242  );
   1243  let privateMenuItem = doc.querySelector(
   1244    "#fingerprintingProtectionMenu > menupopup > menuitem[value=private]"
   1245  );
   1246 
   1247  // Click the always option on the FPP drop down.
   1248  menu.selectedItem = alwaysMenuItem;
   1249  alwaysMenuItem.click();
   1250 
   1251  // Verify the pref states and the telemetry.
   1252  is(
   1253    Services.prefs.getBoolPref(FPP_PREF),
   1254    true,
   1255    `${FPP_PREF} has been set to true`
   1256  );
   1257 
   1258  is(
   1259    Services.prefs.getBoolPref(FPP_PBM_PREF),
   1260    true,
   1261    `${FPP_PBM_PREF} has been set to true`
   1262  );
   1263 
   1264  let events = Glean.privacyUiFppClick.menu.testGetValue();
   1265  is(events.length, 1, "The event length is correct");
   1266  is(events[0].extra.value, "always", "The extra field is correct.");
   1267 
   1268  // Click the private-only option on the FPP drop down.
   1269  menu.selectedItem = privateMenuItem;
   1270  privateMenuItem.click();
   1271 
   1272  // Verify the pref states and the telemetry.
   1273  is(
   1274    Services.prefs.getBoolPref(FPP_PREF),
   1275    false,
   1276    `${FPP_PREF} has been set to true`
   1277  );
   1278 
   1279  is(
   1280    Services.prefs.getBoolPref(FPP_PBM_PREF),
   1281    true,
   1282    `${FPP_PBM_PREF} has been set to true`
   1283  );
   1284 
   1285  events = Glean.privacyUiFppClick.menu.testGetValue();
   1286  is(events.length, 2, "The event length is correct");
   1287  is(events[1].extra.value, "private", "The extra field is correct.");
   1288 
   1289  // Uncheck the checkbox
   1290  fppCheckbox.click();
   1291 
   1292  // Verify the pref states and the telemetry.
   1293  is(
   1294    Services.prefs.getBoolPref(FPP_PREF),
   1295    false,
   1296    `${FPP_PREF} has been set to true`
   1297  );
   1298 
   1299  is(
   1300    Services.prefs.getBoolPref(FPP_PBM_PREF),
   1301    false,
   1302    `${FPP_PBM_PREF} has been set to true`
   1303  );
   1304  is(menu.disabled, true, "The menu is disabled as the checkbox is unchecked");
   1305 
   1306  events = Glean.privacyUiFppClick.checkbox.testGetValue();
   1307  is(events.length, 1, "The event length is correct");
   1308  is(events[0].extra.checked, "false", "The extra field is correct.");
   1309 
   1310  // Check the checkbox again.
   1311  fppCheckbox.click();
   1312 
   1313  // Verify the pref states and telemetry.
   1314  is(
   1315    Services.prefs.getBoolPref(FPP_PREF),
   1316    false,
   1317    `${FPP_PREF} has been set to true`
   1318  );
   1319 
   1320  is(
   1321    Services.prefs.getBoolPref(FPP_PBM_PREF),
   1322    true,
   1323    `${FPP_PBM_PREF} has been set to true`
   1324  );
   1325  is(menu.disabled, false, "The menu is enabled as the checkbox is checked");
   1326 
   1327  events = Glean.privacyUiFppClick.checkbox.testGetValue();
   1328  is(events.length, 2, "The event length is correct");
   1329  is(events[1].extra.checked, "true", "The extra field is correct.");
   1330 
   1331  gBrowser.removeCurrentTab();
   1332 });
   1333 
   1334 // Checks that social media trackers, cryptomining and fingerprinting visibility
   1335 // can be controlled via pref.
   1336 add_task(async function testCustomOptionsVisibility() {
   1337  Services.prefs.setBoolPref(
   1338    "browser.contentblocking.cryptomining.preferences.ui.enabled",
   1339    false
   1340  );
   1341  Services.prefs.setBoolPref(
   1342    "browser.contentblocking.fingerprinting.preferences.ui.enabled",
   1343    false
   1344  );
   1345  Services.prefs.setBoolPref(
   1346    "privacy.socialtracking.block_cookies.enabled",
   1347    false
   1348  );
   1349 
   1350  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1351 
   1352  let doc = gBrowser.contentDocument;
   1353  let cryptominersOption = doc.getElementById(
   1354    "contentBlockingCryptominersOption"
   1355  );
   1356  let fingerprintersOption = doc.getElementById(
   1357    "contentBlockingFingerprintersOption"
   1358  );
   1359 
   1360  ok(cryptominersOption.hidden, "Cryptomining is hidden");
   1361  ok(fingerprintersOption.hidden, "Fingerprinting is hidden");
   1362 
   1363  gBrowser.removeCurrentTab();
   1364 
   1365  Services.prefs.setBoolPref(
   1366    "browser.contentblocking.cryptomining.preferences.ui.enabled",
   1367    true
   1368  );
   1369 
   1370  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1371 
   1372  doc = gBrowser.contentDocument;
   1373  cryptominersOption = doc.getElementById("contentBlockingCryptominersOption");
   1374  fingerprintersOption = doc.getElementById(
   1375    "contentBlockingFingerprintersOption"
   1376  );
   1377 
   1378  ok(!cryptominersOption.hidden, "Cryptomining is shown");
   1379  ok(fingerprintersOption.hidden, "Fingerprinting is hidden");
   1380 
   1381  gBrowser.removeCurrentTab();
   1382 
   1383  Services.prefs.setBoolPref(
   1384    "browser.contentblocking.fingerprinting.preferences.ui.enabled",
   1385    true
   1386  );
   1387 
   1388  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1389 
   1390  doc = gBrowser.contentDocument;
   1391  cryptominersOption = doc.getElementById("contentBlockingCryptominersOption");
   1392  fingerprintersOption = doc.getElementById(
   1393    "contentBlockingFingerprintersOption"
   1394  );
   1395 
   1396  ok(!cryptominersOption.hidden, "Cryptomining is shown");
   1397  ok(!fingerprintersOption.hidden, "Fingerprinting is shown");
   1398 
   1399  gBrowser.removeCurrentTab();
   1400 
   1401  // Social media trackers UI should be hidden
   1402  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1403 
   1404  doc = gBrowser.contentDocument;
   1405  let socialTrackingUI = [...doc.querySelectorAll(".social-media-option")];
   1406 
   1407  ok(
   1408    socialTrackingUI.every(el => el.hidden),
   1409    "All Social media tracker UI instances are hidden"
   1410  );
   1411 
   1412  gBrowser.removeCurrentTab();
   1413 
   1414  // Social media trackers UI should be visible
   1415  Services.prefs.setBoolPref(
   1416    "privacy.socialtracking.block_cookies.enabled",
   1417    true
   1418  );
   1419 
   1420  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1421 
   1422  doc = gBrowser.contentDocument;
   1423  socialTrackingUI = [...doc.querySelectorAll(".social-media-option")];
   1424 
   1425  ok(
   1426    !socialTrackingUI.every(el => el.hidden),
   1427    "All Social media tracker UI instances are visible"
   1428  );
   1429 
   1430  gBrowser.removeCurrentTab();
   1431 
   1432  Services.prefs.clearUserPref(
   1433    "browser.contentblocking.cryptomining.preferences.ui.enabled"
   1434  );
   1435  Services.prefs.clearUserPref(
   1436    "browser.contentblocking.fingerprinting.preferences.ui.enabled"
   1437  );
   1438  Services.prefs.clearUserPref("privacy.socialtracking.block_cookies.enabled");
   1439 });
   1440 
   1441 // Checks that adding a custom enterprise policy will put the user in the custom category.
   1442 // Other categories will be disabled.
   1443 add_task(async function testPolicyCategorization() {
   1444  Services.prefs.setStringPref(CAT_PREF, "standard");
   1445  is(
   1446    Services.prefs.getStringPref(CAT_PREF),
   1447    "standard",
   1448    `${CAT_PREF} starts on standard`
   1449  );
   1450  ok(
   1451    !Services.prefs.prefHasUserValue(TP_PREF),
   1452    `${TP_PREF} starts with the default value`
   1453  );
   1454  PoliciesPrefTracker.start();
   1455 
   1456  await EnterprisePolicyTesting.setupPolicyEngineWithJson({
   1457    policies: {
   1458      EnableTrackingProtection: {
   1459        Value: true,
   1460      },
   1461    },
   1462  });
   1463  EnterprisePolicyTesting.checkPolicyPref(TP_PREF, true, false);
   1464  is(
   1465    Services.prefs.getStringPref(CAT_PREF),
   1466    "custom",
   1467    `${CAT_PREF} has been set to custom`
   1468  );
   1469 
   1470  Services.prefs.setStringPref(CAT_PREF, "standard");
   1471  is(
   1472    Services.prefs.getStringPref(CAT_PREF),
   1473    "standard",
   1474    `${CAT_PREF} starts on standard`
   1475  );
   1476  ok(
   1477    !Services.prefs.prefHasUserValue(NCB_PREF),
   1478    `${NCB_PREF} starts with the default value`
   1479  );
   1480  ok(
   1481    !Services.prefs.prefHasUserValue(NCBP_PREF),
   1482    `${NCBP_PREF} starts with the default value`
   1483  );
   1484 
   1485  let uiUpdatedPromise = TestUtils.topicObserved("privacy-pane-tp-ui-updated");
   1486  await EnterprisePolicyTesting.setupPolicyEngineWithJson({
   1487    policies: {
   1488      Cookies: {
   1489        AcceptThirdParty: "never",
   1490        Locked: true,
   1491      },
   1492    },
   1493  });
   1494  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1495  await uiUpdatedPromise;
   1496 
   1497  EnterprisePolicyTesting.checkPolicyPref(
   1498    NCB_PREF,
   1499    Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
   1500    true
   1501  );
   1502  EnterprisePolicyTesting.checkPolicyPref(
   1503    NCBP_PREF,
   1504    Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN,
   1505    true
   1506  );
   1507  is(
   1508    Services.prefs.getStringPref(CAT_PREF),
   1509    "custom",
   1510    `${CAT_PREF} has been set to custom`
   1511  );
   1512 
   1513  let doc = gBrowser.contentDocument;
   1514  let strictRadioOption = doc.getElementById("strictRadio");
   1515  let standardRadioOption = doc.getElementById("standardRadio");
   1516  is(strictRadioOption.disabled, true, "the strict option is disabled");
   1517  is(standardRadioOption.disabled, true, "the standard option is disabled");
   1518 
   1519  gBrowser.removeCurrentTab();
   1520 
   1521  // Cleanup after this particular test.
   1522  if (Services.policies.status != Ci.nsIEnterprisePolicies.INACTIVE) {
   1523    await EnterprisePolicyTesting.setupPolicyEngineWithJson({
   1524      policies: {
   1525        Cookies: {
   1526          Locked: false,
   1527        },
   1528      },
   1529    });
   1530    await EnterprisePolicyTesting.setupPolicyEngineWithJson("");
   1531  }
   1532  is(
   1533    Services.policies.status,
   1534    Ci.nsIEnterprisePolicies.INACTIVE,
   1535    "Engine is inactive at the end of the test"
   1536  );
   1537 
   1538  EnterprisePolicyTesting.resetRunOnceState();
   1539  PoliciesPrefTracker.stop();
   1540 });
   1541 
   1542 // Tests that changing a content blocking pref shows the content blocking warning
   1543 // to reload tabs to apply changes.
   1544 add_task(async function testContentBlockingReloadWarning() {
   1545  Services.prefs.setStringPref(CAT_PREF, "standard");
   1546  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1547  let doc = gBrowser.contentDocument;
   1548  let reloadWarnings = [
   1549    ...doc.querySelectorAll(".content-blocking-warning.reload-tabs"),
   1550  ];
   1551  let allHidden = reloadWarnings.every(el => el.hidden);
   1552  ok(allHidden, "all of the warnings to reload tabs are initially hidden");
   1553 
   1554  Services.prefs.setStringPref(CAT_PREF, "strict");
   1555 
   1556  let strictWarning = doc.querySelector(
   1557    "#contentBlockingOptionStrict .content-blocking-warning.reload-tabs"
   1558  );
   1559  ok(
   1560    !BrowserTestUtils.isHidden(strictWarning),
   1561    "The warning in the strict section should be showing"
   1562  );
   1563 
   1564  Services.prefs.setStringPref(CAT_PREF, "standard");
   1565  gBrowser.removeCurrentTab();
   1566 });
   1567 
   1568 // Tests that changing a content blocking pref does not show the content blocking warning
   1569 // if it is the only tab.
   1570 add_task(async function testContentBlockingReloadWarningSingleTab() {
   1571  Services.prefs.setStringPref(CAT_PREF, "standard");
   1572  BrowserTestUtils.startLoadingURIString(
   1573    gBrowser.selectedBrowser,
   1574    PRIVACY_PAGE
   1575  );
   1576  await BrowserTestUtils.browserLoaded(
   1577    gBrowser.selectedBrowser,
   1578    false,
   1579    PRIVACY_PAGE
   1580  );
   1581 
   1582  let reloadWarnings = [
   1583    ...gBrowser.contentDocument.querySelectorAll(
   1584      ".content-blocking-warning.reload-tabs"
   1585    ),
   1586  ];
   1587  ok(reloadWarnings.length, "must have at least one reload warning");
   1588  ok(
   1589    reloadWarnings.every(el => el.hidden),
   1590    "all of the warnings to reload tabs are initially hidden"
   1591  );
   1592 
   1593  is(BrowserWindowTracker.windowCount, 1, "There is only one window open");
   1594  is(gBrowser.tabs.length, 1, "There is only one tab open");
   1595  Services.prefs.setStringPref(CAT_PREF, "strict");
   1596 
   1597  ok(
   1598    reloadWarnings.every(el => el.hidden),
   1599    "all of the warnings to reload tabs are still hidden"
   1600  );
   1601  Services.prefs.setStringPref(CAT_PREF, "standard");
   1602  BrowserTestUtils.startLoadingURIString(
   1603    gBrowser.selectedBrowser,
   1604    "about:newtab"
   1605  );
   1606  await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
   1607 });
   1608 
   1609 // Checks that the reload tabs message reloads all tabs except the active tab.
   1610 add_task(async function testReloadTabsMessage() {
   1611  Services.prefs.setStringPref(CAT_PREF, "strict");
   1612  let exampleTab = await BrowserTestUtils.openNewForegroundTab(
   1613    gBrowser,
   1614    "http://example.com"
   1615  );
   1616  let examplePinnedTab = await BrowserTestUtils.openNewForegroundTab(
   1617    gBrowser,
   1618    "http://example.com"
   1619  );
   1620  gBrowser.pinTab(examplePinnedTab);
   1621  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1622  let doc = gBrowser.contentDocument;
   1623  let standardWarning = doc.querySelector(
   1624    "#contentBlockingOptionStandard .content-blocking-warning.reload-tabs"
   1625  );
   1626  let standardReloadButton = doc.querySelector(
   1627    "#contentBlockingOptionStandard .reload-tabs-button"
   1628  );
   1629 
   1630  Services.prefs.setStringPref(CAT_PREF, "standard");
   1631  ok(
   1632    !BrowserTestUtils.isHidden(standardWarning),
   1633    "The warning in the standard section should be showing"
   1634  );
   1635 
   1636  let exampleTabBrowserDiscardedPromise = BrowserTestUtils.waitForEvent(
   1637    exampleTab,
   1638    "TabBrowserDiscarded"
   1639  );
   1640  let examplePinnedTabLoadPromise = BrowserTestUtils.browserLoaded(
   1641    examplePinnedTab.linkedBrowser
   1642  );
   1643  standardReloadButton.click();
   1644  // The pinned example page had a load event
   1645  await examplePinnedTabLoadPromise;
   1646  // The other one had its browser discarded
   1647  await exampleTabBrowserDiscardedPromise;
   1648 
   1649  ok(
   1650    BrowserTestUtils.isHidden(standardWarning),
   1651    "The warning in the standard section should have hidden after being clicked"
   1652  );
   1653 
   1654  // cleanup
   1655  Services.prefs.setStringPref(CAT_PREF, "standard");
   1656  gBrowser.removeTab(exampleTab);
   1657  gBrowser.removeTab(examplePinnedTab);
   1658  gBrowser.removeCurrentTab();
   1659 });
   1660 
   1661 // Checks that the RFP warning banner is properly shown when rfp prefs are enabled.
   1662 add_task(async function testRFPWarningBanner() {
   1663  // Set the prefs to false before testing.
   1664  await SpecialPowers.pushPrefEnv({
   1665    set: [
   1666      ["privacy.resistFingerprinting", false],
   1667      ["privacy.resistFingerprinting.pbmode", false],
   1668    ],
   1669  });
   1670 
   1671  await openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
   1672  let doc = gBrowser.contentDocument;
   1673  let rfpWarningBanner = doc.getElementById("rfpIncompatibilityWarning");
   1674 
   1675  // Verify if the banner is hidden at the beginning.
   1676  ok(
   1677    !BrowserTestUtils.isVisible(rfpWarningBanner),
   1678    "The RFP warning banner is hidden at the beginning."
   1679  );
   1680 
   1681  // Enable the RFP pref
   1682  await SpecialPowers.pushPrefEnv({
   1683    set: [["privacy.resistFingerprinting", true]],
   1684  });
   1685 
   1686  // Verify if the banner is shown.
   1687  ok(
   1688    BrowserTestUtils.isVisible(rfpWarningBanner),
   1689    "The RFP warning banner is shown."
   1690  );
   1691 
   1692  // Enable the RFP pref for private windows
   1693  await SpecialPowers.pushPrefEnv({
   1694    set: [
   1695      ["privacy.resistFingerprinting", false],
   1696      ["privacy.resistFingerprinting.pbmode", true],
   1697    ],
   1698  });
   1699 
   1700  // Verify if the banner is shown.
   1701  ok(
   1702    BrowserTestUtils.isVisible(rfpWarningBanner),
   1703    "The RFP warning banner is shown."
   1704  );
   1705 
   1706  // Enable both RFP prefs.
   1707  await SpecialPowers.pushPrefEnv({
   1708    set: [
   1709      ["privacy.resistFingerprinting", true],
   1710      ["privacy.resistFingerprinting.pbmode", true],
   1711    ],
   1712  });
   1713 
   1714  // Verify if the banner is shown.
   1715  ok(
   1716    BrowserTestUtils.isVisible(rfpWarningBanner),
   1717    "The RFP warning banner is shown."
   1718  );
   1719 
   1720  gBrowser.removeCurrentTab();
   1721 });