tor-browser

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

browser_frame_history.js (7607B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 /* eslint-disable mozilla/no-arbitrary-setTimeout */
      5 
      6 /**
      7 Ensure that frameset history works properly when restoring a tab,
      8 provided that the frameset is static.
      9 */
     10 
     11 // Loading a toplevel frameset
     12 add_task(async function () {
     13  await SpecialPowers.pushPrefEnv({
     14    set: [
     15      ["browser.navigation.requireUserInteraction", false],
     16      ["dom.navigation.webidl.enabled", true],
     17    ],
     18  });
     19 
     20  let testURL =
     21    getRootDirectory(gTestPath) + "browser_frame_history_index.html";
     22  let tab = BrowserTestUtils.addTab(gBrowser, testURL);
     23  gBrowser.selectedTab = tab;
     24 
     25  info("Opening a page with three frames, 4 loads should take place");
     26  await waitForLoadsInBrowser(tab.linkedBrowser, 4);
     27 
     28  let browser_b =
     29    tab.linkedBrowser.contentDocument.getElementsByTagName("frame")[1];
     30  let document_b = browser_b.contentDocument;
     31  let links = document_b.getElementsByTagName("a");
     32 
     33  // We're going to click on the first link, so listen for another load event
     34  info("Clicking on link 1, 1 load should take place");
     35  let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
     36  EventUtils.sendMouseEvent(
     37    { type: "click" },
     38    links[0],
     39    browser_b.contentWindow
     40  );
     41  await promise;
     42 
     43  info("Clicking on link 2, 1 load should take place");
     44  promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
     45  EventUtils.sendMouseEvent(
     46    { type: "click" },
     47    links[1],
     48    browser_b.contentWindow
     49  );
     50  await promise;
     51 
     52  info("Close then un-close page, 4 loads should take place");
     53  await promiseRemoveTabAndSessionState(tab);
     54  let newTab = ss.undoCloseTab(window, 0);
     55  await waitForLoadsInBrowser(newTab.linkedBrowser, 4);
     56 
     57  info("Go back in time, 1 load should take place");
     58  gBrowser.goBack();
     59  await waitForLoadsInBrowser(newTab.linkedBrowser, 1);
     60 
     61  let expectedURLEnds = ["a.html", "b.html", "c1.html"];
     62  let frames =
     63    newTab.linkedBrowser.contentDocument.getElementsByTagName("frame");
     64  for (let i = 0; i < frames.length; i++) {
     65    is(
     66      frames[i].contentDocument.location.href,
     67      getRootDirectory(gTestPath) +
     68        "browser_frame_history_" +
     69        expectedURLEnds[i],
     70      "frame " + i + " has the right url"
     71    );
     72  }
     73 
     74  let expectedUrls = ["c", "c1", "c2"].map(
     75    url => `${getRootDirectory(gTestPath)}browser_frame_history_${url}.html`
     76  );
     77  let entryUrls = frames[2].contentWindow.navigation
     78    .entries()
     79    .map(entry => entry.url);
     80  for (const [entryUrl, expectedUrl] of expectedUrls.map((url, i) => [
     81    entryUrls[i],
     82    url,
     83  ])) {
     84    is(entryUrl, expectedUrl, "frame 2 NHE has correct url");
     85  }
     86 
     87  gBrowser.removeTab(newTab);
     88 });
     89 
     90 // Loading the frameset inside an iframe
     91 add_task(async function () {
     92  let testURL =
     93    getRootDirectory(gTestPath) + "browser_frame_history_index2.html";
     94  let tab = BrowserTestUtils.addTab(gBrowser, testURL);
     95  gBrowser.selectedTab = tab;
     96 
     97  info(
     98    "iframe: Opening a page with an iframe containing three frames, 5 loads should take place"
     99  );
    100  await waitForLoadsInBrowser(tab.linkedBrowser, 5);
    101 
    102  let browser_b = tab.linkedBrowser.contentDocument
    103    .getElementById("iframe")
    104    .contentDocument.getElementsByTagName("frame")[1];
    105  let document_b = browser_b.contentDocument;
    106  let links = document_b.getElementsByTagName("a");
    107 
    108  // We're going to click on the first link, so listen for another load event
    109  info("iframe: Clicking on link 1, 1 load should take place");
    110  let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
    111  EventUtils.sendMouseEvent(
    112    { type: "click" },
    113    links[0],
    114    browser_b.contentWindow
    115  );
    116  await promise;
    117 
    118  info("iframe: Clicking on link 2, 1 load should take place");
    119  promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
    120  EventUtils.sendMouseEvent(
    121    { type: "click" },
    122    links[1],
    123    browser_b.contentWindow
    124  );
    125  await promise;
    126 
    127  info("iframe: Close then un-close page, 5 loads should take place");
    128  await promiseRemoveTabAndSessionState(tab);
    129  let newTab = ss.undoCloseTab(window, 0);
    130  await waitForLoadsInBrowser(newTab.linkedBrowser, 5);
    131 
    132  info("iframe: Go back in time, 1 load should take place");
    133  gBrowser.goBack();
    134  await waitForLoadsInBrowser(newTab.linkedBrowser, 1);
    135 
    136  let expectedURLEnds = ["a.html", "b.html", "c1.html"];
    137  let frames = newTab.linkedBrowser.contentDocument
    138    .getElementById("iframe")
    139    .contentDocument.getElementsByTagName("frame");
    140  for (let i = 0; i < frames.length; i++) {
    141    is(
    142      frames[i].contentDocument.location.href,
    143      getRootDirectory(gTestPath) +
    144        "browser_frame_history_" +
    145        expectedURLEnds[i],
    146      "frame " + i + " has the right url"
    147    );
    148  }
    149  gBrowser.removeTab(newTab);
    150 });
    151 
    152 // Now, test that we don't record history if the iframe is added dynamically
    153 add_task(async function () {
    154  // Start with an empty history
    155  let blankState = JSON.stringify({
    156    windows: [
    157      {
    158        tabs: [
    159          { entries: [{ url: "about:blank", triggeringPrincipal_base64 }] },
    160        ],
    161        _closedTabs: [],
    162      },
    163    ],
    164    _closedWindows: [],
    165  });
    166  await setBrowserState(blankState);
    167 
    168  let testURL =
    169    getRootDirectory(gTestPath) + "browser_frame_history_index_blank.html";
    170  let tab = BrowserTestUtils.addTab(gBrowser, testURL);
    171  gBrowser.selectedTab = tab;
    172  await waitForLoadsInBrowser(tab.linkedBrowser, 1);
    173 
    174  info(
    175    "dynamic: Opening a page with an iframe containing three frames, 4 dynamic loads should take place"
    176  );
    177  let doc = tab.linkedBrowser.contentDocument;
    178  let iframe = doc.createElement("iframe");
    179  iframe.id = "iframe";
    180  iframe.src = "browser_frame_history_index.html";
    181  doc.body.appendChild(iframe);
    182  await waitForLoadsInBrowser(tab.linkedBrowser, 4);
    183 
    184  let browser_b = tab.linkedBrowser.contentDocument
    185    .getElementById("iframe")
    186    .contentDocument.getElementsByTagName("frame")[1];
    187  let document_b = browser_b.contentDocument;
    188  let links = document_b.getElementsByTagName("a");
    189 
    190  // We're going to click on the first link, so listen for another load event
    191  info("dynamic: Clicking on link 1, 1 load should take place");
    192  let promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
    193  EventUtils.sendMouseEvent(
    194    { type: "click" },
    195    links[0],
    196    browser_b.contentWindow
    197  );
    198  await promise;
    199 
    200  info("dynamic: Clicking on link 2, 1 load should take place");
    201  promise = waitForLoadsInBrowser(tab.linkedBrowser, 1);
    202  EventUtils.sendMouseEvent(
    203    { type: "click" },
    204    links[1],
    205    browser_b.contentWindow
    206  );
    207  await promise;
    208 
    209  info("Check in the state that we have not stored this history");
    210  let state = ss.getBrowserState();
    211  info(JSON.stringify(JSON.parse(state), null, "\t"));
    212  is(
    213    state.indexOf("c1.html"),
    214    -1,
    215    "History entry was not stored in the session state"
    216  );
    217  gBrowser.removeTab(tab);
    218 });
    219 
    220 // helper functions
    221 function waitForLoadsInBrowser(aBrowser, aLoadCount) {
    222  return new Promise(resolve => {
    223    let loadCount = 0;
    224    aBrowser.addEventListener(
    225      "load",
    226      function listener() {
    227        if (++loadCount < aLoadCount) {
    228          info(
    229            "Got " + loadCount + " loads, waiting until we have " + aLoadCount
    230          );
    231          return;
    232        }
    233 
    234        aBrowser.removeEventListener("load", listener, true);
    235        resolve();
    236      },
    237      true
    238    );
    239  });
    240 }
    241 
    242 function timeout(delay, task) {
    243  return new Promise((resolve, reject) => {
    244    setTimeout(() => resolve(true), delay);
    245    task.then(() => resolve(false), reject);
    246  });
    247 }