tor-browser

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

browser_browsingContext-02.js (7863B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 add_task(async function () {
      7  await BrowserTestUtils.withNewTab(
      8    { gBrowser, url: "about:blank" },
      9    async function (browser) {
     10      const BASE1 = getRootDirectory(gTestPath).replace(
     11        "chrome://mochitests/content",
     12        // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     13        "http://example.com"
     14      );
     15      const BASE2 = getRootDirectory(gTestPath).replace(
     16        "chrome://mochitests/content",
     17        // eslint-disable-next-line @microsoft/sdl/no-insecure-url
     18        "http://test1.example.com"
     19      );
     20      const URL = BASE1 + "onload_message.html";
     21      let sixth = BrowserTestUtils.waitForNewTab(
     22        gBrowser,
     23        URL + "#sixth",
     24        true,
     25        true
     26      );
     27      let seventh = BrowserTestUtils.waitForNewTab(
     28        gBrowser,
     29        URL + "#seventh",
     30        true,
     31        true
     32      );
     33      let browserIds = await SpecialPowers.spawn(
     34        browser,
     35        [{ base1: BASE1, base2: BASE2 }],
     36        async function ({ base1, base2 }) {
     37          let top = content;
     38          top.name = "top";
     39          top.location.href += "#top";
     40 
     41          let contexts = {
     42            top: top.location.href,
     43            first: base1 + "dummy_page.html#first",
     44            third: base2 + "dummy_page.html#third",
     45            second: base1 + "dummy_page.html#second",
     46            fourth: base2 + "dummy_page.html#fourth",
     47            fifth: base1 + "dummy_page.html#fifth",
     48            sixth: base1 + "onload_message.html#sixth",
     49            seventh: base1 + "onload_message.html#seventh",
     50          };
     51 
     52          function addFrame(target, name) {
     53            return content.SpecialPowers.spawn(
     54              target,
     55              [name, contexts[name]],
     56              async (name, context) => {
     57                let doc = this.content.document;
     58 
     59                let frame = doc.createElement("iframe");
     60                doc.body.appendChild(frame);
     61                frame.name = name;
     62                frame.src = context;
     63                await new Promise(resolve => {
     64                  frame.addEventListener("load", resolve, { once: true });
     65                });
     66                return frame.browsingContext;
     67              }
     68            );
     69          }
     70 
     71          function addWindow(target, name, { options, resolve }) {
     72            return content.SpecialPowers.spawn(
     73              target,
     74              [name, contexts[name], options, resolve],
     75              (name, context, options, resolve) => {
     76                let win = this.content.open(context, name, options);
     77                let bc = win && win.docShell.browsingContext;
     78 
     79                if (resolve) {
     80                  return new Promise(resolve =>
     81                    this.content.addEventListener("message", () => resolve(bc))
     82                  );
     83                }
     84                return Promise.resolve({ name });
     85              }
     86            );
     87          }
     88 
     89          // We're going to create a tree that looks like the
     90          // following.
     91          //
     92          //           top          sixth    seventh
     93          //          /   \
     94          //         /     \        /
     95          //      first  second
     96          //      /   \           /
     97          //     /     \
     98          //  third  fourth - - -
     99          //          /
    100          //         /
    101          //      fifth
    102          //
    103          // The idea is to have one top level non-auxiliary browsing
    104          // context, five nested, one top level auxiliary with an
    105          // opener, and one top level without an opener. Given that
    106          // set of related and one unrelated browsing contexts we
    107          // wish to confirm that targeting is able to find
    108          // appropriate browsing contexts.
    109 
    110          // WindowGlobalChild.findBrowsingContextWithName requires access
    111          // checks, which can only be performed in the process of the accessor
    112          // WindowGlobalChild.
    113          function findWithName(bc, name) {
    114            return content.SpecialPowers.spawn(bc, [name], name => {
    115              return content.windowGlobalChild.findBrowsingContextWithName(
    116                name
    117              );
    118            });
    119          }
    120 
    121          async function reachable(start, target) {
    122            info(start.name, target.name);
    123            is(
    124              await findWithName(start, target.name),
    125              target,
    126              [start.name, "can reach", target.name].join(" ")
    127            );
    128          }
    129 
    130          async function unreachable(start, target) {
    131            is(
    132              await findWithName(start, target.name),
    133              null,
    134              [start.name, "can't reach", target.name].join(" ")
    135            );
    136          }
    137 
    138          let first = await addFrame(top, "first");
    139          info("first");
    140          let second = await addFrame(top, "second");
    141          info("second");
    142          let third = await addFrame(first, "third");
    143          info("third");
    144          let fourth = await addFrame(first, "fourth");
    145          info("fourth");
    146          let fifth = await addFrame(fourth, "fifth");
    147          info("fifth");
    148          let sixth = await addWindow(fourth, "sixth", { resolve: true });
    149          info("sixth");
    150          let seventh = await addWindow(fourth, "seventh", {
    151            options: ["noopener"],
    152          });
    153          info("seventh");
    154 
    155          let origin1 = [first, second, fifth, sixth];
    156          let origin2 = [third, fourth];
    157 
    158          let topBC = BrowsingContext.getFromWindow(top);
    159          let frames = new Map([
    160            [topBC, [topBC, first, second, third, fourth, fifth, sixth]],
    161            [first, [topBC, ...origin1, third, fourth]],
    162            [second, [topBC, ...origin1, third, fourth]],
    163            [third, [topBC, ...origin2, fifth, sixth]],
    164            [fourth, [topBC, ...origin2, fifth, sixth]],
    165            [fifth, [topBC, ...origin1, third, fourth]],
    166            [sixth, [...origin1, third, fourth]],
    167          ]);
    168 
    169          for (let [start, accessible] of frames) {
    170            for (let frame of frames.keys()) {
    171              if (accessible.includes(frame)) {
    172                await reachable(start, frame);
    173              } else {
    174                await unreachable(start, frame);
    175              }
    176            }
    177            await unreachable(start, seventh);
    178          }
    179 
    180          let topBrowserId = topBC.browserId;
    181          Assert.greater(topBrowserId, 0, "Should have a browser ID.");
    182          for (let [name, bc] of Object.entries({
    183            first,
    184            second,
    185            third,
    186            fourth,
    187            fifth,
    188          })) {
    189            is(
    190              bc.browserId,
    191              topBrowserId,
    192              `${name} frame should have the same browserId as top.`
    193            );
    194          }
    195 
    196          Assert.greater(sixth.browserId, 0, "sixth should have a browserId.");
    197          isnot(
    198            sixth.browserId,
    199            topBrowserId,
    200            "sixth frame should have a different browserId to top."
    201          );
    202 
    203          return [topBrowserId, sixth.browserId];
    204        }
    205      );
    206 
    207      [sixth, seventh] = await Promise.all([sixth, seventh]);
    208 
    209      is(
    210        browser.browserId,
    211        browserIds[0],
    212        "browser should have the right browserId."
    213      );
    214      is(
    215        browser.browsingContext.browserId,
    216        browserIds[0],
    217        "browser's BrowsingContext should have the right browserId."
    218      );
    219      is(
    220        sixth.linkedBrowser.browserId,
    221        browserIds[1],
    222        "sixth should have the right browserId."
    223      );
    224      is(
    225        sixth.linkedBrowser.browsingContext.browserId,
    226        browserIds[1],
    227        "sixth's BrowsingContext should have the right browserId."
    228      );
    229 
    230      for (let tab of [sixth, seventh]) {
    231        BrowserTestUtils.removeTab(tab);
    232      }
    233    }
    234  );
    235 });