tor-browser

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

browser_document_tracer.js (3347B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const JS_CODE = `
      7 window.onclick = function foo() {
      8  setTimeout(function bar() {
      9    dump("click and timed out\n");
     10    subFunction();
     11    document.documentElement.setAttribute("foo", "bar");
     12  });
     13  function subFunction() { nestedSubFunction(); };
     14  function nestedSubFunction() {};
     15 };
     16 window.scriptReady = true;
     17 `;
     18 const TEST_URL =
     19  "data:text/html,<!DOCTYPE html><html><script>" + JS_CODE + " </script>";
     20 
     21 add_task(async function testTracingDocument() {
     22  const tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_URL);
     23 
     24  await SpecialPowers.spawn(tab.linkedBrowser, [], async () => {
     25    info("Wait for scriptReady on the window object");
     26    await ContentTaskUtils.waitForCondition(
     27      () => content.wrappedJSObject.scriptReady
     28    );
     29 
     30    const { JSTracer } = ChromeUtils.importESModule(
     31      "resource://devtools/server/tracer/tracer.sys.mjs",
     32      { global: "shared" }
     33    );
     34 
     35    // We have to fake opening DevTools otherwise DebuggerNotificationObserver wouldn't work
     36    // and the tracer wouldn't be able to trace the DOM events.
     37    ChromeUtils.notifyDevToolsOpened();
     38 
     39    const frames = [];
     40    const mutations = [];
     41    const listener = {
     42      onTracingFrame(frameInfo) {
     43        frames.push(frameInfo);
     44      },
     45      onTracingDOMMutation(mutation) {
     46        mutations.push(mutation);
     47      },
     48    };
     49    info("Register a tracing listener");
     50    JSTracer.addTracingListener(listener);
     51 
     52    info("Start tracing the iframe");
     53    JSTracer.startTracing({
     54      global: content,
     55      traceDOMEvents: true,
     56      traceDOMMutations: ["attributes"],
     57    });
     58 
     59    info("Dispatch a click event on the iframe");
     60    EventUtils.synthesizeMouseAtCenter(
     61      content.document.documentElement,
     62      {},
     63      content
     64    );
     65 
     66    info("Wait for the traces generated by this click");
     67    await ContentTaskUtils.waitForCondition(() => frames.length == 4);
     68    info("Wait for the mutation to be notified");
     69    await ContentTaskUtils.waitForCondition(() => mutations.length == 1);
     70 
     71    const firstFrame = frames[0];
     72    is(firstFrame.formatedDisplayName, "λ foo");
     73    is(firstFrame.currentDOMEvent, "global.click");
     74    is(firstFrame.depth, 0);
     75 
     76    const secondFrame = frames[1];
     77    is(secondFrame.formatedDisplayName, "λ bar");
     78    is(secondFrame.currentDOMEvent, "setTimeoutCallback");
     79    is(secondFrame.depth, 0);
     80 
     81    const thirdFrame = frames[2];
     82    is(thirdFrame.formatedDisplayName, "λ subFunction");
     83    is(thirdFrame.currentDOMEvent, "setTimeoutCallback");
     84    is(thirdFrame.depth, 1);
     85 
     86    const lastFrame = frames[3];
     87    is(lastFrame.formatedDisplayName, "λ nestedSubFunction");
     88    is(lastFrame.currentDOMEvent, "setTimeoutCallback");
     89    is(lastFrame.depth, 2);
     90 
     91    const mutation = mutations[0];
     92    is(mutation.type, "attributes");
     93    is(mutation.element, content.document.documentElement);
     94    is(mutation.caller.filename, content.document.location.href);
     95    // ensure that the depth is correct and the DOM Mutation is nested to `bar` and not `subFunction` or `nestedSubFunction`
     96    is(mutation.depth, 1);
     97 
     98    JSTracer.stopTracing();
     99    JSTracer.removeTracingListener(listener);
    100 
    101    ChromeUtils.notifyDevToolsClosed();
    102  });
    103 
    104  BrowserTestUtils.removeTab(tab);
    105 });