summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_webconsole_context_menu_reveal_in_inspector.js
blob: 4925b03a419610d4f6dbc3754f1eddd76c89bec8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

// Test the "Reveal in Inspector" menu item of the webconsole is enabled only when
// clicking on HTML elements attached to the DOM. Also check that clicking the menu
// item or using the access-key Q does select the node in the inspector.

"use strict";

const TEST_URI = `data:text/html;charset=utf-8,<!DOCTYPE html>
  <!DOCTYPE html>
  <html>
    <body></body>
    <script>
      console.log("foo");
      console.log({hello: "world"});
      console.log(document.createElement("span"));
      console.log(document.body.appendChild(document.createElement("div")));
      console.log(document.body.appendChild(document.createTextNode("test-text")));
      console.log(document.querySelectorAll('html'));
    </script>
  </html>
`;
const revealInInspectorMenuItemId = "#console-menu-open-node";

add_task(async function () {
  const hud = await openNewTabAndConsole(TEST_URI);

  const msgWithText = await waitFor(() => findConsoleAPIMessage(hud, `foo`));
  const msgWithObj = await waitFor(() => findConsoleAPIMessage(hud, `Object`));
  const nonDomEl = await waitFor(() =>
    findMessagePartByType(hud, {
      text: `<span>`,
      typeSelector: ".console-api",
      partSelector: ".objectBox-node",
    })
  );

  const domEl = await waitFor(() =>
    findMessagePartByType(hud, {
      text: `<div>`,
      typeSelector: ".console-api",
      partSelector: ".objectBox-node",
    })
  );
  const domTextEl = await waitFor(() =>
    findMessagePartByType(hud, {
      text: `test-text`,
      typeSelector: ".console-api",
      partSelector: ".objectBox-textNode",
    })
  );
  const domElCollection = await waitFor(() =>
    findMessagePartByType(hud, {
      text: `html`,
      typeSelector: ".console-api",
      partSelector: ".objectBox-node",
    })
  );

  info("Check `Reveal in Inspector` is not visible for strings");
  await testRevealInInspectorDisabled(hud, msgWithText);

  info("Check `Reveal in Inspector` is not visible for objects");
  await testRevealInInspectorDisabled(hud, msgWithObj);

  info("Check `Reveal in Inspector` is not visible for disconnected nodes");
  await testRevealInInspectorDisabled(hud, nonDomEl);

  info("Check `Reveal in Inspector` for a single connected node");
  await testRevealInInspector(hud, domEl, "div", false);

  info("Check `Reveal in Inspector` for a connected text element");
  await testRevealInInspector(hud, domTextEl, "#text", false);

  info("Check `Reveal in Inspector` for a collection of elements");
  await testRevealInInspector(hud, domElCollection, "html", false);

  info("`Reveal in Inspector` by using the access-key Q");
  await testRevealInInspector(hud, domEl, "div", true);
});

async function testRevealInInspector(hud, element, tag, accesskey) {
  if (
    !accesskey &&
    AppConstants.platform == "macosx" &&
    Services.prefs.getBoolPref("widget.macos.native-context-menus", false)
  ) {
    info(
      "Not testing accesskey behaviour since we can't use synthesized keypresses in macOS native menus."
    );
    return;
  }
  const toolbox = hud.toolbox;

  // Loading the inspector panel at first, to make it possible to listen for
  // new node selections
  await toolbox.loadTool("inspector");
  const inspector = toolbox.getPanel("inspector");

  const menuPopup = await openContextMenu(hud, element);
  const revealInInspectorMenuItem = menuPopup.querySelector(
    revealInInspectorMenuItemId
  );
  Assert.notStrictEqual(
    revealInInspectorMenuItem,
    null,
    "There is the `Reveal in Inspector` menu item"
  );

  const onInspectorSelected = toolbox.once("inspector-selected");
  const onInspectorUpdated = inspector.once("inspector-updated");
  const onNewNode = toolbox.selection.once("new-node-front");

  if (accesskey) {
    info("Clicking on `Reveal in Inspector` menu item");
    menuPopup.activateItem(revealInInspectorMenuItem);
  } else {
    info("Using access-key Q to `Reveal in Inspector`");
    await synthesizeKeyShortcut("Q");
  }

  await onInspectorSelected;
  await onInspectorUpdated;
  const nodeFront = await onNewNode;

  ok(true, "Inspector selected and new node got selected");
  is(nodeFront.displayName, tag, "The expected node was selected");

  await openConsole();
}

async function testRevealInInspectorDisabled(hud, element) {
  info("Check 'Reveal in Inspector' is not in the menu");
  const menuPopup = await openContextMenu(hud, element);
  const revealInInspectorMenuItem = menuPopup.querySelector(
    revealInInspectorMenuItemId
  );
  ok(
    !revealInInspectorMenuItem,
    `"Reveal in Inspector" is not available for messages with no HTML DOM elements`
  );
  await hideContextMenu(hud);
}