tor-browser

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

browser_aboutNetError_trr.js (5493B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // See bug 1831731. This test should not actually try to create a connection to
      7 // the real DoH endpoint. But that may happen when clearing the proxy type, and
      8 // sometimes even in the next test.
      9 // To prevent that we override the IP to a local address.
     10 Cc["@mozilla.org/network/native-dns-override;1"]
     11  .getService(Ci.nsINativeDNSResolverOverride)
     12  .addIPOverride("mozilla.cloudflare-dns.com", "127.0.0.1");
     13 
     14 let oldProxyType = Services.prefs.getIntPref("network.proxy.type");
     15 function resetPrefs() {
     16  Services.prefs.clearUserPref("network.trr.mode");
     17  Services.prefs.clearUserPref("network.dns.native-is-localhost");
     18  Services.prefs.setIntPref("network.proxy.type", oldProxyType);
     19 }
     20 
     21 async function loadErrorPage() {
     22  Services.prefs.setBoolPref("network.dns.native-is-localhost", true);
     23  Services.prefs.setIntPref("network.trr.mode", Ci.nsIDNSService.MODE_TRRONLY);
     24  // We need to disable proxy, otherwise TRR isn't used for name resolution.
     25  Services.prefs.setIntPref("network.proxy.type", 0);
     26  registerCleanupFunction(resetPrefs);
     27 
     28  let browser;
     29  let pageLoaded;
     30  await BrowserTestUtils.openNewForegroundTab(
     31    gBrowser,
     32    () => {
     33      gBrowser.selectedTab = BrowserTestUtils.addTab(
     34        gBrowser,
     35        "https://does-not-exist.test"
     36      );
     37      browser = gBrowser.selectedBrowser;
     38      pageLoaded = BrowserTestUtils.waitForErrorPage(browser);
     39    },
     40    false
     41  );
     42 
     43  info("Loading and waiting for the net error");
     44  await pageLoaded;
     45  return browser;
     46 }
     47 
     48 // This test makes sure that the Add exception button only shows up
     49 // when the skipReason indicates that the domain could not be resolved.
     50 // If instead there is a problem with the TRR connection, then we don't
     51 // show the exception button.
     52 add_task(async function exceptionButtonTRROnly() {
     53  let browser = await loadErrorPage();
     54 
     55  await SpecialPowers.spawn(browser, [], function () {
     56    const doc = content.document;
     57    ok(
     58      doc.documentURI.startsWith("about:neterror"),
     59      "Should be showing error page"
     60    );
     61 
     62    const titleEl = doc.querySelector(".title-text");
     63    const actualDataL10nID = titleEl.getAttribute("data-l10n-id");
     64    is(
     65      actualDataL10nID,
     66      "dnsNotFound-title",
     67      "Correct error page title is set"
     68    );
     69 
     70    let trrExceptionButton = doc.getElementById("trrExceptionButton");
     71    Assert.equal(
     72      trrExceptionButton.hidden,
     73      true,
     74      "Exception button should be hidden for TRR service failures"
     75    );
     76  });
     77 
     78  BrowserTestUtils.removeTab(gBrowser.selectedTab);
     79  resetPrefs();
     80 });
     81 
     82 add_task(async function TRROnlyExceptionButtonTelemetry() {
     83  // Clear everything.
     84  Services.telemetry.clearEvents();
     85  await TestUtils.waitForCondition(() => {
     86    let events = Services.telemetry.snapshotEvents(
     87      Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
     88      true
     89    ).content;
     90    return !events || !events.length;
     91  });
     92 
     93  let browser = await loadErrorPage();
     94 
     95  await SpecialPowers.spawn(browser, [], function () {
     96    const doc = content.document;
     97    ok(
     98      doc.documentURI.startsWith("about:neterror"),
     99      "Should be showing error page"
    100    );
    101  });
    102 
    103  let loadEvent = await TestUtils.waitForCondition(() => {
    104    let events = Services.telemetry.snapshotEvents(
    105      Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
    106      true
    107    ).content;
    108    return events?.find(e => e[1] == "security.doh.neterror" && e[2] == "load");
    109  }, "recorded telemetry for the load");
    110 
    111  loadEvent.shift();
    112  Assert.deepEqual(loadEvent, [
    113    "security.doh.neterror",
    114    "load",
    115    "dohwarning",
    116    "TRROnlyFailure",
    117    {
    118      mode: "3",
    119      provider_key: "mozilla.cloudflare-dns.com",
    120      skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE",
    121    },
    122  ]);
    123 
    124  await SpecialPowers.spawn(browser, [], function () {
    125    const doc = content.document;
    126    let buttons = ["neterrorTryAgainButton", "trrSettingsButton"];
    127    for (let buttonId of buttons) {
    128      let button = doc.getElementById(buttonId);
    129      button.click();
    130    }
    131  });
    132 
    133  // Since we click TryAgain, make sure the error page is loaded again.
    134  await BrowserTestUtils.waitForErrorPage(browser);
    135 
    136  is(
    137    gBrowser.tabs.length,
    138    3,
    139    "Should open about:preferences#privacy-doh in another tab"
    140  );
    141 
    142  let clickEvents = await TestUtils.waitForCondition(
    143    () => {
    144      let events = Services.telemetry.snapshotEvents(
    145        Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
    146        true
    147      ).content;
    148      return events?.filter(
    149        e => e[1] == "security.doh.neterror" && e[2] == "click"
    150      );
    151    },
    152    "recorded telemetry for clicking buttons",
    153    500,
    154    100
    155  );
    156 
    157  let firstEvent = clickEvents[0];
    158  firstEvent.shift(); // remove timestamp
    159  Assert.deepEqual(firstEvent, [
    160    "security.doh.neterror",
    161    "click",
    162    "try_again_button",
    163    "TRROnlyFailure",
    164    {
    165      mode: "3",
    166      provider_key: "mozilla.cloudflare-dns.com",
    167      skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE",
    168    },
    169  ]);
    170 
    171  let secondEvent = clickEvents[1];
    172  secondEvent.shift(); // remove timestamp
    173  Assert.deepEqual(secondEvent, [
    174    "security.doh.neterror",
    175    "click",
    176    "settings_button",
    177    "TRROnlyFailure",
    178    {
    179      mode: "3",
    180      provider_key: "mozilla.cloudflare-dns.com",
    181      skip_reason: "TRR_UNKNOWN_CHANNEL_FAILURE",
    182    },
    183  ]);
    184 
    185  BrowserTestUtils.removeTab(gBrowser.tabs[2]);
    186  BrowserTestUtils.removeTab(gBrowser.tabs[1]);
    187  resetPrefs();
    188 });