tor-browser

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

head.js (7048B)


      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 
      5 "use strict";
      6 
      7 var { ContextDescriptorType } = ChromeUtils.importESModule(
      8  "chrome://remote/content/shared/messagehandler/MessageHandler.sys.mjs"
      9 );
     10 
     11 var { WindowGlobalMessageHandler } = ChromeUtils.importESModule(
     12  "chrome://remote/content/shared/messagehandler/WindowGlobalMessageHandler.sys.mjs"
     13 );
     14 
     15 var contextDescriptorAll = {
     16  type: ContextDescriptorType.All,
     17 };
     18 
     19 function createRootMessageHandler(sessionId) {
     20  const { RootMessageHandlerRegistry } = ChromeUtils.importESModule(
     21    "chrome://remote/content/shared/messagehandler/RootMessageHandlerRegistry.sys.mjs"
     22  );
     23  return RootMessageHandlerRegistry.getOrCreateMessageHandler(sessionId);
     24 }
     25 
     26 /**
     27 * Load the provided url in an existing browser.
     28 * Returns a promise which will resolve when the page is loaded.
     29 *
     30 * @param {Browser} browser
     31 *     The browser element where the URL should be loaded.
     32 * @param {string} url
     33 *     The URL to load in the new tab
     34 */
     35 async function loadURL(browser, url) {
     36  const loaded = BrowserTestUtils.browserLoaded(browser);
     37  BrowserTestUtils.startLoadingURIString(browser, url);
     38  return loaded;
     39 }
     40 
     41 /**
     42 * Create a new foreground tab loading the provided url.
     43 * Returns a promise which will resolve when the page is loaded.
     44 *
     45 * @param {string} url
     46 *     The URL to load in the new tab
     47 */
     48 async function addTab(url) {
     49  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
     50  registerCleanupFunction(() => {
     51    gBrowser.removeTab(tab);
     52  });
     53  return tab;
     54 }
     55 
     56 /**
     57 * Create inline markup for a simple iframe that can be used with
     58 * document-builder.sjs. The iframe will be served under the provided domain.
     59 *
     60 * @param {string} domain
     61 *     A domain (eg "example.com"), compatible with build/pgo/server-locations.txt
     62 */
     63 function createFrame(domain) {
     64  return createFrameForUri(
     65    `https://${domain}/document-builder.sjs?html=frame-${domain}`
     66  );
     67 }
     68 
     69 function createFrameForUri(uri) {
     70  return `<iframe src="${encodeURI(uri)}"></iframe>`;
     71 }
     72 
     73 /**
     74 * Create a XUL browser element in the provided XUL tab, with the provided type.
     75 *
     76 * @param {XULTab} tab
     77 *     The XUL tab in which the browser element should be inserted.
     78 * @param {string} type
     79 *     The type attribute of the browser element, "chrome" or "content".
     80 * @returns {XULBrowser}
     81 *     The created browser element.
     82 */
     83 function createParentBrowserElement(tab, type) {
     84  const parentBrowser = gBrowser.ownerDocument.createXULElement("browser");
     85  parentBrowser.setAttribute("type", type);
     86  const container = gBrowser.getBrowserContainer(tab.linkedBrowser);
     87  container.appendChild(parentBrowser);
     88 
     89  return parentBrowser;
     90 }
     91 
     92 // Create a test page with 2 iframes:
     93 // - one with a different eTLD+1 (example.com)
     94 // - one with a nested iframe on a different eTLD+1 (example.net)
     95 //
     96 // Overall the document structure should look like:
     97 //
     98 // html (example.org)
     99 //   iframe (example.org)
    100 //     iframe (example.net)
    101 //   iframe(example.com)
    102 //
    103 // Which means we should have 4 browsing contexts in total.
    104 function createTestMarkupWithFrames() {
    105  // Create the markup for an example.net frame nested in an example.com frame.
    106  const NESTED_FRAME_MARKUP = createFrameForUri(
    107    `https://example.org/document-builder.sjs?html=${createFrame(
    108      "example.net"
    109    )}`
    110  );
    111 
    112  // Combine the nested frame markup created above with an example.com frame.
    113  const TEST_URI_MARKUP = `${NESTED_FRAME_MARKUP}${createFrame("example.com")}`;
    114 
    115  // Create the test page URI on example.org.
    116  return `https://example.org/document-builder.sjs?html=${encodeURI(
    117    TEST_URI_MARKUP
    118  )}`;
    119 }
    120 
    121 const hasPromiseResolved = async function (promise) {
    122  let resolved = false;
    123 
    124  // Note that the catch() is only here to avoid leaking promise rejections.
    125  // In all cases the resolved flag should be successfully flipped in finally().
    126  promise.finally(() => (resolved = true)).catch(() => {});
    127  // Make sure microtasks have time to run.
    128  await new Promise(resolve => Services.tm.dispatchToMainThread(resolve));
    129  return resolved;
    130 };
    131 
    132 /**
    133 * Install a sidebar extension.
    134 *
    135 * @returns {object}
    136 *     Return value with two properties:
    137 *     - extension: test wrapper as returned by SpecialPowers.loadExtension.
    138 *       Make sure to explicitly call extension.unload() before the end of the test.
    139 *     - sidebarBrowser: the browser element containing the extension sidebar.
    140 */
    141 async function installSidebarExtension() {
    142  info("Load the test extension");
    143  let extension = ExtensionTestUtils.loadExtension({
    144    manifest: {
    145      sidebar_action: {
    146        default_panel: "sidebar.html",
    147      },
    148    },
    149    useAddonManager: "temporary",
    150 
    151    files: {
    152      "sidebar.html": `
    153        <!DOCTYPE html>
    154        <html>
    155          Test extension
    156          <script src="sidebar.js"></script>
    157        </html>
    158      `,
    159      "sidebar.js": function () {
    160        const { browser } = this;
    161        browser.test.sendMessage("sidebar-loaded", {
    162          bcId: SpecialPowers.wrap(window).browsingContext.id,
    163        });
    164      },
    165      "tab.html": `
    166        <!DOCTYPE html>
    167        <html>
    168          Test extension (tab)
    169          <script src="tab.js"></script>
    170        </html>
    171      `,
    172      "tab.js": function () {
    173        const { browser } = this;
    174        browser.test.sendMessage("tab-loaded", {
    175          bcId: SpecialPowers.wrap(window).browsingContext.id,
    176        });
    177      },
    178    },
    179  });
    180 
    181  info("Wait for the extension to start");
    182  await extension.startup();
    183 
    184  info("Wait for the extension browsing context");
    185  const { bcId } = await extension.awaitMessage("sidebar-loaded");
    186  const sidebarBrowser = BrowsingContext.get(bcId).top.embedderElement;
    187  ok(sidebarBrowser, "Got a browser element for the extension sidebar");
    188 
    189  return {
    190    extension,
    191    sidebarBrowser,
    192  };
    193 }
    194 
    195 const SessionDataUpdateHelpers = {
    196  getUpdates(rootMessageHandler, browsingContext) {
    197    return rootMessageHandler.handleCommand({
    198      moduleName: "sessiondataupdate",
    199      commandName: "getSessionDataUpdates",
    200      destination: {
    201        id: browsingContext.id,
    202        type: WindowGlobalMessageHandler.type,
    203      },
    204    });
    205  },
    206 
    207  createSessionDataUpdate(
    208    values,
    209    method,
    210    category,
    211    descriptor = { type: ContextDescriptorType.All }
    212  ) {
    213    return {
    214      method,
    215      values,
    216      moduleName: "sessiondataupdate",
    217      category,
    218      contextDescriptor: descriptor,
    219    };
    220  },
    221 
    222  assertUpdate(update, expectedValues, expectedCategory) {
    223    is(
    224      update.length,
    225      expectedValues.length,
    226      "Update has the expected number of values"
    227    );
    228 
    229    for (const item of update) {
    230      info(`Check session data update item '${item.value}'`);
    231      is(item.category, expectedCategory, "Item has the expected category");
    232      is(
    233        expectedValues[update.indexOf(item)],
    234        item.value,
    235        "Item has the expected value"
    236      );
    237    }
    238  },
    239 };