summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-preview-wrapped-lines.js
blob: bb222408f3ed912c5f923bf89aee70101bda926d (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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

// Test that the tooltip previews are correct with wrapped editor lines.

"use strict";

const httpServer = createTestHTTPServer();
httpServer.registerContentType("html", "text/html");
httpServer.registerContentType("js", "application/javascript");

httpServer.registerPathHandler(
  "/doc-wrapped-lines.html",
  (request, response) => {
    response.setStatusLine(request.httpVersion, 200, "OK");
    response.write(`<!DOCTYPE html>
    <html>
      <head>
        <script type="text/javascript">
        const cs1 = getComputedStyle(document.documentElement);
        const cs2 = getComputedStyle(document.documentElement);
        // This line generates a very long inline-preview which is loaded a bit later after the
        // initial positions for the page has been calculated
        function add(a,b,k){var result=a+b;return k(result)}function sub(a,b,k){var result=a-b;return k(result)}function mul(a,b,k){var result=a*b;return k(result)}function div(a,b,k){var result=a/b;return k(result)}function arithmetic(){
  add(4,4,function(a){
    sub(a,2,function(b){mul(b,3,function(c){div(c,2,function(d){console.log("arithmetic",d)})})})})};
        isNaN(cs1, cs2);
          const foo = { prop: 0 };
          const bar = Math.min(foo);
          const myVeryLongVariableNameThatMayWrap = 42;
          myVeryLongVariableNameThatMayWrap * 2;
          debugger;
        </script>
      </head>
    </html>
  `);
  }
);

const BASE_URL = `http://localhost:${httpServer.identity.primaryPort}/`;

add_task(async function () {
  await pushPref("devtools.toolbox.footer.height", 500);
  await pushPref("devtools.debugger.ui.editor-wrapping", true);

  // Reset toolbox height and end panel size to avoid impacting other tests
  registerCleanupFunction(() => {
    Services.prefs.clearUserPref("debugger.end-panel-size");
  });

  const dbg = await initDebuggerWithAbsoluteURL(
    `${BASE_URL}doc-wrapped-lines.html`
  );
  await waitForSources(dbg, "doc-wrapped-lines.html");

  const onReloaded = reload(dbg);
  await waitForPaused(dbg);

  await assertPreviews(dbg, [
    {
      line: 13,
      column: 18,
      expression: "foo",
      fields: [["prop", "0"]],
    },
    {
      line: 14,
      column: 18,
      result: "NaN",
      expression: "bar",
    },
  ]);

  info("Resize the editor until `myVeryLongVariableNameThatMayWrap` wraps");
  // Use splitter to resize to make sure CodeMirror internal state is refreshed
  // in such case (CodeMirror already handle window resize on its own).
  const splitter = dbg.win.document.querySelectorAll(".splitter")[1];
  const splitterOriginalX = splitter.getBoundingClientRect().left;
  ok(splitter, "Got the splitter");

  let longToken = getTokenElAtLine(
    dbg,
    "myVeryLongVariableNameThatMayWrap",
    16
  );
  const longTokenBoundingClientRect = longToken.getBoundingClientRect();
  await resizeSplitter(
    dbg,
    splitter,
    longTokenBoundingClientRect.left + longTokenBoundingClientRect.width / 2
  );

  info("Wait until the token does wrap");
  longToken = await waitFor(() => {
    const token = getTokenElAtLine(
      dbg,
      "myVeryLongVariableNameThatMayWrap",
      16
    );
    if (token.getBoxQuads().length === 1) {
      return null;
    }
    return token;
  });

  longToken.scrollIntoView();

  await assertPreviews(dbg, [
    {
      line: 16,
      column: 13,
      expression: "myVeryLongVariableNameThatMayWrap",
      result: "42",
    },
  ]);

  // clearing the pref isn't enough to have consistent sizes between runs,
  // so set it back to its original position
  await resizeSplitter(dbg, splitter, splitterOriginalX);

  await resume(dbg);
  await onReloaded;

  Services.prefs.clearUserPref("debugger.end-panel-size");
  await wait(1000);
});

async function resizeSplitter(dbg, splitterEl, x) {
  EventUtils.synthesizeMouse(splitterEl, 0, 0, { type: "mousedown" }, dbg.win);

  // Resizing the editor should cause codeMirror to refresh
  const cm = dbg.getCM();
  const onEditorRefreshed = new Promise(resolve =>
    cm.on("refresh", function onCmRefresh() {
      cm.off("refresh", onCmRefresh);
      resolve();
    })
  );
  // Move the splitter of the secondary pane to the middle of the token,
  // this should cause the token to wrap.
  EventUtils.synthesizeMouseAtPoint(
    x,
    splitterEl.getBoundingClientRect().top + 10,
    { type: "mousemove" },
    dbg.win
  );

  // Stop dragging
  EventUtils.synthesizeMouseAtCenter(splitterEl, { type: "mouseup" }, dbg.win);

  await onEditorRefreshed;
  ok(true, "CodeMirror was refreshed when resizing the editor");
}