tor-browser

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

browser_test_new_window_from_content.js (8576B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /*
      7  We have three ways for content to open new windows:
      8     1) window.open (with the default features)
      9     2) window.open (with non-default features)
     10     3) target="_blank" in <a> tags
     11 
     12     We also have two prefs that modify our window opening behaviours:
     13 
     14     1) browser.link.open_newwindow
     15 
     16        This has a numeric value that allows us to set our window-opening behaviours from
     17        content in three ways:
     18        1) Open links that would normally open a new window in the current tab
     19        2) Open links that would normally open a new window in a new window
     20        3) Open links that would normally open a new window in a new tab (default)
     21 
     22     2) browser.link.open_newwindow.restriction
     23 
     24        This has a numeric value that allows us to fine tune the browser.link.open_newwindow
     25        pref so that it can discriminate between different techniques for opening windows.
     26 
     27        0) All things that open windows should behave according to browser.link.open_newwindow.
     28        1) No things that open windows should behave according to browser.link.open_newwindow
     29           (essentially rendering browser.link.open_newwindow inert).
     30        2) Most things that open windows should behave according to browser.link.open_newwindow,
     31           _except_ for window.open calls with the "feature" parameter. This will open in a new
     32           window regardless of what browser.link.open_newwindow is set at. (default)
     33 
     34     This file attempts to test each window opening technique against all possible settings for
     35     each preference.
     36 */
     37 
     38 const kContentDoc =
     39  "https://www.example.com/browser/dom/tests/browser/test_new_window_from_content_child.html";
     40 const kNewWindowPrefKey = "browser.link.open_newwindow";
     41 const kNewWindowRestrictionPrefKey = "browser.link.open_newwindow.restriction";
     42 const kSameTab = "same tab";
     43 const kNewWin = "new window";
     44 const kNewTab = "new tab";
     45 
     46 SpecialPowers.pushPrefEnv({
     47  set: [["dom.require_user_interaction_for_beforeunload", false]],
     48 });
     49 
     50 requestLongerTimeout(3);
     51 
     52 // The following "matrices" represent the result of content attempting to
     53 // open a window with window.open with the default feature set. The key of
     54 // the kWinOpenDefault object represents the value of browser.link.open_newwindow.
     55 // The value for each key is an array that represents the result (either opening
     56 // the link in the same tab, a new window, or a new tab), where the index of each
     57 // result maps to the browser.link.open_newwindow.restriction pref. I've tried
     58 // to illustrate this more clearly in the kWinOpenDefault object.
     59 const kWinOpenDefault = {
     60  //                    open_newwindow.restriction
     61  //                    0         1        2
     62  // open_newwindow
     63  1: [kSameTab, kNewWin, kSameTab],
     64  2: [kNewWin, kNewWin, kNewWin],
     65  3: [kNewTab, kNewWin, kNewTab],
     66 };
     67 
     68 const kWinOpenNonDefault = {
     69  1: [kSameTab, kNewWin, kNewWin],
     70  2: [kNewWin, kNewWin, kNewWin],
     71  3: [kNewTab, kNewWin, kNewWin],
     72 };
     73 
     74 const kTargetBlank = {
     75  1: [kSameTab, kSameTab, kSameTab],
     76  2: [kNewWin, kNewWin, kNewWin],
     77  3: [kNewTab, kNewTab, kNewTab],
     78 };
     79 
     80 // We'll be changing these preferences a lot, so we'll stash their original
     81 // values and make sure we restore them at the end of the test.
     82 var originalNewWindowPref = Services.prefs.getIntPref(kNewWindowPrefKey);
     83 var originalNewWindowRestrictionPref = Services.prefs.getIntPref(
     84  kNewWindowRestrictionPrefKey
     85 );
     86 
     87 registerCleanupFunction(function () {
     88  Services.prefs.setIntPref(kNewWindowPrefKey, originalNewWindowPref);
     89  Services.prefs.setIntPref(
     90    kNewWindowRestrictionPrefKey,
     91    originalNewWindowRestrictionPref
     92  );
     93 });
     94 
     95 /**
     96 * For some expectation when a link is clicked, creates and
     97 * returns a Promise that resolves when that expectation is
     98 * fulfilled. For example, aExpectation might be kSameTab, which
     99 * will cause this function to return a Promise that resolves when
    100 * the current tab attempts to browse to about:blank.
    101 *
    102 * This function also takes care of cleaning up once the result has
    103 * occurred - for example, if a new window was opened, this function
    104 * closes it before resolving.
    105 *
    106 * @param aBrowser the <xul:browser> with the test document
    107 * @param aExpectation one of kSameTab, kNewWin, or kNewTab.
    108 * @return a Promise that resolves when the expectation is fulfilled,
    109 *         and cleaned up after.
    110 */
    111 function prepareForResult(aBrowser, aExpectation) {
    112  let expectedSpec = kContentDoc.replace(/[^\/]*$/, "dummy.html");
    113  switch (aExpectation) {
    114    case kSameTab:
    115      return (async function () {
    116        await BrowserTestUtils.browserLoaded(aBrowser);
    117        is(aBrowser.currentURI.spec, expectedSpec, "Should be at dummy.html");
    118        // Now put the browser back where it came from
    119        BrowserTestUtils.startLoadingURIString(aBrowser, kContentDoc);
    120        await BrowserTestUtils.browserLoaded(aBrowser);
    121      })();
    122    case kNewWin:
    123      return (async function () {
    124        let newWin = await BrowserTestUtils.waitForNewWindow({
    125          url: expectedSpec,
    126        });
    127        let newBrowser = newWin.gBrowser.selectedBrowser;
    128        is(newBrowser.currentURI.spec, expectedSpec, "Should be at dummy.html");
    129        await BrowserTestUtils.closeWindow(newWin);
    130      })();
    131    case kNewTab:
    132      return (async function () {
    133        let newTab = await BrowserTestUtils.waitForNewTab(gBrowser);
    134        is(
    135          newTab.linkedBrowser.currentURI.spec,
    136          expectedSpec,
    137          "Should be at dummy.html"
    138        );
    139        BrowserTestUtils.removeTab(newTab);
    140      })();
    141    default:
    142      ok(
    143        false,
    144        "prepareForResult can't handle an expectation of " + aExpectation
    145      );
    146      return Promise.resolve();
    147  }
    148 }
    149 
    150 /**
    151 * Ensure that clicks on a link with ID aLinkID cause us to
    152 * perform as specified in the supplied aMatrix (kWinOpenDefault,
    153 * for example).
    154 *
    155 * @param aLinkSelector a selector for the link within the testing page to click.
    156 * @param aMatrix a testing matrix for the
    157 *        browser.link.open_newwindow and browser.link.open_newwindow.restriction
    158 *        prefs to test against. See kWinOpenDefault for an example.
    159 */
    160 function testLinkWithMatrix(aLinkSelector, aMatrix) {
    161  return BrowserTestUtils.withNewTab(
    162    {
    163      gBrowser,
    164      url: kContentDoc,
    165    },
    166    async function (browser) {
    167      // This nested for-loop is unravelling the matrix const
    168      // we set up, and gives us three things through each tick
    169      // of the inner loop:
    170      // 1) newWindowPref: a browser.link.open_newwindow pref to try
    171      // 2) newWindowRestPref: a browser.link.open_newwindow.restriction pref to try
    172      // 3) expectation: what we expect the click outcome on this link to be,
    173      //                 which will either be kSameTab, kNewWin or kNewTab.
    174      for (let newWindowPref in aMatrix) {
    175        let expectations = aMatrix[newWindowPref];
    176        for (let i = 0; i < expectations.length; ++i) {
    177          let newWindowRestPref = i;
    178          let expectation = expectations[i];
    179 
    180          Services.prefs.setIntPref(
    181            "browser.link.open_newwindow",
    182            newWindowPref
    183          );
    184          Services.prefs.setIntPref(
    185            "browser.link.open_newwindow.restriction",
    186            newWindowRestPref
    187          );
    188          info("Clicking on " + aLinkSelector);
    189          info(
    190            "Testing with browser.link.open_newwindow = " +
    191              newWindowPref +
    192              " and " +
    193              "browser.link.open_newwindow.restriction = " +
    194              newWindowRestPref
    195          );
    196          info("Expecting: " + expectation);
    197          let resultPromise = prepareForResult(browser, expectation);
    198          BrowserTestUtils.synthesizeMouseAtCenter(aLinkSelector, {}, browser);
    199          await resultPromise;
    200          info("Got expectation: " + expectation);
    201        }
    202      }
    203    }
    204  );
    205 }
    206 
    207 add_setup(async function () {
    208  await SpecialPowers.pushPrefEnv({
    209    set: [["test.wait300msAfterTabSwitch", true]],
    210  });
    211 });
    212 
    213 add_task(async function test_window_open_with_defaults() {
    214  await testLinkWithMatrix("#winOpenDefault", kWinOpenDefault);
    215 });
    216 
    217 add_task(async function test_window_open_with_non_defaults() {
    218  await testLinkWithMatrix("#winOpenNonDefault", kWinOpenNonDefault);
    219 });
    220 
    221 add_task(async function test_window_open_dialog() {
    222  await testLinkWithMatrix("#winOpenDialog", kWinOpenNonDefault);
    223 });
    224 
    225 add_task(async function test_target__blank() {
    226  await testLinkWithMatrix("#targetBlank", kTargetBlank);
    227 });