tor-browser

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

browser_protectionsUI_cookies_subview.js (17575B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /* eslint-disable mozilla/no-arbitrary-setTimeout */
      5 
      6 "use strict";
      7 
      8 const COOKIE_PAGE =
      9  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     10  "http://not-tracking.example.com/browser/browser/base/content/test/protectionsUI/cookiePage.html";
     11 const CONTAINER_PAGE =
     12  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     13  "http://not-tracking.example.com/browser/browser/base/content/test/protectionsUI/containerPage.html";
     14 
     15 const TPC_PREF = "network.cookie.cookieBehavior";
     16 
     17 add_setup(async function () {
     18  await UrlClassifierTestUtils.addTestTrackers();
     19 
     20  registerCleanupFunction(() => {
     21    UrlClassifierTestUtils.cleanupTestTrackers();
     22  });
     23 });
     24 
     25 /*
     26 * Accepts an array containing 6 elements that identify the testcase:
     27 * [0] - boolean indicating whether trackers are blocked.
     28 * [1] - boolean indicating whether third party cookies are blocked.
     29 * [2] - boolean indicating whether first party cookies are blocked.
     30 * [3] - integer indicating number of expected content blocking events.
     31 * [4] - integer indicating number of expected subview list headers.
     32 * [5] - integer indicating number of expected cookie list items.
     33 * [6] - integer indicating number of expected cookie list items
     34 *       after loading a cookie-setting third party URL in an iframe
     35 * [7] - integer indicating number of expected cookie list items
     36 *       after loading a cookie-setting first party URL in an iframe
     37 */
     38 async function assertSitesListed(testCase) {
     39  let sitesListedTestCases = [
     40    [true, false, false, 4, 1, 1, 1, 1],
     41    [true, true, false, 5, 1, 1, 2, 2],
     42    [true, true, true, 6, 2, 2, 3, 3],
     43    [false, false, false, 3, 1, 1, 1, 1],
     44  ];
     45  let [
     46    trackersBlocked,
     47    thirdPartyBlocked,
     48    firstPartyBlocked,
     49    contentBlockingEventCount,
     50    listHeaderCount,
     51    cookieItemsCount1,
     52    cookieItemsCount2,
     53    cookieItemsCount3,
     54  ] = sitesListedTestCases[testCase];
     55  let promise = BrowserTestUtils.openNewForegroundTab({
     56    url: COOKIE_PAGE,
     57    gBrowser,
     58  });
     59  let [tab] = await Promise.all([
     60    promise,
     61    waitForContentBlockingEvent(contentBlockingEventCount),
     62  ]);
     63  let browser = tab.linkedBrowser;
     64 
     65  await openProtectionsPanel();
     66 
     67  let categoryItem = document.getElementById(
     68    "protections-popup-category-cookies"
     69  );
     70 
     71  // Explicitly waiting for the category item becoming visible.
     72  await TestUtils.waitForCondition(() => {
     73    return BrowserTestUtils.isVisible(categoryItem);
     74  });
     75 
     76  ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible");
     77  let cookiesView = document.getElementById("protections-popup-cookiesView");
     78  let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
     79  categoryItem.click();
     80  await viewShown;
     81 
     82  ok(true, "Cookies view was shown");
     83 
     84  let listHeaders = cookiesView.querySelectorAll(
     85    ".protections-popup-cookiesView-list-header"
     86  );
     87  is(
     88    listHeaders.length,
     89    listHeaderCount,
     90    `We have ${listHeaderCount} list headers.`
     91  );
     92  if (listHeaderCount == 1) {
     93    ok(
     94      !BrowserTestUtils.isVisible(listHeaders[0]),
     95      "Only one header, should be hidden"
     96    );
     97  } else {
     98    for (let header of listHeaders) {
     99      ok(
    100        BrowserTestUtils.isVisible(header),
    101        "Multiple list headers - all should be visible."
    102      );
    103    }
    104  }
    105 
    106  let emptyLabels = cookiesView.querySelectorAll(
    107    ".protections-popup-empty-label"
    108  );
    109  is(emptyLabels.length, 0, `We have no empty labels`);
    110 
    111  let listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    112  is(
    113    listItems.length,
    114    cookieItemsCount1,
    115    `We have ${cookieItemsCount1} cookies in the list`
    116  );
    117 
    118  if (trackersBlocked) {
    119    let trackerTestItem;
    120    for (let item of listItems) {
    121      let label = item.querySelector(".protections-popup-list-host-label");
    122      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    123      if (label.value == "http://trackertest.org") {
    124        trackerTestItem = item;
    125        break;
    126      }
    127    }
    128    ok(trackerTestItem, "Has an item for trackertest.org");
    129    ok(BrowserTestUtils.isVisible(trackerTestItem), "List item is visible");
    130  }
    131 
    132  if (firstPartyBlocked) {
    133    let notTrackingExampleItem;
    134    for (let item of listItems) {
    135      let label = item.querySelector(".protections-popup-list-host-label");
    136      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    137      if (label.value == "http://not-tracking.example.com") {
    138        notTrackingExampleItem = item;
    139        break;
    140      }
    141    }
    142    ok(notTrackingExampleItem, "Has an item for not-tracking.example.com");
    143    ok(
    144      BrowserTestUtils.isVisible(notTrackingExampleItem),
    145      "List item is visible"
    146    );
    147  }
    148  let mainView = document.getElementById("protections-popup-mainView");
    149  viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
    150  let backButton = cookiesView.querySelector(".subviewbutton-back");
    151  backButton.click();
    152  await viewShown;
    153 
    154  ok(true, "Main view was shown");
    155 
    156  let change = waitForContentBlockingEvent();
    157  let timeoutPromise = new Promise(resolve => setTimeout(resolve, 1000));
    158 
    159  await SpecialPowers.spawn(browser, [], function () {
    160    content.postMessage("third-party-cookie", "*");
    161  });
    162 
    163  let result = await Promise.race([change, timeoutPromise]);
    164  is(result, undefined, "No contentBlockingEvent events should be received");
    165 
    166  viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
    167  categoryItem.click();
    168  await viewShown;
    169 
    170  ok(true, "Cookies view was shown");
    171 
    172  emptyLabels = cookiesView.querySelectorAll(".protections-popup-empty-label");
    173  is(emptyLabels.length, 0, `We have no empty labels`);
    174 
    175  listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    176  is(
    177    listItems.length,
    178    cookieItemsCount2,
    179    `We have ${cookieItemsCount2} cookies in the list`
    180  );
    181 
    182  if (thirdPartyBlocked) {
    183    let test1ExampleItem;
    184    for (let item of listItems) {
    185      let label = item.querySelector(".protections-popup-list-host-label");
    186      if (label.value == "https://test1.example.org") {
    187        test1ExampleItem = item;
    188        break;
    189      }
    190    }
    191    ok(test1ExampleItem, "Has an item for test1.example.org");
    192    ok(BrowserTestUtils.isVisible(test1ExampleItem), "List item is visible");
    193  }
    194 
    195  if (trackersBlocked || thirdPartyBlocked || firstPartyBlocked) {
    196    let trackerTestItem;
    197    for (let item of listItems) {
    198      let label = item.querySelector(".protections-popup-list-host-label");
    199      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    200      if (label.value == "http://trackertest.org") {
    201        trackerTestItem = item;
    202        break;
    203      }
    204    }
    205    ok(trackerTestItem, "List item should exist for http://trackertest.org");
    206    ok(BrowserTestUtils.isVisible(trackerTestItem), "List item is visible");
    207  }
    208 
    209  viewShown = BrowserTestUtils.waitForEvent(mainView, "ViewShown");
    210  backButton.click();
    211  await viewShown;
    212 
    213  ok(true, "Main view was shown");
    214 
    215  change = waitForSecurityChange();
    216  timeoutPromise = new Promise(resolve => setTimeout(resolve, 1000));
    217 
    218  await SpecialPowers.spawn(browser, [], function () {
    219    content.postMessage("first-party-cookie", "*");
    220  });
    221 
    222  result = await Promise.race([change, timeoutPromise]);
    223  is(result, undefined, "No securityChange events should be received");
    224 
    225  viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
    226  categoryItem.click();
    227  await viewShown;
    228 
    229  ok(true, "Cookies view was shown");
    230 
    231  emptyLabels = cookiesView.querySelectorAll(".protections-popup-empty-label");
    232  is(emptyLabels.length, 0, "We have no empty labels");
    233 
    234  listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    235  is(
    236    listItems.length,
    237    cookieItemsCount3,
    238    `We have ${cookieItemsCount3} cookies in the list`
    239  );
    240 
    241  if (firstPartyBlocked) {
    242    let notTrackingExampleItem;
    243    for (let item of listItems) {
    244      let label = item.querySelector(".protections-popup-list-host-label");
    245      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    246      if (label.value == "http://not-tracking.example.com") {
    247        notTrackingExampleItem = item;
    248        break;
    249      }
    250    }
    251    ok(notTrackingExampleItem, "Has an item for not-tracking.example.com");
    252    ok(
    253      BrowserTestUtils.isVisible(notTrackingExampleItem),
    254      "List item is visible"
    255    );
    256  }
    257 
    258  BrowserTestUtils.removeTab(tab);
    259 }
    260 
    261 add_task(async function testCookiesSubView() {
    262  info("Testing cookies subview with reject tracking cookies.");
    263  Services.prefs.setIntPref(
    264    TPC_PREF,
    265    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    266  );
    267  let testCaseIndex = 0;
    268  await assertSitesListed(testCaseIndex++);
    269  info("Testing cookies subview with reject third party cookies.");
    270  Services.prefs.setIntPref(
    271    TPC_PREF,
    272    Ci.nsICookieService.BEHAVIOR_REJECT_FOREIGN
    273  );
    274  await assertSitesListed(testCaseIndex++);
    275  info("Testing cookies subview with reject all cookies.");
    276  Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_REJECT);
    277  await assertSitesListed(testCaseIndex++);
    278  info("Testing cookies subview with accept all cookies.");
    279  Services.prefs.setIntPref(TPC_PREF, Ci.nsICookieService.BEHAVIOR_ACCEPT);
    280  await assertSitesListed(testCaseIndex++);
    281 
    282  Services.prefs.clearUserPref(TPC_PREF);
    283 });
    284 
    285 add_task(async function testCookiesSubViewAllowed() {
    286  Services.prefs.setIntPref(
    287    TPC_PREF,
    288    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    289  );
    290  let principal =
    291    Services.scriptSecurityManager.createContentPrincipalFromOrigin(
    292      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    293      "http://trackertest.org/"
    294    );
    295  Services.perms.addFromPrincipal(
    296    principal,
    297    "cookie",
    298    Services.perms.ALLOW_ACTION
    299  );
    300 
    301  let promise = BrowserTestUtils.openNewForegroundTab({
    302    url: COOKIE_PAGE,
    303    gBrowser,
    304  });
    305  let [tab] = await Promise.all([promise, waitForContentBlockingEvent(3)]);
    306 
    307  await openProtectionsPanel();
    308 
    309  let categoryItem = document.getElementById(
    310    "protections-popup-category-cookies"
    311  );
    312 
    313  // Explicitly waiting for the category item becoming visible.
    314  await TestUtils.waitForCondition(() => {
    315    return BrowserTestUtils.isVisible(categoryItem);
    316  });
    317 
    318  ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible");
    319  let cookiesView = document.getElementById("protections-popup-cookiesView");
    320  let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
    321  categoryItem.click();
    322  await viewShown;
    323 
    324  ok(true, "Cookies view was shown");
    325 
    326  let listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    327  is(listItems.length, 1, "We have 1 cookie in the list");
    328 
    329  let listItem = listItems[0];
    330  let label = listItem.querySelector(".protections-popup-list-host-label");
    331  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    332  is(label.value, "http://trackertest.org", "has an item for trackertest.org");
    333  ok(BrowserTestUtils.isVisible(listItem), "list item is visible");
    334  ok(
    335    listItem.classList.contains("allowed"),
    336    "indicates whether the cookie was blocked or allowed"
    337  );
    338 
    339  let stateLabel = listItem.querySelector(
    340    ".protections-popup-list-state-label"
    341  );
    342  ok(stateLabel, "List item has a state label");
    343  ok(BrowserTestUtils.isVisible(stateLabel), "State label is visible");
    344  is(
    345    stateLabel.getAttribute("data-l10n-id"),
    346    "content-blocking-cookies-view-allowed-label",
    347    "State label has correct text"
    348  );
    349 
    350  let button = listItem.querySelector(
    351    ".permission-popup-permission-remove-button"
    352  );
    353  ok(BrowserTestUtils.isVisible(button), "Permission remove button is visible");
    354  button.click();
    355  is(
    356    Services.perms.testExactPermissionFromPrincipal(principal, "cookie"),
    357    Services.perms.UNKNOWN_ACTION,
    358    "Button click should remove cookie pref."
    359  );
    360  ok(!listItem.classList.contains("allowed"), "Has removed the allowed class");
    361 
    362  BrowserTestUtils.removeTab(tab);
    363 
    364  Services.prefs.clearUserPref(TPC_PREF);
    365 });
    366 
    367 add_task(async function testCookiesSubViewAllowedHeuristic() {
    368  Services.prefs.setIntPref(
    369    TPC_PREF,
    370    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    371  );
    372  Services.prefs.setBoolPref(
    373    "privacy.restrict3rdpartystorage.heuristic.exclude_third_party_trackers",
    374    false
    375  );
    376  let principal =
    377    Services.scriptSecurityManager.createContentPrincipalFromOrigin(
    378      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    379      "http://not-tracking.example.com/"
    380    );
    381 
    382  // Pretend that the tracker has already been interacted with
    383  let trackerPrincipal =
    384    Services.scriptSecurityManager.createContentPrincipalFromOrigin(
    385      // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    386      "http://trackertest.org/"
    387    );
    388  Services.perms.addFromPrincipal(
    389    trackerPrincipal,
    390    "storageAccessAPI",
    391    Services.perms.ALLOW_ACTION
    392  );
    393 
    394  let promise = BrowserTestUtils.openNewForegroundTab({
    395    url: COOKIE_PAGE,
    396    gBrowser,
    397  });
    398  let [tab] = await Promise.all([promise, waitForContentBlockingEvent(5)]);
    399  let browser = tab.linkedBrowser;
    400 
    401  let popup;
    402  let windowCreated = TestUtils.topicObserved(
    403    "chrome-document-global-created",
    404    subject => {
    405      popup = subject;
    406      return true;
    407    }
    408  );
    409  let permChanged = TestUtils.topicObserved("perm-changed", (subject, data) => {
    410    return (
    411      subject &&
    412      subject.QueryInterface(Ci.nsIPermission).type ==
    413        "3rdPartyStorage^http://trackertest.org" &&
    414      subject.principal.origin == principal.origin &&
    415      data == "added"
    416    );
    417  });
    418 
    419  await SpecialPowers.spawn(browser, [], function () {
    420    content.postMessage("window-open", "*");
    421  });
    422  await Promise.all([windowCreated, permChanged]);
    423 
    424  await new Promise(resolve => waitForFocus(resolve, popup));
    425  await new Promise(resolve => waitForFocus(resolve, window));
    426 
    427  await openProtectionsPanel();
    428 
    429  let categoryItem = document.getElementById(
    430    "protections-popup-category-cookies"
    431  );
    432 
    433  // Explicitly waiting for the category item becoming visible.
    434  await TestUtils.waitForCondition(() => {
    435    return BrowserTestUtils.isVisible(categoryItem);
    436  });
    437 
    438  ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible");
    439  let cookiesView = document.getElementById("protections-popup-cookiesView");
    440  let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
    441  categoryItem.click();
    442  await viewShown;
    443 
    444  ok(true, "Cookies view was shown");
    445 
    446  let listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    447  is(listItems.length, 1, "We have 1 cookie in the list");
    448 
    449  let listItem = listItems[0];
    450  let label = listItem.querySelector(".protections-popup-list-host-label");
    451  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    452  is(label.value, "http://trackertest.org", "has an item for trackertest.org");
    453  ok(BrowserTestUtils.isVisible(listItem), "list item is visible");
    454  ok(
    455    listItem.classList.contains("allowed"),
    456    "indicates whether the cookie was blocked or allowed"
    457  );
    458 
    459  let button = listItem.querySelector(
    460    ".permission-popup-permission-remove-button"
    461  );
    462  ok(BrowserTestUtils.isVisible(button), "Permission remove button is visible");
    463  button.click();
    464  is(
    465    Services.perms.testExactPermissionFromPrincipal(
    466      principal,
    467      "3rdPartyStorage^http://trackertest.org"
    468    ),
    469    Services.perms.UNKNOWN_ACTION,
    470    "Button click should remove the storage pref."
    471  );
    472  ok(!listItem.classList.contains("allowed"), "Has removed the allowed class");
    473 
    474  await SpecialPowers.spawn(browser, [], function () {
    475    content.postMessage("window-close", "*");
    476  });
    477 
    478  BrowserTestUtils.removeTab(tab);
    479 
    480  Services.prefs.clearUserPref(TPC_PREF);
    481  Services.prefs.clearUserPref(
    482    "privacy.restrict3rdpartystorage.heuristic.exclude_third_party_trackers"
    483  );
    484 });
    485 
    486 add_task(async function testCookiesSubViewBlockedDoublyNested() {
    487  requestLongerTimeout(2);
    488 
    489  Services.prefs.setIntPref(
    490    TPC_PREF,
    491    Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER
    492  );
    493 
    494  let promise = BrowserTestUtils.openNewForegroundTab({
    495    url: CONTAINER_PAGE,
    496    gBrowser,
    497  });
    498  let [tab] = await Promise.all([promise, waitForContentBlockingEvent(3)]);
    499 
    500  await openProtectionsPanel();
    501 
    502  let categoryItem = document.getElementById(
    503    "protections-popup-category-cookies"
    504  );
    505 
    506  // Explicitly waiting for the category item becoming visible.
    507  await TestUtils.waitForCondition(() => {
    508    return BrowserTestUtils.isVisible(categoryItem);
    509  });
    510 
    511  ok(BrowserTestUtils.isVisible(categoryItem), "TP category item is visible");
    512  let cookiesView = document.getElementById("protections-popup-cookiesView");
    513  let viewShown = BrowserTestUtils.waitForEvent(cookiesView, "ViewShown");
    514  categoryItem.click();
    515  await viewShown;
    516 
    517  ok(true, "Cookies view was shown");
    518 
    519  let listItems = cookiesView.querySelectorAll(".protections-popup-list-item");
    520  is(listItems.length, 1, "We have 1 cookie in the list");
    521 
    522  let listItem = listItems[0];
    523  let label = listItem.querySelector(".protections-popup-list-host-label");
    524  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    525  is(label.value, "http://trackertest.org", "has an item for trackertest.org");
    526  ok(BrowserTestUtils.isVisible(listItem), "list item is visible");
    527  ok(
    528    !listItem.classList.contains("allowed"),
    529    "indicates whether the cookie was blocked or allowed"
    530  );
    531 
    532  let button = listItem.querySelector(
    533    ".permission-popup-permission-remove-button"
    534  );
    535  ok(!button, "Permission remove button doesn't exist");
    536 
    537  BrowserTestUtils.removeTab(tab);
    538 
    539  Services.prefs.clearUserPref(TPC_PREF);
    540 });