tor-browser

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

browser_beforeunload_permit_http.js (7857B)


      1 "use strict";
      2 
      3 const { PromptTestUtils } = ChromeUtils.importESModule(
      4  "resource://testing-common/PromptTestUtils.sys.mjs"
      5 );
      6 
      7 const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace(
      8  "chrome://mochitests/content",
      9  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     10  "http://nocert.example.com/"
     11 );
     12 /*
     13 * Description of Tests:
     14 *
     15 * Test load page and reload:
     16 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction
     17 * 2. Open an HTTP site. HTTPS-First will try to upgrade it to https - but since it has no cert that try will fail
     18 * 3. Then simulated user interaction and reload the page with a reload flag.
     19 * 4. That should lead to a beforeUnload prompt that asks for users permission to perform reload. HTTPS-First should not try to upgrade the reload again
     20 *
     21 * Test Navigation:
     22 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction
     23 * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail
     24 * 3. Then simulated user interaction and navigate to another http page. Again HTTPS-First will try to upgrade to HTTPS
     25 * 4. This attempted navigation leads to a prompt which askes for permission to leave page - accept it
     26 * 5. Since the site is not using a valid HTTPS cert HTTPS-First will downgrade the request back to HTTP
     27 * 6. User should NOT get asked again for permission to unload
     28 *
     29 * Test Session History Navigation:
     30 * 1. Enable HTTPS-First and the pref to trigger beforeunload by user interaction
     31 * 2. Open an http site. HTTPS-First will try to upgrade it to https - but since it has no cert for https that try will fail
     32 * 3. Then navigate to another http page and simulated a user interaction.
     33 * 4. Trigger a session history navigation by clicking the "back button".
     34 * 5. This attempted navigation leads to a prompt which askes for permission to leave page - accept it
     35 */
     36 add_setup(async function () {
     37  await SpecialPowers.pushPrefEnv({
     38    set: [
     39      ["test.wait300msAfterTabSwitch", true],
     40      ["dom.security.https_first", true],
     41      ["dom.require_user_interaction_for_beforeunload", true],
     42    ],
     43  });
     44 });
     45 const TESTS = [
     46  {
     47    name: "Normal Reload (No flag)",
     48    reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
     49  },
     50  {
     51    name: "Bypass Cache Reload",
     52    reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE,
     53  },
     54  {
     55    name: "Bypass Proxy Reload",
     56    reloadFlag: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY,
     57  },
     58  {
     59    name: "Bypass Cache and Proxy Reload",
     60    reloadFlag:
     61      Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE |
     62      Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY,
     63  },
     64 ];
     65 
     66 add_task(async function testReloadFlags() {
     67  for (let index = 0; index < TESTS.length; index++) {
     68    const testCase = TESTS[index];
     69    // The onbeforeunload dialog should appear
     70    let dialogPromise = PromptTestUtils.waitForPrompt(null, {
     71      modalType: Services.prompt.MODAL_TYPE_CONTENT,
     72      promptType: "confirmEx",
     73    });
     74    let reloadPromise = loadPageAndReload(testCase);
     75    let dialog = await dialogPromise;
     76    Assert.ok(true, "Showed the beforeunload dialog.");
     77    await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 });
     78    await reloadPromise;
     79  }
     80 });
     81 
     82 add_task(async function testNavigation() {
     83  // The onbeforeunload dialog should appear
     84  let dialogPromise = PromptTestUtils.waitForPrompt(null, {
     85    modalType: Services.prompt.MODAL_TYPE_CONTENT,
     86    promptType: "confirmEx",
     87  });
     88 
     89  let openPagePromise = openPage();
     90  let dialog = await dialogPromise;
     91  Assert.ok(true, "Showed the beforeunload dialog.");
     92  await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 });
     93  await openPagePromise;
     94 });
     95 
     96 add_task(async function testSessionHistoryNavigation() {
     97  // The onbeforeunload dialog should appear
     98  let dialogPromise = PromptTestUtils.waitForPrompt(null, {
     99    modalType: Services.prompt.MODAL_TYPE_CONTENT,
    100    promptType: "confirmEx",
    101  });
    102 
    103  let openPagePromise = loadPagesAndUseBackButton();
    104  let dialog = await dialogPromise;
    105  Assert.ok(true, "Showed the beforeunload dialog.");
    106  await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 0 });
    107  await openPagePromise;
    108 });
    109 
    110 async function openPage() {
    111  // Open about:blank in a new tab
    112  await BrowserTestUtils.withNewTab(
    113    { gBrowser, url: "about:blank" },
    114    async function (browser) {
    115      // Load http page
    116      BrowserTestUtils.startLoadingURIString(
    117        browser,
    118        `${TEST_PATH_HTTP}file_beforeunload_permit_http.html`
    119      );
    120      await BrowserTestUtils.browserLoaded(browser);
    121      // Interact with page such that unload permit will be necessary
    122      await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser);
    123      let hasInteractedWith = await SpecialPowers.spawn(
    124        browser,
    125        [""],
    126        function () {
    127          return content.document.hasBeenUserGestureActivated;
    128        }
    129      );
    130 
    131      is(true, hasInteractedWith, "Simulated successfully user interaction");
    132      // And then navigate away to another site which proves that user won't be asked twice to permit a reload (otherwise the test get timed out)
    133      BrowserTestUtils.startLoadingURIString(
    134        browser,
    135        // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    136        "http://self-signed.example.com/"
    137      );
    138      await BrowserTestUtils.browserLoaded(browser);
    139      Assert.ok(true, "Navigated successfully.");
    140    }
    141  );
    142 }
    143 
    144 async function loadPageAndReload(testCase) {
    145  // Load initial site
    146  // Open about:blank in a new tab
    147  await BrowserTestUtils.withNewTab(
    148    { gBrowser, url: "about:blank" },
    149    async function (browser) {
    150      BrowserTestUtils.startLoadingURIString(
    151        browser,
    152        `${TEST_PATH_HTTP}file_beforeunload_permit_http.html`
    153      );
    154      await BrowserTestUtils.browserLoaded(browser);
    155      // Interact with page such that unload permit will be necessary
    156      await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser);
    157 
    158      let hasInteractedWith = await SpecialPowers.spawn(
    159        browser,
    160        [""],
    161        function () {
    162          return content.document.hasBeenUserGestureActivated;
    163        }
    164      );
    165      is(true, hasInteractedWith, "Simulated successfully user interaction");
    166      BrowserCommands.reloadWithFlags(testCase.reloadFlag);
    167      await BrowserTestUtils.browserLoaded(browser);
    168      is(true, true, `reload with flag ${testCase.name} was successful`);
    169    }
    170  );
    171 }
    172 
    173 async function loadPagesAndUseBackButton() {
    174  // Load initial site
    175  // Open about:blank in a new tab
    176  await BrowserTestUtils.withNewTab(
    177    { gBrowser, url: "about:blank" },
    178    async function (browser) {
    179      BrowserTestUtils.startLoadingURIString(
    180        browser,
    181        `${TEST_PATH_HTTP}file_beforeunload_permit_http.html`
    182      );
    183      await BrowserTestUtils.browserLoaded(browser);
    184 
    185      BrowserTestUtils.startLoadingURIString(
    186        browser,
    187        `${TEST_PATH_HTTP}file_beforeunload_permit_http.html?getASessionHistoryEntry`
    188      );
    189      await BrowserTestUtils.browserLoaded(browser);
    190      // Interact with page such that unload permit will be necessary
    191      await BrowserTestUtils.synthesizeMouse("body", 2, 2, {}, browser);
    192 
    193      let hasInteractedWith = await SpecialPowers.spawn(
    194        browser,
    195        [""],
    196        function () {
    197          return content.document.hasBeenUserGestureActivated;
    198        }
    199      );
    200      is(true, hasInteractedWith, "Simulated successfully user interaction");
    201      // Go back one site by clicking the back button
    202      info("Clicking back button");
    203      let backButton = document.getElementById("back-button");
    204      backButton.click();
    205      await BrowserTestUtils.waitForLocationChange(
    206        gBrowser,
    207        `${TEST_PATH_HTTP}file_beforeunload_permit_http.html`
    208      );
    209      is(true, true, `Got back successful`);
    210    }
    211  );
    212 }