tor-browser

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

browser_schemeless.js (6710B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * https://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // We explicitly need HTTP URLs in this test
      7 /* eslint-disable @microsoft/sdl/no-insecure-url */
      8 
      9 ChromeUtils.defineLazyGetter(this, "UrlbarTestUtils", () => {
     10  const { UrlbarTestUtils: module } = ChromeUtils.importESModule(
     11    "resource://testing-common/UrlbarTestUtils.sys.mjs"
     12  );
     13  module.init(this);
     14  return module;
     15 });
     16 
     17 XPCOMUtils.defineLazyServiceGetter(
     18  this,
     19  "clipboardHelper",
     20  "@mozilla.org/widget/clipboardhelper;1",
     21  Ci.nsIClipboardHelper
     22 );
     23 
     24 /** Type aInput into the address bar and press enter */
     25 async function runMainTest(aInput, aDesc, aExpectedScheme) {
     26  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
     27    const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true);
     28    await UrlbarTestUtils.promiseAutocompleteResultPopup({
     29      window,
     30      value: aInput,
     31    });
     32    EventUtils.synthesizeKey("KEY_Enter");
     33    await loaded;
     34 
     35    is(browser.currentURI.scheme, aExpectedScheme, "Main test: " + aDesc);
     36  });
     37 }
     38 
     39 /**
     40 * Type aInput into the address bar and press ctrl+enter,
     41 * resulting in the input being canonized first.
     42 * This should not change schemeless HTTPS behaviour.
     43 */
     44 async function runCanonizedTest(aInput, aDesc, aExpectedScheme) {
     45  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
     46    const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true);
     47    await UrlbarTestUtils.promiseAutocompleteResultPopup({
     48      window,
     49      value: aInput,
     50    });
     51    EventUtils.synthesizeKey("KEY_Enter", { ctrlKey: true });
     52    await loaded;
     53 
     54    is(browser.currentURI.scheme, aExpectedScheme, "Canonized test: " + aDesc);
     55  });
     56 }
     57 
     58 /**
     59 * Type aInput into the address bar and press alt+enter,
     60 * resulting in the input being loaded in a new tab.
     61 * This should not change schemeless HTTPS behaviour.
     62 */
     63 async function runNewTabTest(aInput, aDesc, aExpectedScheme) {
     64  await BrowserTestUtils.withNewTab(
     65    "about:about", // For alt+enter to do anything, we need to be on a page other than about:blank.
     66    async function () {
     67      const newTabPromise = BrowserTestUtils.waitForNewTab(
     68        gBrowser,
     69        null,
     70        true
     71      );
     72      await UrlbarTestUtils.promiseAutocompleteResultPopup({
     73        window,
     74        value: aInput,
     75      });
     76      EventUtils.synthesizeKey("KEY_Enter", { altKey: true });
     77      const newTab = await newTabPromise;
     78 
     79      is(
     80        newTab.linkedBrowser.currentURI.scheme,
     81        aExpectedScheme,
     82        "New tab test: " + aDesc
     83      );
     84 
     85      BrowserTestUtils.removeTab(newTab);
     86    }
     87  );
     88 }
     89 
     90 /**
     91 * Type aInput into the address bar and press shift+enter,
     92 * resulting in the input being loaded in a new window.
     93 * This should not change schemeless HTTPS behaviour.
     94 */
     95 async function runNewWindowTest(aInput, aDesc, aExpectedScheme) {
     96  await BrowserTestUtils.withNewTab("about:about", async function () {
     97    const newWindowPromise = BrowserTestUtils.waitForNewWindow({
     98      waitForAnyURLLoaded: true,
     99    });
    100    await UrlbarTestUtils.promiseAutocompleteResultPopup({
    101      window,
    102      value: aInput,
    103    });
    104    EventUtils.synthesizeKey("KEY_Enter", { shiftKey: true });
    105    const newWindow = await newWindowPromise;
    106 
    107    is(
    108      newWindow.gBrowser.selectedBrowser.currentURI.scheme,
    109      aExpectedScheme,
    110      "New window test: " + aDesc
    111    );
    112 
    113    await BrowserTestUtils.closeWindow(newWindow);
    114  });
    115 }
    116 
    117 /**
    118 * Instead of typing aInput into the address bar, copy it
    119 * to the clipboard and use the "Paste and Go" menu entry.
    120 * This should not change schemeless HTTPS behaviour.
    121 */
    122 async function runPasteAndGoTest(aInput, aDesc, aExpectedScheme) {
    123  await BrowserTestUtils.withNewTab("about:blank", async function (browser) {
    124    gURLBar.focus();
    125    await SimpleTest.promiseClipboardChange(aInput, () => {
    126      clipboardHelper.copyString(aInput);
    127    });
    128 
    129    const loaded = BrowserTestUtils.browserLoaded(browser, false, null, true);
    130    const textBox = gURLBar.querySelector("moz-input-box");
    131    const cxmenu = textBox.menupopup;
    132    const cxmenuPromise = BrowserTestUtils.waitForEvent(cxmenu, "popupshown");
    133    EventUtils.synthesizeMouseAtCenter(gURLBar.inputField, {
    134      type: "contextmenu",
    135      button: 2,
    136    });
    137    await cxmenuPromise;
    138    const menuitem = textBox.getMenuItem("paste-and-go");
    139    menuitem.closest("menupopup").activateItem(menuitem);
    140    await loaded;
    141 
    142    is(
    143      browser.currentURI.scheme,
    144      aExpectedScheme,
    145      "Paste and go test: " + aDesc
    146    );
    147  });
    148 }
    149 
    150 async function runTest(aInput, aDesc, aExpectedScheme) {
    151  await runMainTest(aInput, aDesc, aExpectedScheme);
    152  await runCanonizedTest(aInput, aDesc, aExpectedScheme);
    153  await runNewTabTest(aInput, aDesc, aExpectedScheme);
    154  await runNewWindowTest(aInput, aDesc, aExpectedScheme);
    155  await runPasteAndGoTest(aInput, aDesc, aExpectedScheme);
    156 }
    157 
    158 add_task(async function () {
    159  requestLongerTimeout(10);
    160  Services.fog.testResetFOG();
    161 
    162  await SpecialPowers.pushPrefEnv({
    163    set: [
    164      ["dom.security.https_first", false],
    165      ["dom.security.https_first_schemeless", false],
    166    ],
    167  });
    168 
    169  await runTest(
    170    "http://example.com",
    171    "Should not upgrade upgradeable website with explicit scheme",
    172    "http"
    173  );
    174 
    175  await runTest(
    176    "example.com",
    177    "Should not upgrade upgradeable website without explicit scheme",
    178    "http"
    179  );
    180 
    181  await SpecialPowers.pushPrefEnv({
    182    set: [["dom.security.https_first_schemeless", true]],
    183  });
    184 
    185  await runTest(
    186    "http://example.com",
    187    "Should not upgrade upgradeable website with explicit scheme",
    188    "http"
    189  );
    190 
    191  for (const key of [
    192    "upgraded",
    193    "upgradedSchemeless",
    194    "downgraded",
    195    "downgradedSchemeless",
    196    "downgradedOnTimer",
    197    "downgradedOnTimerSchemeless",
    198    "downgradeTime",
    199    "downgradeTimeSchemeless",
    200  ]) {
    201    is(
    202      Glean.httpsfirst[key].testGetValue(),
    203      null,
    204      `No telemetry should have been recorded yet for ${key}`
    205    );
    206  }
    207 
    208  await runTest(
    209    "example.com",
    210    "Should upgrade upgradeable website without explicit scheme",
    211    "https"
    212  );
    213 
    214  info("Checking expected telemetry");
    215  is(Glean.httpsfirst.upgraded.testGetValue(), null);
    216  is(Glean.httpsfirst.upgradedSchemeless.testGetValue(), 5);
    217  is(Glean.httpsfirst.downgraded.testGetValue(), null);
    218  is(Glean.httpsfirst.downgradedSchemeless.testGetValue(), null);
    219  is(Glean.httpsfirst.downgradedOnTimer.testGetValue(), null);
    220  is(Glean.httpsfirst.downgradedOnTimerSchemeless.testGetValue(), null);
    221  is(Glean.httpsfirst.downgradeTime.testGetValue(), null);
    222  is(Glean.httpsfirst.downgradeTimeSchemeless.testGetValue(), null);
    223 });