tor-browser

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

browser_target_command_various_descriptors.js (8445B)


      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 with all possible descriptors
      7 
      8 const TEST_URL = "https://example.org/document-builder.sjs?html=org";
      9 const SECOND_TEST_URL = "https://example.com/document-builder.sjs?html=org";
     10 const CHROME_WORKER_URL = CHROME_URL_ROOT + "test_worker.js";
     11 
     12 const DESCRIPTOR_TYPES = require("resource://devtools/client/fronts/descriptors/descriptor-types.js");
     13 
     14 add_task(async function () {
     15  // Enabled fission prefs
     16  await pushPref("devtools.browsertoolbox.scope", "everything");
     17  // Disable the preloaded process as it gets created lazily and may interfere
     18  // with process count assertions
     19  await pushPref("dom.ipc.processPrelaunch.enabled", false);
     20  // This preference helps destroying the content process when we close the tab
     21  await pushPref("dom.ipc.keepProcessesAlive.web", 1);
     22 
     23  await testLocalTab();
     24  await testRemoteTab();
     25  await testParentProcess();
     26  await testWorker();
     27  await testWebExtension();
     28 });
     29 
     30 async function testParentProcess() {
     31  info("Test TargetCommand against parent process descriptor");
     32 
     33  const commands = await CommandsFactory.forMainProcess();
     34  const { descriptorFront } = commands;
     35 
     36  is(
     37    descriptorFront.descriptorType,
     38    DESCRIPTOR_TYPES.PROCESS,
     39    "The descriptor type is correct"
     40  );
     41  is(
     42    descriptorFront.isParentProcessDescriptor,
     43    true,
     44    "Descriptor front isParentProcessDescriptor is correct"
     45  );
     46  is(
     47    descriptorFront.isProcessDescriptor,
     48    true,
     49    "Descriptor front isProcessDescriptor is correct"
     50  );
     51 
     52  const targetCommand = commands.targetCommand;
     53  await targetCommand.startListening();
     54 
     55  const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
     56  Assert.greater(
     57    targets.length,
     58    1,
     59    "We get many targets when debugging the parent process"
     60  );
     61  const targetFront = targets[0];
     62  is(targetFront, targetCommand.targetFront, "The first is the top level one");
     63  is(
     64    targetFront.targetType,
     65    targetCommand.TYPES.FRAME,
     66    "the parent process target is of frame type, because it inherits from WindowGlobalTargetActor"
     67  );
     68  is(targetFront.isTopLevel, true, "This is flagged as top level");
     69 
     70  targetCommand.destroy();
     71  await waitForAllTargetsToBeAttached(targetCommand);
     72 
     73  await commands.destroy();
     74 }
     75 
     76 async function testLocalTab() {
     77  info("Test TargetCommand against local tab descriptor (via getTab({ tab }))");
     78 
     79  const tab = await addTab(TEST_URL);
     80  const commands = await CommandsFactory.forTab(tab);
     81  const { descriptorFront } = commands;
     82  is(
     83    descriptorFront.descriptorType,
     84    DESCRIPTOR_TYPES.TAB,
     85    "The descriptor type is correct"
     86  );
     87  is(
     88    descriptorFront.isTabDescriptor,
     89    true,
     90    "Descriptor front isTabDescriptor is correct"
     91  );
     92 
     93  const targetCommand = commands.targetCommand;
     94  await targetCommand.startListening();
     95 
     96  const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
     97  is(targets.length, 1, "Got a unique target");
     98  const targetFront = targets[0];
     99  is(targetFront, targetCommand.targetFront, "The first is the top level one");
    100  is(
    101    targetFront.targetType,
    102    targetCommand.TYPES.FRAME,
    103    "the tab target is of frame type"
    104  );
    105  is(targetFront.isTopLevel, true, "This is flagged as top level");
    106 
    107  targetCommand.destroy();
    108 
    109  BrowserTestUtils.removeTab(tab);
    110 
    111  await commands.destroy();
    112 }
    113 
    114 async function testRemoteTab() {
    115  info(
    116    "Test TargetCommand against remote tab descriptor (via getTab({ browserId }))"
    117  );
    118 
    119  const tab = await addTab(TEST_URL);
    120  const commands = await CommandsFactory.forRemoteTab(
    121    tab.linkedBrowser.browserId
    122  );
    123  const { descriptorFront } = commands;
    124  is(
    125    descriptorFront.descriptorType,
    126    DESCRIPTOR_TYPES.TAB,
    127    "The descriptor type is correct"
    128  );
    129  is(
    130    descriptorFront.isTabDescriptor,
    131    true,
    132    "Descriptor front isTabDescriptor is correct"
    133  );
    134 
    135  const targetCommand = commands.targetCommand;
    136  await targetCommand.startListening();
    137 
    138  const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
    139  is(targets.length, 1, "Got a unique target");
    140  const targetFront = targets[0];
    141  is(
    142    targetFront,
    143    targetCommand.targetFront,
    144    "TargetCommand top target is the same as the first target"
    145  );
    146  is(
    147    targetFront.targetType,
    148    targetCommand.TYPES.FRAME,
    149    "the tab target is of frame type"
    150  );
    151  is(targetFront.isTopLevel, true, "This is flagged as top level");
    152 
    153  const browser = tab.linkedBrowser;
    154  const onLoaded = BrowserTestUtils.browserLoaded(browser);
    155  BrowserTestUtils.startLoadingURIString(browser, SECOND_TEST_URL);
    156  await onLoaded;
    157 
    158  info("Wait for the new target");
    159  await waitFor(() => targetCommand.targetFront != targetFront);
    160  isnot(
    161    targetCommand.targetFront,
    162    targetFront,
    163    "The top level target changes on navigation"
    164  );
    165  ok(
    166    !targetCommand.targetFront.isDestroyed(),
    167    "The new target isn't destroyed"
    168  );
    169  ok(targetFront.isDestroyed(), "While the previous target is destroyed");
    170 
    171  targetCommand.destroy();
    172 
    173  BrowserTestUtils.removeTab(tab);
    174 
    175  await commands.destroy();
    176 }
    177 
    178 async function testWebExtension() {
    179  info("Test TargetCommand against webextension descriptor");
    180 
    181  const extension = ExtensionTestUtils.loadExtension({
    182    useAddonManager: "temporary",
    183    manifest: {
    184      name: "Sample extension",
    185    },
    186  });
    187 
    188  await extension.startup();
    189 
    190  const commands = await CommandsFactory.forAddon(extension.id);
    191  const { descriptorFront } = commands;
    192  is(
    193    descriptorFront.descriptorType,
    194    DESCRIPTOR_TYPES.EXTENSION,
    195    "The descriptor type is correct"
    196  );
    197  is(
    198    descriptorFront.isWebExtensionDescriptor,
    199    true,
    200    "Descriptor front isWebExtensionDescriptor is correct"
    201  );
    202 
    203  const targetCommand = commands.targetCommand;
    204  await targetCommand.startListening();
    205 
    206  const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
    207  is(targets.length, 1, "Got a unique target");
    208  const targetFront = targets[0];
    209  is(targetFront, targetCommand.targetFront, "The first is the top level one");
    210  is(
    211    targetFront.targetType,
    212    targetCommand.TYPES.FRAME,
    213    "the web extension target is of frame type, because it inherits from WindowGlobalTargetActor"
    214  );
    215  is(targetFront.isTopLevel, true, "This is flagged as top level");
    216  is(targetFront.addonId, extension.id, "The addonId attribute is correct");
    217 
    218  targetCommand.destroy();
    219 
    220  await extension.unload();
    221 
    222  await commands.destroy();
    223 }
    224 
    225 // CommandsFactory expect the worker id, which is computed from the nsIWorkerDebugger.id attribute
    226 function getNextWorkerDebuggerId() {
    227  return new Promise(resolve => {
    228    const wdm = Cc[
    229      "@mozilla.org/dom/workers/workerdebuggermanager;1"
    230    ].createInstance(Ci.nsIWorkerDebuggerManager);
    231    const listener = {
    232      onRegister(dbg) {
    233        wdm.removeListener(listener);
    234        resolve(dbg.id);
    235      },
    236    };
    237    wdm.addListener(listener);
    238  });
    239 }
    240 async function testWorker() {
    241  info("Test TargetCommand against worker descriptor");
    242 
    243  const workerUrl = CHROME_WORKER_URL + "#descriptor";
    244  const onNextWorker = getNextWorkerDebuggerId();
    245  const worker = new Worker(workerUrl);
    246  const workerId = await onNextWorker;
    247  ok(workerId, "Found the worker Debugger ID");
    248 
    249  const commands = await CommandsFactory.forWorker(workerId);
    250  const { descriptorFront } = commands;
    251  is(
    252    descriptorFront.descriptorType,
    253    DESCRIPTOR_TYPES.WORKER,
    254    "The descriptor type is correct"
    255  );
    256  is(
    257    descriptorFront.isWorkerDescriptor,
    258    true,
    259    "Descriptor front isWorkerDescriptor is correct"
    260  );
    261 
    262  const targetCommand = commands.targetCommand;
    263  await targetCommand.startListening();
    264 
    265  const targets = await targetCommand.getAllTargets(targetCommand.ALL_TYPES);
    266  is(targets.length, 1, "Got a unique target");
    267  const targetFront = targets[0];
    268  is(targetFront, targetCommand.targetFront, "The first is the top level one");
    269  is(
    270    targetFront.targetType,
    271    targetCommand.TYPES.WORKER,
    272    "the worker target is of worker type"
    273  );
    274  is(targetFront.isTopLevel, true, "This is flagged as top level");
    275 
    276  targetCommand.destroy();
    277 
    278  // Calling CommandsFactory.forWorker, will call RootFront.getWorker
    279  // which will spawn lots of worker legacy code, firing lots of requests,
    280  // which may still be pending
    281  await commands.waitForRequestsToSettle();
    282 
    283  await commands.destroy();
    284  worker.terminate();
    285 }