tor-browser

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

browser_dbg-inline-preview.js (8662B)


      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 // Test checking inline preview feature
      6 
      7 "use strict";
      8 
      9 add_task(async function testInlinePreviews() {
     10  await pushPref("devtools.debugger.features.inline-preview", true);
     11 
     12  const dbg = await initDebugger(
     13    "doc-inline-preview.html",
     14    "inline-preview.js"
     15  );
     16  await selectSource(dbg, "inline-preview.js");
     17 
     18  // Reload the page to trigger the pause at the debugger statement
     19  // in the block on line 66.
     20  const onReload = reload(dbg);
     21  await waitForPaused(dbg);
     22 
     23  info("Check that debugger is paused in the block scope");
     24  await assertPausedAtSourceAndLine(
     25    dbg,
     26    findSource(dbg, "inline-preview.js").id,
     27    66
     28  );
     29 
     30  await assertInlinePreviews(
     31    dbg,
     32    [
     33      { previews: [{ identifier: "x:", value: "1" }], line: 63 },
     34      { previews: [{ identifier: "x:", value: "2" }], line: 65 },
     35    ],
     36    // `block` is passed as the function name here because
     37    // we are testing a block scope
     38    "block"
     39  );
     40 
     41  await resume(dbg);
     42 
     43  await assertInlinePreviews(
     44    dbg,
     45    [
     46      { previews: [{ identifier: "x:", value: "1" }], line: 63 },
     47      {
     48        previews: [{ identifier: "dict:", value: 'Object { hello: "world" }' }],
     49        line: 68,
     50      },
     51      { previews: [{ identifier: "key:", value: '"hello"' }], line: 69 },
     52    ],
     53    "block"
     54  );
     55 
     56  await resume(dbg);
     57  await onReload;
     58 
     59  await invokeFunctionAndAssertInlinePreview({
     60    dbg,
     61    fnName: "checkValues",
     62    expectedInlinePreviews: [
     63      { previews: [{ identifier: "a:", value: '""' }], line: 2 },
     64      { previews: [{ identifier: "b:", value: "false" }], line: 3 },
     65      { previews: [{ identifier: "c:", value: "undefined" }], line: 4 },
     66      { previews: [{ identifier: "d:", value: "null" }], line: 5 },
     67      { previews: [{ identifier: "e:", value: "Array []" }], line: 6 },
     68      { previews: [{ identifier: "f:", value: "Object { }" }], line: 7 },
     69      {
     70        previews: [{ identifier: "reg:", value: "/^\\p{RGI_Emoji}$/v" }],
     71        line: 8,
     72      },
     73      {
     74        previews: [{ identifier: "obj:", value: "Object { foo: 1 }" }],
     75        line: 9,
     76      },
     77      {
     78        previews: [
     79          {
     80            identifier: "bs:",
     81            value: "Array(101) [ {…}, {…}, {…}, … ]",
     82          },
     83        ],
     84        line: 13,
     85      },
     86    ],
     87  });
     88 
     89  await invokeFunctionAndAssertInlinePreview({
     90    dbg,
     91    fnName: "columnWise",
     92    expectedInlinePreviews: [
     93      { previews: [{ identifier: "a:", value: '"a"' }], line: 21 },
     94      { previews: [{ identifier: "b:", value: '"b"' }], line: 22 },
     95      { previews: [{ identifier: "c:", value: '"c"' }], line: 23 },
     96    ],
     97  });
     98 
     99  // Check that referencing an object property previews the property, not the object (bug 1599917)
    100  await invokeFunctionAndAssertInlinePreview({
    101    dbg,
    102    fnName: "objectProperties",
    103    expectedInlinePreviews: [
    104      {
    105        previews: [
    106          {
    107            identifier: "obj:",
    108            value: 'Object { hello: "world", a: {…} }',
    109          },
    110        ],
    111        line: 29,
    112      },
    113      { previews: [{ identifier: "obj.hello:", value: '"world"' }], line: 30 },
    114      { previews: [{ identifier: "obj.a.b:", value: '"c"' }], line: 31 },
    115    ],
    116  });
    117 
    118  await invokeFunctionAndAssertInlinePreview({
    119    dbg,
    120    fnName: "classProperties",
    121    expectedInlinePreviews: [
    122      {
    123        previews: [
    124          { identifier: "i:", value: "2" },
    125          { identifier: "this.x:", value: "1" },
    126        ],
    127        line: 43,
    128      },
    129      {
    130        previews: [
    131          { identifier: "self:", value: `Object { x: 1, #privateVar: 2 }` },
    132        ],
    133        line: 44,
    134      },
    135    ],
    136  });
    137 
    138  // Checks __proto__ variable/argument are displayed
    139  await invokeFunctionAndAssertInlinePreview({
    140    dbg,
    141    fnName: "protoArg",
    142    fnArgs: ["tomato"],
    143    expectedInlinePreviews: [
    144      {
    145        previews: [{ identifier: "__proto__:", value: `"tomato"` }],
    146        line: 74,
    147      },
    148    ],
    149  });
    150  await invokeFunctionAndAssertInlinePreview({
    151    dbg,
    152    fnName: "protoVar",
    153    expectedInlinePreviews: [
    154      {
    155        previews: [{ identifier: "__proto__:", value: `"lemon"` }],
    156        line: 79,
    157      },
    158    ],
    159  });
    160 
    161  await invokeFunctionAndAssertInlinePreview({
    162    dbg,
    163    fnName: "innerBlockHoistedFuncDecl",
    164    expectedInlinePreviews: [
    165      { previews: [{ identifier: "foo:", value: "function foo()" }], line: 90 },
    166    ],
    167  });
    168 
    169  // Check inline previews for values within a module script
    170  await invokeFunctionAndAssertInlinePreview({
    171    dbg,
    172    fnName: "runInModule",
    173    expectedInlinePreviews: [
    174      { previews: [{ identifier: "val:", value: "4" }], line: 20 },
    175      { previews: [{ identifier: "ids:", value: "Array [ 1, 2 ]" }], line: 21 },
    176    ],
    177  });
    178 
    179  // Make sure the next breakpoint source is selected, parsed etc...
    180  // Bug 1974236: This should not be necessary.
    181  await selectSource(dbg, "inline-preview.js");
    182 
    183  // Checks that open in inspector button works in inline preview
    184  invokeInTab("btnClick");
    185  await assertInlinePreviews(
    186    dbg,
    187    [{ previews: [{ identifier: "btn:", value: "button" }], line: 53 }],
    188    "onBtnClick"
    189  );
    190 
    191  await checkInspectorIcon(dbg);
    192 
    193  await dbg.toolbox.selectTool("jsdebugger");
    194 
    195  await waitForSelectedSource(dbg, "inline-preview.js");
    196 
    197  // Check preview of event ( event.target should be clickable )
    198  // onBtnClick function in inline-preview.js
    199  await assertInlinePreviews(
    200    dbg,
    201    [
    202      {
    203        previews: [
    204          {
    205            identifier: "event:",
    206            value: "click { target: button, buttons: 0, clientX: 0, … }",
    207          },
    208        ],
    209        line: 58,
    210      },
    211    ],
    212    "onBtnClick"
    213  );
    214  await checkInspectorIcon(dbg);
    215  await resume(dbg);
    216 
    217  await dbg.toolbox.closeToolbox();
    218 });
    219 
    220 add_task(async function testInlinePreviewsWithExplicitResourceManagement() {
    221  await pushPref("devtools.debugger.features.inline-preview", true);
    222  // javascript.options.experimental.explicit_resource_management is set to true, but it's
    223  // only supported on Nightly at the moment, so only check for SuppressedError if
    224  // they're supported.
    225  if (!AppConstants.ENABLE_EXPLICIT_RESOURCE_MANAGEMENT) {
    226    return;
    227  }
    228  const dbg = await initDebugger("doc-inline-preview.html");
    229 
    230  const onPaused = waitForPaused(dbg);
    231  dbg.commands.scriptCommand.execute(
    232    `
    233    function explicitResourceManagement() {
    234      using erm = {
    235        [Symbol.dispose]() {},
    236        foo: 42
    237      };
    238      console.log(erm.foo);
    239      debugger;
    240    }; explicitResourceManagement();`,
    241    {}
    242  );
    243  await onPaused;
    244 
    245  await invokeFunctionAndAssertInlinePreview({
    246    dbg,
    247    fnName: "explicitResourceManagement",
    248    expectedInlinePreviews: [
    249      {
    250        previews: [
    251          {
    252            identifier: "erm:",
    253            value: `Object { foo: 42, Symbol("Symbol.dispose"): Symbol.dispose() }`,
    254          },
    255        ],
    256        line: 3,
    257      },
    258      {
    259        previews: [
    260          {
    261            identifier: "erm.foo:",
    262            value: "42",
    263          },
    264        ],
    265        line: 7,
    266      },
    267    ],
    268  });
    269 
    270  await dbg.toolbox.closeToolbox();
    271 });
    272 
    273 async function invokeFunctionAndAssertInlinePreview({
    274  dbg,
    275  fnName,
    276  fnArgs = [],
    277  expectedInlinePreviews,
    278 }) {
    279  invokeInTab(fnName, ...fnArgs);
    280  await assertInlinePreviews(dbg, expectedInlinePreviews, fnName);
    281  await resume(dbg);
    282 }
    283 
    284 async function checkInspectorIcon(dbg) {
    285  const node = await waitForElement(dbg, "inlinePreviewOpenInspector");
    286 
    287  // Ensure hovering over button highlights the node in content pane
    288  const view = node.ownerDocument.defaultView;
    289  const { toolbox } = dbg;
    290 
    291  // Setup a promise that will set `nodeHighlighted` to the highlighter-shown
    292  // event payload.
    293  let nodeHighlighted;
    294  toolbox
    295    .getHighlighter()
    296    .waitForHighlighterShown()
    297    .then(event => {
    298      nodeHighlighted = event;
    299    });
    300 
    301  info("Wait for node to be highlighted");
    302  const nodeFront = await waitFor(() => {
    303    // The test intermittently fails when we try to mouseover only once.
    304    // Setup a simple polling mechanism to avoid this. See Bug 1607636.
    305    if (nodeHighlighted) {
    306      return nodeHighlighted.nodeFront;
    307    }
    308 
    309    EventUtils.synthesizeMouseAtCenter(node, { type: "mousemove" }, view);
    310    return false;
    311  });
    312 
    313  is(nodeFront.displayName, "button", "The correct node was highlighted");
    314 
    315  // Ensure panel changes when button is clicked
    316  const onInspectorPanelLoad = waitForInspectorPanelChange(dbg);
    317  node.click();
    318  await onInspectorPanelLoad;
    319 
    320  await resume(dbg);
    321 }