tor-browser

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

browser_dbg-breakpoints-popup.js (7407B)


      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 // Verify that we hit breakpoints on popups
      6 
      7 "use strict";
      8 
      9 const TEST_URI = "https://example.org/document-builder.sjs?html=main page";
     10 const POPUP_URL = `https://example.com/document-builder.sjs?html=${escape(`popup for breakpoints
     11  <script>
     12    var paused = true;
     13    console.log('popup');
     14    paused = false;
     15  </script>
     16 `)}`;
     17 const POPUP_DEBUGGER_STATEMENT_URL = `https://example.com/document-builder.sjs?html=${escape(`popup with debugger;
     18  <script>
     19    var paused = true;
     20    debugger;
     21    paused = false;
     22  </script>
     23 `)}`;
     24 
     25 function isPopupPaused(popupBrowsingContext) {
     26  return SpecialPowers.spawn(popupBrowsingContext, [], function () {
     27    return content.wrappedJSObject.paused;
     28  });
     29 }
     30 
     31 async function openPopup(popupUrl, browser = gBrowser.selectedBrowser) {
     32  const onPopupTabSelected = BrowserTestUtils.waitForEvent(
     33    gBrowser.tabContainer,
     34    "TabSelect"
     35  );
     36  const popupBrowsingContext = await SpecialPowers.spawn(
     37    browser,
     38    [popupUrl],
     39    function (url) {
     40      const popup = content.open(url);
     41      return popup.browsingContext;
     42    }
     43  );
     44  await onPopupTabSelected;
     45  is(
     46    gBrowser.selectedBrowser.browsingContext,
     47    popupBrowsingContext,
     48    "The popup is the selected tab"
     49  );
     50  return popupBrowsingContext;
     51 }
     52 
     53 async function closePopup(browsingContext) {
     54  const onPreviousTabSelected = BrowserTestUtils.waitForEvent(
     55    gBrowser.tabContainer,
     56    "TabSelect"
     57  );
     58  await SpecialPowers.spawn(browsingContext, [], function () {
     59    content.close();
     60  });
     61  await onPreviousTabSelected;
     62 }
     63 
     64 add_task(async function testPausedByBreakpoint() {
     65  await pushPref("devtools.popups.debug", true);
     66 
     67  info("Test breakpoints set in popup scripts");
     68  const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
     69 
     70  info("Open the popup in order to be able to set a breakpoint");
     71  const firstPopupBrowsingContext = await openPopup(POPUP_URL);
     72 
     73  let source = await waitForSource(dbg, POPUP_URL);
     74 
     75  await selectSource(dbg, source);
     76  await addBreakpoint(dbg, source, 4);
     77 
     78  info("Now close and reopen the popup");
     79  let onToolboxSwitchedToTab = dbg.toolbox.once("switched-host-to-tab");
     80  await closePopup(firstPopupBrowsingContext);
     81  await onToolboxSwitchedToTab;
     82 
     83  info("Re-open the popup");
     84  onToolboxSwitchedToTab = dbg.toolbox.once("switched-host-to-tab");
     85  const popupBrowsingContext = await openPopup(POPUP_URL);
     86  await onToolboxSwitchedToTab;
     87  await waitForPaused(dbg);
     88  is(
     89    await isPopupPaused(popupBrowsingContext),
     90    true,
     91    "The popup is really paused"
     92  );
     93 
     94  source = await waitForSource(dbg, POPUP_URL);
     95  await assertPausedAtSourceAndLine(dbg, source.id, 4);
     96 
     97  await resume(dbg);
     98  is(
     99    await isPopupPaused(popupBrowsingContext),
    100    false,
    101    "The popup resumed its execution"
    102  );
    103 });
    104 
    105 add_task(async function testPausedByDebuggerStatement() {
    106  info("Test debugger statements in popup scripts");
    107  const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
    108 
    109  info("Open a popup with a debugger statement");
    110  const popupBrowsingContext = await openPopup(POPUP_DEBUGGER_STATEMENT_URL);
    111  await waitForPaused(dbg);
    112  is(
    113    await isPopupPaused(popupBrowsingContext),
    114    true,
    115    "The popup is really paused"
    116  );
    117 
    118  const source = findSource(dbg, POPUP_DEBUGGER_STATEMENT_URL);
    119  await assertPausedAtSourceAndLine(dbg, source.id, 4);
    120 
    121  await resume(dbg);
    122  is(
    123    await isPopupPaused(popupBrowsingContext),
    124    false,
    125    "The popup resumed its execution"
    126  );
    127 });
    128 
    129 add_task(async function testPausedInTwoPopups() {
    130  info("Test being paused in two popup at the same time");
    131  const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
    132 
    133  info("Open the popup in order to be able to set a breakpoint");
    134  const browser = gBrowser.selectedBrowser;
    135  const popupBrowsingContext = await openPopup(POPUP_URL);
    136 
    137  const source = await waitForSource(dbg, POPUP_URL);
    138 
    139  await selectSource(dbg, source);
    140  await addBreakpoint(dbg, source, 4);
    141 
    142  info("Now close and reopen the popup");
    143  await closePopup(popupBrowsingContext);
    144 
    145  info("Open a first popup which will hit the breakpoint");
    146  const firstPopupBrowsingContext = await openPopup(POPUP_URL);
    147  await waitForPaused(dbg);
    148  const { targetCommand } = dbg.commands;
    149  const firstTarget = targetCommand
    150    .getAllTargets([targetCommand.TYPES.FRAME])
    151    .find(targetFront => targetFront.url == POPUP_URL);
    152  is(
    153    firstTarget.browsingContextID,
    154    firstPopupBrowsingContext.id,
    155    "The popup target matches the popup BrowsingContext"
    156  );
    157  const firstThread = (await firstTarget.getFront("thread")).actorID;
    158  is(
    159    dbg.selectors.getCurrentThread(),
    160    firstThread,
    161    "The popup thread is automatically selected on pause"
    162  );
    163  is(
    164    await isPopupPaused(firstPopupBrowsingContext),
    165    true,
    166    "The first popup is really paused"
    167  );
    168 
    169  info("Open a second popup which will also hit the breakpoint");
    170  let onAvailable;
    171  const onNewTarget = new Promise(resolve => {
    172    onAvailable = ({ targetFront }) => {
    173      if (
    174        targetFront.url == POPUP_URL &&
    175        targetFront.browsingContextID != firstPopupBrowsingContext.id
    176      ) {
    177        targetCommand.unwatchTargets({
    178          types: [targetCommand.TYPES.FRAME],
    179          onAvailable,
    180        });
    181        resolve(targetFront);
    182      }
    183    };
    184  });
    185  await targetCommand.watchTargets({
    186    types: [targetCommand.TYPES.FRAME],
    187    onAvailable,
    188  });
    189  const secondPopupBrowsingContext = await openPopup(POPUP_URL, browser);
    190  info("Wait for second popup's target");
    191  const popupTarget = await onNewTarget;
    192  is(
    193    popupTarget.browsingContextID,
    194    secondPopupBrowsingContext.id,
    195    "The new target matches the popup WindowGlobal"
    196  );
    197  const secondThread = (await popupTarget.getFront("thread")).actorID;
    198  await waitForPausedThread(dbg, secondThread);
    199  is(
    200    dbg.selectors.getCurrentThread(),
    201    secondThread,
    202    "The second popup thread is automatically selected on pause"
    203  );
    204  is(
    205    await isPopupPaused(secondPopupBrowsingContext),
    206    true,
    207    "The second popup is really paused"
    208  );
    209 
    210  info("Resume the execution of the second popup");
    211  await resume(dbg);
    212  is(
    213    await isPopupPaused(secondPopupBrowsingContext),
    214    false,
    215    "The second popup resumed its execution"
    216  );
    217  is(
    218    await isPopupPaused(firstPopupBrowsingContext),
    219    true,
    220    "The first popup is still paused"
    221  );
    222 
    223  info("Resume the execution of the first popup");
    224  await dbg.actions.selectThread(firstThread);
    225  await resume(dbg);
    226  is(
    227    await isPopupPaused(firstPopupBrowsingContext),
    228    false,
    229    "The first popup resumed its execution"
    230  );
    231 });
    232 
    233 add_task(async function testClosingOriginalTab() {
    234  info(
    235    "Test closing the toolbox on the original tab while the popup is kept open"
    236  );
    237  const dbg = await initDebuggerWithAbsoluteURL(TEST_URI);
    238  await dbg.toolbox.selectTool("webconsole");
    239 
    240  info("Open a popup");
    241  const originalTab = gBrowser.selectedTab;
    242  await openPopup("about:blank");
    243  await wait(1000);
    244  const popupTab = gBrowser.selectedTab;
    245  gBrowser.selectedTab = originalTab;
    246  info("Close the toolbox from the original tab");
    247  await dbg.toolbox.closeToolbox();
    248  await wait(1000);
    249  info("Re-select the popup");
    250  gBrowser.selectedTab = popupTab;
    251  await wait(1000);
    252 });