tor-browser

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

browser_document_devtools_basics.js (4570B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 /**
      5 * Document the basics of DevTools backend via Fronts in a test.
      6 */
      7 
      8 "use strict";
      9 
     10 const TEST_URL = "data:text/html,new-tab";
     11 
     12 add_task(async () => {
     13  // Allow logging all RDP packets
     14  await pushPref("devtools.debugger.log", true);
     15  // Really all of them
     16  await pushPref("devtools.debugger.log.verbose", true);
     17 
     18  // Instantiate a DevTools server
     19  DevToolsServer.init();
     20  DevToolsServer.registerAllActors();
     21 
     22  // Instantiate a client connected to this server
     23  const transport = DevToolsServer.connectPipe();
     24  const client = new DevToolsClient(transport);
     25 
     26  // This will trigger some handshake with the server
     27  await client.connect();
     28 
     29  // You need to call listTabs once to retrieve the existing list of Tab Descriptor actors...
     30  const tabs = await client.mainRoot.listTabs();
     31 
     32  // ... which will let you receive the 'tabListChanged' event.
     33  // This is an empty RDP packet, you need to re-call listTabs to get the full new updated list of actors.
     34  const onTabListUpdated = client.mainRoot.once("tabListChanged");
     35 
     36  // Open a new tab.
     37  await BrowserTestUtils.openNewForegroundTab({
     38    gBrowser,
     39    url: TEST_URL,
     40  });
     41 
     42  await onTabListUpdated;
     43 
     44  // The new list of Tab descriptors should contain the newly opened tab
     45  const newTabs = await client.mainRoot.listTabs();
     46  is(newTabs.length, tabs.length + 1);
     47 
     48  const tabDescriptorActor = newTabs.pop();
     49  is(tabDescriptorActor.url, TEST_URL);
     50 
     51  // Query the Tab Descriptor actor to retrieve its related Watcher actor.
     52  // Each Descriptor actor has a dedicated watcher which will be scoped to the context of the descriptor.
     53  // Here the watcher will focus on the related tab.
     54  const watcherActor = await tabDescriptorActor.getWatcher();
     55 
     56  // The call to Watcher Actor's watchTargets will emit target-available-form RDP events.
     57  // One per available target. It will emit one for each immediatly available target,
     58  // but also for any available later. That, until you call unwatchTarget method.
     59  //
     60  // Here I'm listening to "target-available" to get a Front instance, which helps call RDP methods.
     61  // But this isn't an RDP event. This is a frontend-only thing.
     62  const onTopTargetAvailable = watcherActor.once("target-available");
     63 
     64  // watchTargets accepts "frame", "process" and "worker"
     65  // When debugging a web page you want to listen to frame and worker targets.
     66  // "frame" would better be named "WindowGlobal" as it will notify you about all the WindowGlobal of the page.
     67  // Each top level documents and any iframe documents will have a related WindowGlobal,
     68  // if any of these documents navigate, a new WindowGlobal will be instantiated.
     69  // If you care about workers, listen to worker targets as well.
     70  await watcherActor.watchTargets("frame");
     71 
     72  // This is a trivial example so we have a unique WindowGlobal target for the top level document
     73  const topTarget = await onTopTargetAvailable;
     74  is(topTarget.url, TEST_URL);
     75 
     76  // Similarly to watchTarget, the next call to watchResources will emit new resources right away as well as later.
     77  const onConsoleMessages = topTarget.once("resources-available-array");
     78 
     79  // If you want to observe anything, you have to use Watcher Actor's watchrResources API.
     80  // The list of all available resources is here:
     81  // https://searchfox.org/mozilla-central/source/devtools/server/actors/resources/index.js#9
     82  // And you might have a look at each ResourceWatcher subclass to learn more about the fields exposed by each resource type:
     83  // https://searchfox.org/mozilla-central/source/devtools/server/actors/resources
     84  await watcherActor.watchResources(["console-message"]);
     85 
     86  // You may use many useful actors on each target actor, like console, thread, ...
     87  // You can get the full list of available actors in:
     88  // https://searchfox.org/mozilla-central/source/devtools/server/actors/utils/actor-registry.js#176
     89  // And then look into the mentioned path for implementation.
     90  const webConsoleActor = await topTarget.getFront("console");
     91 
     92  // Call the Console API in order to force emitting a console-message resource
     93  await webConsoleActor.evaluateJSAsync({ text: "console.log('42')" });
     94 
     95  // Wait for the related console-message resource
     96  const [[, resources]] = await onConsoleMessages;
     97 
     98  // Note that resources-available-array comes with a "array" attribute which is an array of resources
     99  // which may contain various resource types.
    100  is(resources[0].arguments[0], "42");
    101 
    102  await client.close();
    103 });