tor-browser

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

browser_target_command_content_scripts.js (5968B)


      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 TargetCommand API around workers
      7 
      8 const FISSION_TEST_URL = URL_ROOT_SSL + "fission_document.html";
      9 
     10 add_task(async function () {
     11  // Disable the preloaded process as it creates processes intermittently
     12  // which forces the emission of RDP requests we aren't correctly waiting for.
     13  await pushPref("dom.ipc.processPrelaunch.enabled", false);
     14 
     15  await pushPref("devtools.debugger.show-content-scripts", true);
     16 
     17  const extension = ExtensionTestUtils.loadExtension({
     18    manifest: {
     19      name: "Addon with content script",
     20      content_scripts: [
     21        {
     22          matches: [`https://example.com/*`],
     23          js: ["content-script.js"],
     24        },
     25      ],
     26    },
     27    files: {
     28      "content-script.js": function () {
     29        // eslint-disable-next-line no-undef
     30        browser.test.notifyPass("contentScriptRan");
     31      },
     32    },
     33  });
     34 
     35  await extension.startup();
     36 
     37  info("Test TargetCommand against content scripts via a tab target");
     38  const tab = await addTab(FISSION_TEST_URL);
     39 
     40  await extension.awaitFinish("contentScriptRan");
     41 
     42  // Create a TargetCommand for the tab
     43  const commands = await CommandsFactory.forTab(tab);
     44  const targetCommand = commands.targetCommand;
     45 
     46  await commands.targetCommand.startListening();
     47 
     48  const { TYPES } = targetCommand;
     49 
     50  info("Check that getAllTargets only returns content scripts");
     51  const contentScripts = await targetCommand.getAllTargets([
     52    TYPES.CONTENT_SCRIPT,
     53  ]);
     54 
     55  is(contentScripts.length, 1, "Retrieved the content script");
     56  const [contentScript] = contentScripts;
     57  Assert.stringContains(contentScript.title, "Addon with content script");
     58 
     59  info("Assert that watchTargets works for the existing content script");
     60  const targets = [];
     61  const destroyedTargets = [];
     62  const onAvailable = async ({ targetFront }) => {
     63    info(`onAvailable called for ${targetFront.title}`);
     64    is(
     65      targetFront.targetType,
     66      TYPES.CONTENT_SCRIPT,
     67      "We are only notified about content script targets"
     68    );
     69    ok(!targetFront.isTopLevel, "The content scripts are never top level");
     70    targets.push(targetFront);
     71    info(`Handled ${targets.length} targets\n`);
     72  };
     73  const onDestroyed = async ({ targetFront }) => {
     74    is(
     75      targetFront.targetType,
     76      TYPES.CONTENT_SCRIPT,
     77      "We are only notified about content script targets"
     78    );
     79    destroyedTargets.push(targetFront);
     80  };
     81 
     82  await targetCommand.watchTargets({
     83    types: [TYPES.CONTENT_SCRIPT],
     84    onAvailable,
     85    onDestroyed,
     86  });
     87 
     88  is(targets.length, 1, "watchTargets notifies about a unique target");
     89  is(
     90    targets[0],
     91    contentScript,
     92    "watchTargets reports the same target instance"
     93  );
     94 
     95  await reloadBrowser();
     96 
     97  await waitFor(
     98    () => destroyedTargets.length == 1,
     99    "Wait for content script target to be destroyed on navigation"
    100  );
    101  await waitFor(
    102    () => targets.length == 2,
    103    "Wait for a new content script target to be created on navigation"
    104  );
    105 
    106  is(destroyedTargets[0], contentScript, "the previous target is destroyed");
    107  is(targets.length, 2, "a new target is notified");
    108  Assert.stringContains(
    109    targets[1].title,
    110    "Addon with content script",
    111    "the new target is still about the same content script"
    112  );
    113 
    114  await extension.unload();
    115 
    116  await waitFor(
    117    () => destroyedTargets.length == 2,
    118    "Content scripts are destroyed on extension destruction"
    119  );
    120 
    121  targetCommand.unwatchTargets({
    122    types: [TYPES.CONTENT_SCRIPT],
    123    onAvailable,
    124    onDestroyed,
    125  });
    126  targetCommand.destroy();
    127 
    128  BrowserTestUtils.removeTab(tab);
    129  await commands.destroy();
    130 });
    131 
    132 // Cover the special codepath used by VS.Code which listens to CONTENT SCRIPT targets
    133 // on a parent process watcher.
    134 add_task(async function () {
    135  info(
    136    "Test TargetCommand against content scripts via multiprocess descriptor"
    137  );
    138 
    139  await pushPref("devtools.browsertoolbox.scope", "everything");
    140 
    141  const extension = ExtensionTestUtils.loadExtension({
    142    manifest: {
    143      name: "Addon with content script",
    144      content_scripts: [
    145        {
    146          matches: [`https://example.com/*`],
    147          js: ["content-script.js"],
    148        },
    149      ],
    150    },
    151    files: {
    152      "content-script.js": function () {
    153        // eslint-disable-next-line no-undef
    154        browser.test.notifyPass("contentScriptRan");
    155      },
    156    },
    157  });
    158 
    159  await extension.startup();
    160 
    161  const tab = await addTab(FISSION_TEST_URL);
    162 
    163  await extension.awaitFinish("contentScriptRan");
    164 
    165  info(" ### Listen for content scripts");
    166  {
    167    // Create a TargetCommand for the tab
    168    const commands = await CommandsFactory.forMainProcess();
    169    const targetCommand = commands.targetCommand;
    170 
    171    targetCommand.listenForContentScripts = true;
    172    await targetCommand.startListening();
    173 
    174    const { TYPES } = targetCommand;
    175 
    176    info("Check that getAllTargets only returns content scripts");
    177    const contentScripts = await targetCommand.getAllTargets([
    178      TYPES.CONTENT_SCRIPT,
    179    ]);
    180 
    181    is(contentScripts.length, 1, "Retrieved the content script");
    182    const [contentScript] = contentScripts;
    183    Assert.stringContains(contentScript.title, "Addon with content script");
    184 
    185    await commands.destroy();
    186  }
    187 
    188  info(" ### Do not listen for content script");
    189  {
    190    // Create a TargetCommand for the tab
    191    const commands = await CommandsFactory.forMainProcess();
    192    const targetCommand = commands.targetCommand;
    193 
    194    targetCommand.listenForContentScripts = false;
    195    await targetCommand.startListening();
    196 
    197    const { TYPES } = targetCommand;
    198 
    199    info("Check that getAllTargets only returns content scripts");
    200    const contentScripts = await targetCommand.getAllTargets([
    201      TYPES.CONTENT_SCRIPT,
    202    ]);
    203 
    204    is(contentScripts.length, 0, "No content script is retrieved");
    205 
    206    await commands.destroy();
    207  }
    208 
    209  await extension.unload();
    210 
    211  BrowserTestUtils.removeTab(tab);
    212 });