tor-browser

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

head_devtools_inspector_sidebar.js (7033B)


      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 /* exported getExtensionSidebarActors, expectNoSuchActorIDs,
      6            waitForObjectInspector, testSetExpressionSidebarPanel, assertTreeView,
      7            assertObjectInspector, moveMouseOnObjectInspectorDOMNode,
      8            moveMouseOnPanelCenter, clickOpenInspectorIcon */
      9 
     10 "use strict";
     11 
     12 const ACCORDION_LABEL_SELECTOR = ".accordion-header-label";
     13 const ACCORDION_CONTENT_SELECTOR = ".accordion-content";
     14 
     15 // Retrieve the array of all the objectValueGrip actors from the
     16 // inspector extension sidebars state
     17 // (used in browser_ext_devtools_panels_elements_sidebar.js).
     18 function getExtensionSidebarActors(inspector) {
     19  const state = inspector.store.getState();
     20 
     21  const actors = [];
     22 
     23  for (const sidebarId of Object.keys(state.extensionsSidebar)) {
     24    const sidebarState = state.extensionsSidebar[sidebarId];
     25 
     26    if (
     27      sidebarState.viewMode === "object-value-grip-view" &&
     28      sidebarState.objectValueGrip &&
     29      sidebarState.objectValueGrip.actor
     30    ) {
     31      actors.push(sidebarState.objectValueGrip.actor);
     32    }
     33  }
     34 
     35  return actors;
     36 }
     37 
     38 // Test that the specified objectValueGrip actors have been released
     39 // on the remote debugging server
     40 // (used in browser_ext_devtools_panels_elements_sidebar.js).
     41 async function expectNoSuchActorIDs(client, actors) {
     42  info(`Test that all the objectValueGrip actors have been released`);
     43  for (const actor of actors) {
     44    await Assert.rejects(
     45      client.request({ to: actor, type: "requestTypes" }),
     46      err => err.message == `No such actor for ID: ${actor}`
     47    );
     48  }
     49 }
     50 
     51 function waitForObjectInspector(panelDoc, waitForNodeWithType = "object") {
     52  const selector = `.object-inspector .objectBox-${waitForNodeWithType}`;
     53  return TestUtils.waitForCondition(() => {
     54    return !!panelDoc.querySelectorAll(selector).length;
     55  }, `Wait for objectInspector's node type "${waitForNodeWithType}" to be loaded`);
     56 }
     57 
     58 // Helper function used inside the sidebar.setExtensionPage test case.
     59 async function testSetExtensionPageSidebarPanel(panelDoc, expectedURL) {
     60  const selector = "iframe.inspector-extension-sidebar-page";
     61  const iframesCount = await TestUtils.waitForCondition(() => {
     62    return panelDoc.querySelectorAll(selector).length;
     63  }, "Wait for the extension page iframe");
     64 
     65  is(
     66    iframesCount,
     67    1,
     68    "Got the expected number of iframes in the extension panel"
     69  );
     70 
     71  const iframeWindow = panelDoc.querySelector(selector).contentWindow;
     72  await TestUtils.waitForCondition(() => {
     73    return (
     74      iframeWindow.document.readyState === "complete" &&
     75      iframeWindow.location.href != "about:blank"
     76    );
     77  }, "Wait for the extension page iframe to complete to load");
     78 
     79  is(
     80    iframeWindow.location.href,
     81    expectedURL,
     82    "Got the expected url in the extension panel iframe"
     83  );
     84 }
     85 
     86 // Helper function used inside the sidebar.setObjectValueGrip test case.
     87 async function testSetExpressionSidebarPanel(panel, expected) {
     88  const { nodesLength, propertiesNames, rootTitle } = expected;
     89 
     90  await waitForObjectInspector(panel);
     91 
     92  const objectInspectors = [...panel.querySelectorAll(".tree")];
     93  is(
     94    objectInspectors.length,
     95    1,
     96    "There is the expected number of object inspectors"
     97  );
     98  const [objectInspector] = objectInspectors;
     99 
    100  await TestUtils.waitForCondition(() => {
    101    return objectInspector.querySelectorAll(".node").length >= nodesLength;
    102  }, "Wait the objectInspector to have been fully rendered");
    103 
    104  const oiNodes = objectInspector.querySelectorAll(".node");
    105 
    106  is(
    107    oiNodes.length,
    108    nodesLength,
    109    "Got the expected number of nodes in the tree"
    110  );
    111  const propertiesNodes = [
    112    ...objectInspector.querySelectorAll(".object-label"),
    113  ].map(el => el.textContent);
    114  is(
    115    JSON.stringify(propertiesNodes),
    116    JSON.stringify(propertiesNames),
    117    "Got the expected property names"
    118  );
    119 
    120  if (rootTitle) {
    121    // Also check that the ObjectInspector is rendered inside
    122    // an Accordion component with the expected title.
    123    const accordion = panel.querySelector(".accordion");
    124 
    125    ok(accordion, "Got an Accordion component as expected");
    126 
    127    is(
    128      accordion.querySelector(ACCORDION_CONTENT_SELECTOR).firstChild,
    129      objectInspector,
    130      "The ObjectInspector should be inside the Accordion content"
    131    );
    132 
    133    is(
    134      accordion.querySelector(ACCORDION_LABEL_SELECTOR).textContent,
    135      rootTitle,
    136      "The Accordion has the expected label"
    137    );
    138  } else {
    139    // Also check that there is no Accordion component rendered
    140    // inside the sidebar panel.
    141    ok(
    142      !panel.querySelector(".accordion"),
    143      "Got no Accordion component as expected"
    144    );
    145  }
    146 }
    147 
    148 function assertTreeView(panelDoc, expectedContent) {
    149  const { expectedTreeTables, expectedStringCells, expectedNumberCells } =
    150    expectedContent;
    151 
    152  if (expectedTreeTables) {
    153    is(
    154      panelDoc.querySelectorAll("table.treeTable").length,
    155      expectedTreeTables,
    156      "The panel document contains the expected number of TreeView components"
    157    );
    158  }
    159 
    160  if (expectedStringCells) {
    161    is(
    162      panelDoc.querySelectorAll("table.treeTable .stringCell").length,
    163      expectedStringCells,
    164      "The panel document contains the expected number of string cells."
    165    );
    166  }
    167 
    168  if (expectedNumberCells) {
    169    is(
    170      panelDoc.querySelectorAll("table.treeTable .numberCell").length,
    171      expectedNumberCells,
    172      "The panel document contains the expected number of number cells."
    173    );
    174  }
    175 }
    176 
    177 async function assertObjectInspector(panelDoc, expectedContent) {
    178  const { expectedDOMNodes, expectedOpenInspectors } = expectedContent;
    179 
    180  // Get and verify the DOMNode and the "open inspector"" icon
    181  // rendered inside the ObjectInspector.
    182  const nodes = panelDoc.querySelectorAll(".objectBox-node");
    183  const nodeOpenInspectors = panelDoc.querySelectorAll(
    184    ".objectBox-node .open-inspector"
    185  );
    186 
    187  is(
    188    nodes.length,
    189    expectedDOMNodes,
    190    "Found the expected number of ObjectInspector DOMNodes"
    191  );
    192  is(
    193    nodeOpenInspectors.length,
    194    expectedOpenInspectors,
    195    "Found the expected nuber of open-inspector icons inside the ObjectInspector"
    196  );
    197 }
    198 
    199 function moveMouseOnObjectInspectorDOMNode(panelDoc, nodeIndex = 0) {
    200  const nodes = panelDoc.querySelectorAll(".objectBox-node");
    201  const node = nodes[nodeIndex];
    202 
    203  ok(node, "Found the ObjectInspector DOMNode");
    204 
    205  EventUtils.synthesizeMouseAtCenter(
    206    node,
    207    { type: "mousemove" },
    208    node.ownerDocument.defaultView
    209  );
    210 }
    211 
    212 function moveMouseOnPanelCenter(panelDoc) {
    213  EventUtils.synthesizeMouseAtCenter(
    214    panelDoc,
    215    { type: "mousemove" },
    216    panelDoc.window
    217  );
    218 }
    219 
    220 function clickOpenInspectorIcon(panelDoc, nodeIndex = 0) {
    221  const nodes = panelDoc.querySelectorAll(".objectBox-node .open-inspector");
    222  const node = nodes[nodeIndex];
    223 
    224  ok(node, "Found the ObjectInspector open-inspector icon");
    225 
    226  node.click();
    227 }