tor-browser

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

browser_bug1415918_beforeunload_options.js (4843B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 const TEST_PATH = getRootDirectory(gTestPath).replace(
      5  "chrome://mochitests/content",
      6  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
      7  "http://example.com"
      8 );
      9 
     10 const { PromptTestUtils } = ChromeUtils.importESModule(
     11  "resource://testing-common/PromptTestUtils.sys.mjs"
     12 );
     13 
     14 SimpleTest.requestFlakyTimeout("Needs to test a timeout");
     15 
     16 function delay(msec) {
     17  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
     18  return new Promise(resolve => setTimeout(resolve, msec));
     19 }
     20 
     21 function allowNextNavigation(browser) {
     22  return PromptTestUtils.handleNextPrompt(
     23    browser,
     24    { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
     25    { buttonNumClick: 0 }
     26  );
     27 }
     28 
     29 function cancelNextNavigation(browser) {
     30  return PromptTestUtils.handleNextPrompt(
     31    browser,
     32    { modalType: Services.prompt.MODAL_TYPE_CONTENT, promptType: "confirmEx" },
     33    { buttonNumClick: 1 }
     34  );
     35 }
     36 
     37 add_task(async function test() {
     38  await SpecialPowers.pushPrefEnv({
     39    set: [["dom.require_user_interaction_for_beforeunload", false]],
     40  });
     41 
     42  const permitUnloadTimeout = Services.prefs.getIntPref(
     43    "dom.beforeunload_timeout_ms"
     44  );
     45 
     46  let url = TEST_PATH + "dummy_page.html";
     47  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
     48  let browser = tab.linkedBrowser;
     49 
     50  await SpecialPowers.spawn(browser.browsingContext, [], () => {
     51    content.addEventListener("beforeunload", event => {
     52      event.preventDefault();
     53    });
     54  });
     55 
     56  /*
     57   * Check condition where beforeunload handlers request a prompt.
     58   */
     59 
     60  // Prompt is shown, user clicks OK.
     61 
     62  let promptShownPromise = allowNextNavigation(browser);
     63  ok(browser.permitUnload().permitUnload, "permit unload should be true");
     64  await promptShownPromise;
     65 
     66  // Prompt is shown, user clicks CANCEL.
     67  promptShownPromise = cancelNextNavigation(browser);
     68  ok(!browser.permitUnload().permitUnload, "permit unload should be false");
     69  await promptShownPromise;
     70 
     71  // Prompt is not shown, don't permit unload.
     72  let promptShown = false;
     73  let shownCallback = () => {
     74    promptShown = true;
     75  };
     76 
     77  browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
     78  ok(
     79    !browser.permitUnload("dontUnload").permitUnload,
     80    "permit unload should be false"
     81  );
     82  ok(!promptShown, "prompt should not have been displayed");
     83 
     84  // Prompt is not shown, permit unload.
     85  promptShown = false;
     86  ok(
     87    browser.permitUnload("unload").permitUnload,
     88    "permit unload should be true"
     89  );
     90  ok(!promptShown, "prompt should not have been displayed");
     91  browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
     92 
     93  promptShownPromise = PromptTestUtils.waitForPrompt(browser, {
     94    modalType: Services.prompt.MODAL_TYPE_CONTENT,
     95    promptType: "confirmEx",
     96  });
     97 
     98  let promptDismissed = false;
     99  let closedCallback = () => {
    100    promptDismissed = true;
    101  };
    102 
    103  browser.addEventListener("DOMModalDialogClosed", closedCallback);
    104 
    105  let promise = browser.asyncPermitUnload();
    106 
    107  let promiseResolved = false;
    108  promise.then(() => {
    109    promiseResolved = true;
    110  });
    111 
    112  let dialog = await promptShownPromise;
    113  ok(!promiseResolved, "Should not have resolved promise yet");
    114 
    115  await delay(permitUnloadTimeout * 1.5);
    116 
    117  ok(!promptDismissed, "Should not have dismissed prompt yet");
    118  ok(!promiseResolved, "Should not have resolved promise yet");
    119 
    120  await PromptTestUtils.handlePrompt(dialog, { buttonNumClick: 1 });
    121 
    122  let { permitUnload } = await promise;
    123  ok(promptDismissed, "Should have dismissed prompt");
    124  ok(!permitUnload, "Should not have permitted unload");
    125 
    126  browser.removeEventListener("DOMModalDialogClosed", closedCallback);
    127 
    128  promptShownPromise = allowNextNavigation(browser);
    129 
    130  /*
    131   * Check condition where no one requests a prompt.  In all cases,
    132   * permitUnload should be true, and all handlers fired.
    133   */
    134  url += "?1";
    135  BrowserTestUtils.startLoadingURIString(browser, url);
    136  await BrowserTestUtils.browserLoaded(browser, false, url);
    137  await promptShownPromise;
    138 
    139  promptShown = false;
    140  browser.addEventListener("DOMWillOpenModalDialog", shownCallback);
    141 
    142  ok(browser.permitUnload().permitUnload, "permit unload should be true");
    143  ok(!promptShown, "prompt should not have been displayed");
    144 
    145  promptShown = false;
    146  ok(
    147    browser.permitUnload("dontUnload").permitUnload,
    148    "permit unload should be true"
    149  );
    150  ok(!promptShown, "prompt should not have been displayed");
    151 
    152  promptShown = false;
    153  ok(
    154    browser.permitUnload("unload").permitUnload,
    155    "permit unload should be true"
    156  );
    157  ok(!promptShown, "prompt should not have been displayed");
    158 
    159  browser.removeEventListener("DOMWillOpenModalDialog", shownCallback);
    160 
    161  await BrowserTestUtils.removeTab(tab, { skipPermitUnload: true });
    162 });