tor-browser

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

browser_resources_console_messages_navigation.js (5458B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test the resource command API around CONSOLE_MESSAGE when navigating
      7 // tab and inner iframes to distinct origin/processes.
      8 
      9 const TEST_URL = URL_ROOT_COM_SSL + "doc_console.html";
     10 const TEST_IFRAME_URL = URL_ROOT_ORG_SSL + "doc_console_iframe.html";
     11 const TEST_DOMAIN = "https://example.org";
     12 add_task(async function () {
     13  const START_URL = "data:text/html;charset=utf-8,foo";
     14  const tab = await addTab(START_URL);
     15 
     16  const { client, resourceCommand, targetCommand } =
     17    await initResourceCommand(tab);
     18 
     19  await testCrossProcessTabNavigation(tab.linkedBrowser, resourceCommand);
     20  await testCrossProcessIframeNavigation(tab.linkedBrowser, resourceCommand);
     21 
     22  targetCommand.destroy();
     23  await client.close();
     24  BrowserTestUtils.removeTab(tab);
     25 });
     26 
     27 async function testCrossProcessTabNavigation(browser, resourceCommand) {
     28  info(
     29    "Navigate the top level document from data: URI to a https document including remote iframes"
     30  );
     31 
     32  let doneResolve;
     33  const messages = [];
     34  const onConsoleLogsComplete = new Promise(resolve => (doneResolve = resolve));
     35 
     36  const onAvailable = resources => {
     37    messages.push(...resources);
     38    if (messages.length == 2) {
     39      doneResolve();
     40    }
     41  };
     42 
     43  await resourceCommand.watchResources(
     44    [resourceCommand.TYPES.CONSOLE_MESSAGE],
     45    { onAvailable }
     46  );
     47 
     48  const onLoaded = BrowserTestUtils.browserLoaded(browser);
     49  BrowserTestUtils.startLoadingURIString(browser, TEST_URL);
     50  await onLoaded;
     51 
     52  info("Wait for log message");
     53  await onConsoleLogsComplete;
     54 
     55  // messages are coming from different targets so the order isn't guaranteed
     56  const topLevelMessageResource = messages.find(resource =>
     57    resource.filename.startsWith(URL_ROOT_COM_SSL)
     58  );
     59  const iframeMessage = messages.find(resource =>
     60    resource.filename.startsWith("data:")
     61  );
     62 
     63  assertConsoleMessage(resourceCommand, topLevelMessageResource, {
     64    targetFront: resourceCommand.targetCommand.targetFront,
     65    messageText: "top-level document log",
     66  });
     67  assertConsoleMessage(resourceCommand, iframeMessage, {
     68    targetFront: resourceCommand.targetCommand
     69      .getAllTargets([resourceCommand.targetCommand.TYPES.FRAME])
     70      .find(t => t.url.startsWith("data:")),
     71    messageText: "data url data log",
     72  });
     73 
     74  resourceCommand.unwatchResources([resourceCommand.TYPES.CONSOLE_MESSAGE], {
     75    onAvailable,
     76  });
     77 }
     78 
     79 async function testCrossProcessIframeNavigation(browser, resourceCommand) {
     80  info("Navigate an inner iframe from data: URI to a https remote URL");
     81 
     82  let doneResolve;
     83  const messages = [];
     84  const onConsoleLogsComplete = new Promise(resolve => (doneResolve = resolve));
     85 
     86  const onAvailable = resources => {
     87    messages.push(
     88      ...resources.filter(r => !r.arguments[0].startsWith("[WORKER] started"))
     89    );
     90    if (messages.length == 3) {
     91      doneResolve();
     92    }
     93  };
     94 
     95  await resourceCommand.watchResources(
     96    [resourceCommand.TYPES.CONSOLE_MESSAGE],
     97    {
     98      onAvailable,
     99    }
    100  );
    101 
    102  // messages are coming from different targets so the order isn't guaranteed
    103  const topLevelMessageResource = messages.find(resource =>
    104    resource.arguments[0].startsWith("top-level")
    105  );
    106  const dataUrlMessageResource = messages.find(resource =>
    107    resource.arguments[0].startsWith("data url")
    108  );
    109 
    110  // Assert cached messages from the previous top document
    111  assertConsoleMessage(resourceCommand, topLevelMessageResource, {
    112    messageText: "top-level document log",
    113  });
    114  assertConsoleMessage(resourceCommand, dataUrlMessageResource, {
    115    messageText: "data url data log",
    116  });
    117 
    118  // Navigate the iframe to another origin/process
    119  await SpecialPowers.spawn(browser, [TEST_IFRAME_URL], function (iframeUrl) {
    120    const iframe = content.document.querySelector("iframe");
    121    iframe.src = iframeUrl;
    122  });
    123 
    124  info("Wait for log message");
    125  await onConsoleLogsComplete;
    126 
    127  // iframeTarget will be different if Fission is on or off
    128  const iframeTarget = await getIframeTargetFront(
    129    resourceCommand.targetCommand
    130  );
    131 
    132  const iframeMessageResource = messages.find(resource =>
    133    resource.arguments[0].endsWith("iframe log")
    134  );
    135  assertConsoleMessage(resourceCommand, iframeMessageResource, {
    136    messageText: `${TEST_DOMAIN} iframe log`,
    137    targetFront: iframeTarget,
    138  });
    139 
    140  resourceCommand.unwatchResources([resourceCommand.TYPES.CONSOLE_MESSAGE], {
    141    onAvailable,
    142  });
    143 }
    144 
    145 function assertConsoleMessage(resourceCommand, messageResource, expected) {
    146  is(
    147    messageResource.resourceType,
    148    resourceCommand.TYPES.CONSOLE_MESSAGE,
    149    "Resource is a console message"
    150  );
    151  if (expected.targetFront) {
    152    is(
    153      messageResource.targetFront,
    154      expected.targetFront,
    155      "Message has the correct target front"
    156    );
    157  }
    158  is(
    159    messageResource.arguments[0],
    160    expected.messageText,
    161    "The correct type of message"
    162  );
    163 }
    164 
    165 async function getIframeTargetFront(targetCommand) {
    166  const frameTargets = targetCommand.getAllTargets([targetCommand.TYPES.FRAME]);
    167  const browsingContextID = await SpecialPowers.spawn(
    168    gBrowser.selectedBrowser,
    169    [],
    170    () => {
    171      return content.document.querySelector("iframe").browsingContext.id;
    172    }
    173  );
    174  const iframeTarget = frameTargets.find(target => {
    175    return target.browsingContextID == browsingContextID;
    176  });
    177  ok(iframeTarget, "Found the iframe target front");
    178  return iframeTarget;
    179 }