tor-browser

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

browser_browsingContext-webProgress.js (7123B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 add_setup(async function () {
      7  await SpecialPowers.pushPrefEnv({
      8    set: [["test.wait300msAfterTabSwitch", true]],
      9  });
     10 });
     11 
     12 add_task(async function () {
     13  const tab = await BrowserTestUtils.openNewForegroundTab(
     14    gBrowser,
     15    "about:blank"
     16  );
     17  const browser = tab.linkedBrowser;
     18  const aboutBlankBrowsingContext = browser.browsingContext;
     19  const { webProgress } = aboutBlankBrowsingContext;
     20  ok(
     21    webProgress,
     22    "Got a WebProgress interface on BrowsingContext in the parent process"
     23  );
     24  is(
     25    webProgress.browsingContext,
     26    browser.browsingContext,
     27    "WebProgress.browsingContext refers to the right BrowsingContext"
     28  );
     29 
     30  const onLocationChanged = waitForNextLocationChange(webProgress);
     31  const newLocation = "data:text/html;charset=utf-8,first-page";
     32  let loaded = BrowserTestUtils.browserLoaded(browser);
     33  BrowserTestUtils.startLoadingURIString(browser, newLocation);
     34  await loaded;
     35 
     36  const firstPageBrowsingContext = browser.browsingContext;
     37  const isBfcacheInParentEnabled =
     38    SpecialPowers.Services.appinfo.sessionHistoryInParent &&
     39    SpecialPowers.Services.prefs.getBoolPref("fission.bfcacheInParent");
     40  is(
     41    aboutBlankBrowsingContext,
     42    firstPageBrowsingContext,
     43    "The first navigation away from the initial about:blank reuses the BrowsingContext with or without bfcacheInParent"
     44  );
     45 
     46  info("Wait for onLocationChange to be fired");
     47  {
     48    const { browsingContext, location, request, flags } =
     49      await onLocationChanged;
     50    is(
     51      browsingContext,
     52      firstPageBrowsingContext,
     53      "Location change fires on the new BrowsingContext"
     54    );
     55    ok(location instanceof Ci.nsIURI);
     56    is(location.spec, newLocation);
     57    ok(request instanceof Ci.nsIChannel);
     58    is(request.URI.spec, newLocation);
     59    is(flags, 0);
     60  }
     61 
     62  const onIframeLocationChanged = waitForNextLocationChange(webProgress);
     63  const iframeLocation = "data:text/html;charset=utf-8,iframe";
     64  const iframeBC = await SpecialPowers.spawn(
     65    browser,
     66    [iframeLocation],
     67    async url => {
     68      const iframe = content.document.createElement("iframe");
     69      await new Promise(resolve => {
     70        iframe.addEventListener("load", resolve, { once: true });
     71        iframe.src = url;
     72        content.document.body.appendChild(iframe);
     73      });
     74 
     75      return iframe.browsingContext;
     76    }
     77  );
     78  ok(
     79    iframeBC.webProgress,
     80    "The iframe BrowsingContext also exposes a WebProgress"
     81  );
     82  {
     83    const { browsingContext, location, request, flags } =
     84      await onIframeLocationChanged;
     85    is(
     86      browsingContext,
     87      iframeBC,
     88      "Iframe location change fires on the iframe BrowsingContext"
     89    );
     90    ok(location instanceof Ci.nsIURI);
     91    is(location.spec, iframeLocation);
     92    ok(request instanceof Ci.nsIChannel);
     93    is(request.URI.spec, iframeLocation);
     94    is(flags, 0);
     95  }
     96 
     97  const onSecondLocationChanged = waitForNextLocationChange(webProgress);
     98  const onSecondPageDocumentStart = waitForNextDocumentStart(webProgress);
     99  // eslint-disable-next-line @microsoft/sdl/no-insecure-url
    100  const secondLocation = "http://example.com/document-builder.sjs?html=com";
    101  loaded = BrowserTestUtils.browserLoaded(browser);
    102  BrowserTestUtils.startLoadingURIString(browser, secondLocation);
    103  await loaded;
    104 
    105  const secondPageBrowsingContext = browser.browsingContext;
    106  if (isBfcacheInParentEnabled) {
    107    isnot(
    108      firstPageBrowsingContext,
    109      secondPageBrowsingContext,
    110      "With bfcache in parent, navigations spawn a new BrowsingContext"
    111    );
    112  } else {
    113    is(
    114      firstPageBrowsingContext,
    115      secondPageBrowsingContext,
    116      "Without bfcache in parent, navigations reuse the same BrowsingContext"
    117    );
    118  }
    119  {
    120    const { browsingContext, location, request, flags } =
    121      await onSecondLocationChanged;
    122    is(
    123      browsingContext,
    124      secondPageBrowsingContext,
    125      "Second location change fires on the new BrowsingContext"
    126    );
    127    ok(location instanceof Ci.nsIURI);
    128    is(location.spec, secondLocation);
    129    ok(request instanceof Ci.nsIChannel);
    130    is(request.URI.spec, secondLocation);
    131    is(flags, 0);
    132  }
    133  {
    134    const { browsingContext, request } = await onSecondPageDocumentStart;
    135    is(
    136      browsingContext,
    137      firstPageBrowsingContext,
    138      "STATE_START, when navigating to another process, fires on the BrowsingContext we navigate *from*"
    139    );
    140    ok(request instanceof Ci.nsIChannel);
    141    is(request.URI.spec, secondLocation);
    142  }
    143 
    144  const onBackLocationChanged = waitForNextLocationChange(webProgress, true);
    145  const onBackDocumentStart = waitForNextDocumentStart(webProgress);
    146  browser.goBack();
    147 
    148  {
    149    const { browsingContext, location, request, flags } =
    150      await onBackLocationChanged;
    151    is(
    152      browsingContext,
    153      firstPageBrowsingContext,
    154      "location change, when navigating back, fires on the BrowsingContext we navigate *to*"
    155    );
    156    ok(location instanceof Ci.nsIURI);
    157    is(location.spec, newLocation);
    158    ok(request instanceof Ci.nsIChannel);
    159    is(request.URI.spec, newLocation);
    160    is(flags, 0);
    161  }
    162  {
    163    const { browsingContext, request } = await onBackDocumentStart;
    164    is(
    165      browsingContext,
    166      secondPageBrowsingContext,
    167      "STATE_START, when navigating back, fires on the BrowsingContext we navigate *from*"
    168    );
    169    ok(request instanceof Ci.nsIChannel);
    170    is(request.URI.spec, newLocation);
    171  }
    172 
    173  BrowserTestUtils.removeTab(tab);
    174 });
    175 
    176 function waitForNextLocationChange(webProgress, onlyTopLevel = false) {
    177  return new Promise(resolve => {
    178    const wpl = {
    179      QueryInterface: ChromeUtils.generateQI([
    180        "nsIWebProgressListener",
    181        "nsISupportsWeakReference",
    182      ]),
    183      onLocationChange(progress, request, location, flags) {
    184        if (onlyTopLevel && progress.browsingContext.parent) {
    185          // Ignore non-toplevel.
    186          return;
    187        }
    188        webProgress.removeProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
    189        resolve({
    190          browsingContext: progress.browsingContext,
    191          location,
    192          request,
    193          flags,
    194        });
    195      },
    196    };
    197    // Add a strong reference to the progress listener.
    198    resolve.wpl = wpl;
    199    webProgress.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
    200  });
    201 }
    202 
    203 function waitForNextDocumentStart(webProgress) {
    204  return new Promise(resolve => {
    205    const wpl = {
    206      QueryInterface: ChromeUtils.generateQI([
    207        "nsIWebProgressListener",
    208        "nsISupportsWeakReference",
    209      ]),
    210      onStateChange(progress, request, flags) {
    211        if (
    212          flags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
    213          flags & Ci.nsIWebProgressListener.STATE_START
    214        ) {
    215          webProgress.removeProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
    216          resolve({ browsingContext: progress.browsingContext, request });
    217        }
    218      },
    219    };
    220    // Add a strong reference to the progress listener.
    221    resolve.wpl = wpl;
    222    webProgress.addProgressListener(wpl, Ci.nsIWebProgress.NOTIFY_ALL);
    223  });
    224 }