tor-browser

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

browser_aboutdebugging_addons_debug_debugger.js (6251B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 "use strict";
      4 
      5 Services.scriptloader.loadSubScript(
      6  "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/shared-head.js",
      7  this
      8 );
      9 
     10 /* import-globals-from helper-addons.js */
     11 Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
     12 
     13 const L10N = new LocalizationHelper(
     14  "devtools/client/locales/toolbox.properties"
     15 );
     16 
     17 const EXTENSION_NAME = "temporary-web-extension";
     18 const EXTENSION_ID = "test-devtools@mozilla.org";
     19 
     20 add_task(async function testOpenDebuggerReload() {
     21  await enableExtensionDebugging();
     22 
     23  info(
     24    "The debugger should show the source codes of extension even if " +
     25      "devtools.chrome.enabled and devtools.debugger.remote-enabled are off"
     26  );
     27  await pushPref("devtools.chrome.enabled", false);
     28  await pushPref("devtools.debugger.remote-enabled", false);
     29 
     30  const { document, tab, window } = await openAboutDebugging();
     31  await selectThisFirefoxPage(document, window.AboutDebugging.store);
     32 
     33  await installTemporaryExtensionFromXPI(
     34    {
     35      background() {
     36        window.someRandomMethodName = () => {
     37          // This will not be referred from anywhere.
     38          // However this is necessary to show as the source code in the debugger.
     39        };
     40      },
     41      id: EXTENSION_ID,
     42      name: EXTENSION_NAME,
     43    },
     44    document
     45  );
     46 
     47  // Select the debugger right away to avoid any noise coming from the inspector.
     48  await pushPref("devtools.toolbox.selectedTool", "jsdebugger");
     49  const { devtoolsWindow } = await openAboutDevtoolsToolbox(
     50    document,
     51    tab,
     52    window,
     53    EXTENSION_NAME
     54  );
     55  const toolbox = getToolbox(devtoolsWindow);
     56  const { panelWin } = toolbox.getCurrentPanel();
     57 
     58  info("Check the state of redux");
     59  ok(
     60    panelWin.dbg.store.getState().sourcesTree.isWebExtension,
     61    "isWebExtension flag in sourcesTree is true"
     62  );
     63 
     64  const descriptorTitle = devtoolsWindow.document.querySelector(
     65    ".qa-descriptor-title"
     66  );
     67  is(
     68    descriptorTitle.textContent,
     69    EXTENSION_NAME,
     70    "The add-on name is displayed in the toolbox header"
     71  );
     72 
     73  info("Check whether the element displays correctly");
     74  let sourceList = panelWin.document.querySelector(".sources-list");
     75  ok(sourceList, "Source list element displays correctly");
     76  ok(
     77    sourceList.textContent.includes("temporary-web-extension"),
     78    "Extension name displays correctly"
     79  );
     80 
     81  const { onResource: onDomCompleteResource } =
     82    await toolbox.commands.resourceCommand.waitForNextResource(
     83      toolbox.commands.resourceCommand.TYPES.DOCUMENT_EVENT,
     84      {
     85        ignoreExistingResources: true,
     86        predicate: resource => {
     87          return (
     88            resource.name === "dom-complete" &&
     89            resource.targetFront.url.endsWith("background_page.html")
     90          );
     91        },
     92      }
     93    );
     94 
     95  info("Reload the addon using a toolbox reload shortcut");
     96  toolbox.win.focus();
     97  synthesizeKeyShortcut(L10N.getStr("toolbox.reload.key"), toolbox.win);
     98 
     99  await onDomCompleteResource;
    100 
    101  info("Wait until a new background log message is logged");
    102  await waitFor(() => {
    103    // As React may re-create a new sources-list element,
    104    // fetch the latest instance
    105    sourceList = panelWin.document.querySelector(".sources-list");
    106    return sourceList?.textContent.includes("temporary-web-extension");
    107  }, "Wait for the source to re-appear");
    108 
    109  await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
    110  await removeTemporaryExtension(EXTENSION_NAME, document);
    111  await removeTab(tab);
    112 });
    113 
    114 add_task(async function testAddAndRemoveBreakpoint() {
    115  await enableExtensionDebugging();
    116 
    117  const { document, tab, window } = await openAboutDebugging();
    118  await selectThisFirefoxPage(document, window.AboutDebugging.store);
    119 
    120  await installTemporaryExtensionFromXPI(
    121    {
    122      background() {
    123        window.invokeLogFromWebextension = () => {
    124          console.log("From webextension");
    125        };
    126      },
    127      id: EXTENSION_ID,
    128      name: EXTENSION_NAME,
    129    },
    130    document
    131  );
    132 
    133  // Select the debugger right away to avoid any noise coming from the inspector.
    134  await pushPref("devtools.toolbox.selectedTool", "jsdebugger");
    135  const { devtoolsWindow } = await openAboutDevtoolsToolbox(
    136    document,
    137    tab,
    138    window,
    139    EXTENSION_NAME
    140  );
    141  const toolbox = getToolbox(devtoolsWindow);
    142  const dbg = createDebuggerContext(toolbox);
    143 
    144  info("Assert the threads displayed in Source Tree as well as Threads pane");
    145  const sourceTreeThreads = findAllElements(dbg, "sourceTreeThreads");
    146  is(
    147    sourceTreeThreads.length,
    148    1,
    149    "There is only one thread with source in the Source Tree"
    150  );
    151  is(
    152    sourceTreeThreads[0].textContent,
    153    "/_generated_background_page.html",
    154    "That thread is the background page"
    155  );
    156 
    157  const threadLabels = findAllElements(dbg, "threadsPaneItems");
    158  is(threadLabels.length, 2, "But there are two threads in the thread panel");
    159  is(threadLabels[0].textContent, "Web Extension Fallback Document");
    160  is(threadLabels[1].textContent, "/_generated_background_page.html");
    161 
    162  info("Select the source and add a breakpoint");
    163  // Note: the background script filename is dynamically generated id, so we
    164  // simply get the first source from the list.
    165  const displayedSources = dbg.selectors.getDisplayedSourcesList();
    166  const backgroundScript = displayedSources[0];
    167  await selectSource(dbg, backgroundScript);
    168  await addBreakpoint(dbg, backgroundScript, 3);
    169 
    170  info("Trigger the breakpoint and wait for the debugger to pause");
    171  const webconsole = await toolbox.selectTool("webconsole");
    172  const { hud } = webconsole;
    173  hud.ui.wrapper.dispatchEvaluateExpression("invokeLogFromWebextension()");
    174  await waitForPaused(dbg);
    175 
    176  info("Resume and remove the breakpoint");
    177  await resume(dbg);
    178  await removeBreakpoint(dbg, backgroundScript.id, 3);
    179 
    180  info("Trigger the function again and check the debugger does not pause");
    181  hud.ui.wrapper.dispatchEvaluateExpression("invokeLogFromWebextension()");
    182  await wait(500);
    183  assertNotPaused(dbg);
    184 
    185  await closeWebExtAboutDevtoolsToolbox(devtoolsWindow, window);
    186  await removeTemporaryExtension(EXTENSION_NAME, document);
    187  await removeTab(tab);
    188 });