tor-browser

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

browser_dbg-xhr-breakpoints.js (6951B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 "use strict";
      6 
      7 const { asyncStore } = require("devtools/client/debugger/src/utils/prefs");
      8 
      9 add_task(async function () {
     10  info("Test XHR requests done very early during page load");
     11 
     12  const dbg = await initDebugger("doc-xhr.html", "fetch.js");
     13 
     14  await addXHRBreakpoint(dbg, "doc", "GET");
     15 
     16  await SpecialPowers.spawn(
     17    gBrowser.selectedBrowser,
     18    [`${EXAMPLE_REMOTE_URL}doc-early-xhr.html`],
     19    remoteUrl => {
     20      const firstIframe = content.document.createElement("iframe");
     21      content.document.body.append(firstIframe);
     22      firstIframe.src = remoteUrl;
     23    }
     24  );
     25 
     26  await waitForPaused(dbg);
     27  await assertPausedAtSourceAndLine(
     28    dbg,
     29    findSource(dbg, "doc-early-xhr.html").id,
     30    10
     31  );
     32 
     33  const whyPaused = await waitFor(
     34    () => dbg.win.document.querySelector(".why-paused")?.innerText
     35  );
     36  is(
     37    whyPaused,
     38    `Paused on XMLHttpRequest\n(global) - doc-early-xhr.html:10:11`
     39  );
     40 
     41  await resume(dbg);
     42 
     43  await dbg.actions.removeXHRBreakpoint(0);
     44 
     45  await SpecialPowers.spawn(
     46    gBrowser.selectedBrowser,
     47    [`${EXAMPLE_REMOTE_URL}doc-early-xhr.html`],
     48    remoteUrl => {
     49      const secondIframe = content.document.createElement("iframe");
     50      content.document.body.append(secondIframe);
     51      secondIframe.src = remoteUrl;
     52    }
     53  );
     54 
     55  // Wait for some time, in order to wait for it to be paused
     56  // in case we regress
     57  await wait(1000);
     58 
     59  assertNotPaused(dbg);
     60 });
     61 
     62 add_task(async function () {
     63  info("Test simple XHR breakpoints set before doing the request");
     64 
     65  const dbg = await initDebugger("doc-xhr.html", "fetch.js");
     66 
     67  await addXHRBreakpoint(dbg, "doc", "GET");
     68 
     69  invokeInTab("main", "doc-xhr.html");
     70  await waitForPaused(dbg);
     71  await assertPausedAtSourceAndLine(dbg, findSource(dbg, "fetch.js").id, 4);
     72  await resume(dbg);
     73 
     74  await dbg.actions.removeXHRBreakpoint(0);
     75  await invokeInTab("main", "doc-xhr.html");
     76  assertNotPaused(dbg);
     77 
     78  info("Test that we do not pause on different method type");
     79  await addXHRBreakpoint(dbg, "doc", "POST");
     80  await invokeInTab("main", "doc-xhr.html");
     81  assertNotPaused(dbg);
     82 });
     83 
     84 // Tests the "pause on any URL" checkbox works properly
     85 add_task(async function () {
     86  info("Test 'pause on any URL'");
     87  const dbg = await initDebugger("doc-xhr.html", "fetch.js");
     88 
     89  // Enable pause on any URL
     90  await clickPauseOnAny(dbg, "SET_XHR_BREAKPOINT");
     91 
     92  invokeInTab("main", "doc-xhr.html");
     93  await waitForPaused(dbg);
     94  await resume(dbg);
     95  await assertDebuggerTabHighlight(dbg);
     96 
     97  invokeInTab("main", "fetch.js");
     98  await waitForPaused(dbg);
     99  await resume(dbg);
    100  await assertDebuggerTabHighlight(dbg);
    101 
    102  invokeInTab("main", "README.md");
    103  await waitForPaused(dbg);
    104  await resume(dbg);
    105  await assertDebuggerTabHighlight(dbg);
    106 
    107  // Disable pause on any URL
    108  await clickPauseOnAny(dbg, "DISABLE_XHR_BREAKPOINT");
    109  invokeInTab("main", "README.md");
    110  assertNotPaused(dbg);
    111 
    112  // Turn off the checkbox
    113  await dbg.actions.removeXHRBreakpoint(0);
    114 });
    115 
    116 // Tests removal works properly
    117 add_task(async function () {
    118  info("Assert the frontend state when removing breakpoints");
    119  const dbg = await initDebugger("doc-xhr.html");
    120 
    121  const pauseOnAnyCheckbox = getXHRBreakpointCheckbox(dbg);
    122 
    123  await clickPauseOnAny(dbg, "SET_XHR_BREAKPOINT");
    124  await addXHRBreakpoint(dbg, "1");
    125  await addXHRBreakpoint(dbg, "2");
    126  await addXHRBreakpoint(dbg, "3");
    127  await addXHRBreakpoint(dbg, "4");
    128 
    129  // Remove "2"
    130  await removeXHRBreakpoint(dbg, 1);
    131 
    132  const listItems = getXHRBreakpointsElements(dbg);
    133  is(listItems.length, 3, "3 XHR breakpoints display in list");
    134  is(pauseOnAnyCheckbox.checked, true, "The pause on any is still checked");
    135  is(
    136    getXHRBreakpointLabels(listItems).join(""),
    137    "134",
    138    "Only the desired breakpoint was removed"
    139  );
    140 });
    141 
    142 add_task(async function () {
    143  info("Assert that remove all the breakpoints work well");
    144  const dbg = await initDebugger("doc-xhr.html");
    145 
    146  await addXHRBreakpoint(dbg, "1");
    147  await addXHRBreakpoint(dbg, "2");
    148  await addXHRBreakpoint(dbg, "3");
    149  await addXHRBreakpoint(dbg, "4");
    150 
    151  is(
    152    getXHRBreakpointsElements(dbg).length,
    153    4,
    154    "There a 4 items on the XHR breakpoints display list"
    155  );
    156 
    157  let persistedXHRBreakpoints = await asyncStore.xhrBreakpoints;
    158  is(
    159    persistedXHRBreakpoints.length,
    160    4,
    161    "Check that the persisted XHR breakpoints have 4 items"
    162  );
    163 
    164  await dbg.actions.removeAllXHRBreakpoints();
    165 
    166  is(
    167    getXHRBreakpointsElements(dbg).length,
    168    0,
    169    "XHR breakpoints display list is empty"
    170  );
    171 
    172  persistedXHRBreakpoints = await asyncStore.xhrBreakpoints;
    173  is(
    174    persistedXHRBreakpoints.length,
    175    0,
    176    "Check that there are no persisted XHR breakpoints"
    177  );
    178 
    179  info("Trying adding a breakpoint with an empty path");
    180  const plusIcon = findElementWithSelector(dbg, ".xhr-breakpoints-pane .plus");
    181  if (plusIcon) {
    182    plusIcon.click();
    183  }
    184  findElementWithSelector(dbg, ".xhr-input-url").value = "";
    185  findElementWithSelector(dbg, ".xhr-input-method").value = "get";
    186 
    187  pressKey(dbg, "Enter");
    188  persistedXHRBreakpoints = await asyncStore.xhrBreakpoints;
    189  is(
    190    persistedXHRBreakpoints.length,
    191    0,
    192    "No breakpoint should be added when the path is empty"
    193  );
    194 });
    195 
    196 async function addXHRBreakpoint(dbg, text, method) {
    197  info(`Adding a XHR breakpoint for pattern ${text} and method ${method}`);
    198 
    199  const plusIcon = findElementWithSelector(dbg, ".xhr-breakpoints-pane .plus");
    200  if (plusIcon) {
    201    plusIcon.click();
    202  }
    203  findElementWithSelector(dbg, ".xhr-input-url").focus();
    204  type(dbg, text);
    205 
    206  if (method) {
    207    findElementWithSelector(dbg, ".xhr-input-method").value = method;
    208  }
    209 
    210  pressKey(dbg, "Enter");
    211 
    212  await waitForDispatch(dbg.store, "SET_XHR_BREAKPOINT");
    213 }
    214 
    215 async function removeXHRBreakpoint(dbg, index) {
    216  info("Removing a XHR breakpoint");
    217 
    218  const closeButtons = dbg.win.document.querySelectorAll(
    219    ".xhr-breakpoints-pane .close-btn"
    220  );
    221  if (closeButtons[index]) {
    222    closeButtons[index].click();
    223  }
    224 
    225  await waitForDispatch(dbg.store, "REMOVE_XHR_BREAKPOINT");
    226 }
    227 
    228 function getXHRBreakpointsElements(dbg) {
    229  return [
    230    ...dbg.win.document.querySelectorAll(
    231      ".xhr-breakpoints-pane .xhr-container"
    232    ),
    233  ];
    234 }
    235 
    236 function getXHRBreakpointLabels(elements) {
    237  return elements.map(element => element.title);
    238 }
    239 
    240 function getXHRBreakpointCheckbox(dbg) {
    241  return findElementWithSelector(
    242    dbg,
    243    ".xhr-breakpoints-pane .breakpoints-exceptions input"
    244  );
    245 }
    246 
    247 async function clickPauseOnAny(dbg, expectedEvent) {
    248  getXHRBreakpointCheckbox(dbg).click();
    249  await waitForDispatch(dbg.store, expectedEvent);
    250 }
    251 
    252 async function assertDebuggerTabHighlight(dbg) {
    253  await waitUntil(() => !dbg.toolbox.isHighlighted("jsdebugger"));
    254  ok(true, "Debugger is no longer highlighted after resume");
    255 }