summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-custom-formatters.js
blob: 3c983ef77ec98d146e777afe0ed3feb73ce6ae2b (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
145
146
147
148
149
150
151
152
153
154
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Check display of custom formatters in debugger.
const TEST_FILENAME = `doc_dbg-custom-formatters.html`;
const TEST_FUNCTION_NAME = "pauseWithCustomFormattedObject";
const CUSTOM_FORMATTED_BODY = "customFormattedBody";
const VARIABLE_NAME = "xyz";

add_task(async function () {
  await pushPref("devtools.custom-formatters.enabled", true);

  const dbg = await initDebugger(TEST_FILENAME);
  await selectSource(dbg, TEST_FILENAME);

  info(
    "Test that custom formatted objects are displayed as expected in the Watch Expressions panel"
  );
  await addExpression(dbg, `({customFormatHeaderAndBody: "body"})`);
  const expressionsElements = findAllElements(dbg, "expressionNodes");
  is(expressionsElements.length, 1);

  const customFormattedElement = expressionsElements[0];

  const headerJsonMlNode =
    customFormattedElement.querySelector(".objectBox-jsonml");
  is(
    headerJsonMlNode.innerText,
    "CUSTOM",
    "The object is rendered with a custom formatter"
  );

  is(
    customFormattedElement.querySelector(".arrow"),
    null,
    "The expression is not expandable…"
  );
  const customFormattedElementArrow =
    customFormattedElement.querySelector(".collapse-button");
  ok(customFormattedElementArrow, "… but the custom formatter is");

  info("Expanding the Object");
  const onBodyRendered = waitFor(
    () =>
      !!customFormattedElement.querySelector(
        ".objectBox-jsonml-body-wrapper .objectBox-jsonml"
      )
  );

  customFormattedElementArrow.click();
  await onBodyRendered;

  ok(
    customFormattedElement
      .querySelector(".collapse-button")
      .classList.contains("expanded"),
    "The arrow of the node has the expected class after clicking on it"
  );

  const bodyJsonMlNode = customFormattedElement.querySelector(
    ".objectBox-jsonml-body-wrapper > .objectBox-jsonml"
  );
  ok(bodyJsonMlNode, "The body is custom formatted");
  is(bodyJsonMlNode?.textContent, "body", "The body text is correct");

  info("Check that custom formatters are displayed in Scopes panel");

  // The function has a debugger statement that will pause the debugger
  invokeInTab(TEST_FUNCTION_NAME);

  info("Wait for the debugger to be paused");
  await waitForPaused(dbg);

  info(
    `Check that '${VARIABLE_NAME}' is in the scopes panel and custom formatted`
  );
  const index = 4;
  is(
    getScopeNodeLabel(dbg, index),
    VARIABLE_NAME,
    `Got '${VARIABLE_NAME}' at the expected position`
  );
  const scopeXElement = findElement(dbg, "scopeValue", index);
  is(
    scopeXElement.innerText,
    "CUSTOM",
    `'${VARIABLE_NAME}' is custom formatted in the scopes panel`
  );
  const xArrow = scopeXElement.querySelector(".collapse-button");
  ok(xArrow, `'${VARIABLE_NAME}' is expandable`);

  info(`Expanding '${VARIABLE_NAME}'`);
  const onScopeBodyRendered = waitFor(
    () =>
      !!scopeXElement.querySelector(
        ".objectBox-jsonml-body-wrapper .objectBox-jsonml"
      )
  );

  xArrow.click();
  await onScopeBodyRendered;
  const scopeXBodyJsonMlNode = scopeXElement.querySelector(
    ".objectBox-jsonml-body-wrapper > .objectBox-jsonml"
  );
  ok(scopeXBodyJsonMlNode, "The scope item body is custom formatted");
  is(
    scopeXBodyJsonMlNode?.textContent,
    CUSTOM_FORMATTED_BODY,
    "The scope item body text is correct"
  );

  await resume(dbg);

  info("Check that custom formatters are displayed in the Debugger tooltip");

  // The function has a debugger statement that will pause the debugger
  invokeInTab(TEST_FUNCTION_NAME);
  await waitForPaused(dbg);

  await assertPreviewTextValue(dbg, 26, 16, {
    expression: VARIABLE_NAME,
    result: "CUSTOM",
    doNotClose: true,
  });

  const tooltipPopup = findElement(dbg, "previewPopup");

  const tooltipArrow = tooltipPopup.querySelector(".collapse-button");
  ok(tooltipArrow, `'${VARIABLE_NAME}' is expandable`);

  info(`Expanding '${VARIABLE_NAME}'`);
  const onTooltipBodyRendered = waitFor(
    () =>
      !!tooltipPopup.querySelector(
        ".objectBox-jsonml-body-wrapper .objectBox-jsonml"
      )
  );

  tooltipArrow.click();
  await onTooltipBodyRendered;
  const tooltipBodyJsonMlNode = tooltipPopup.querySelector(
    ".objectBox-jsonml-body-wrapper > .objectBox-jsonml"
  );
  ok(tooltipBodyJsonMlNode, "The tooltip variable body is custom formatted");
  is(
    tooltipBodyJsonMlNode?.textContent,
    CUSTOM_FORMATTED_BODY,
    "The tooltip variable body text is correct"
  );

  await resume(dbg);
});