summaryrefslogtreecommitdiffstats
path: root/devtools/client/webconsole/test/browser/browser_webconsole_cached_messages.js
blob: 5909d2e8241181121f1eaf95203c84358207f4a9 (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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

// Test to see if the cached messages are displayed when the console UI is opened.

"use strict";

// See Bug 1570524.
requestLongerTimeout(2);

const TEST_URI = `data:text/html,<!DOCTYPE html><meta charset=utf8><h1>Test cached messages</h1>
  <style>
    h1 {
      color: cssColorBug611032;
    }
  </style>
  <script>
    function logException() {
      return new Promise(resolve => {
        setTimeout(() => {
          let foo = {};
          resolve();
          foo.unknown();
        }, 0);
      })
    }
  </script>`;

add_task(async function () {
  // On e10s, the exception is triggered in child process
  // and is ignored by test harness
  if (!Services.appinfo.browserTabsRemoteAutostart) {
    expectUncaughtException();
  }
  // Enable CSS and XHR filters for the test.
  await pushPref("devtools.webconsole.filter.css", true);
  await pushPref("devtools.webconsole.filter.netxhr", true);

  await addTab(TEST_URI);

  info("Log different type of messages to fill the cache");
  await logMessages();

  info("Open the console");
  let hud = await openConsole();

  // We only start watching network requests when opening the toolbox.
  await testMessagesVisibility(hud, false);

  info("Close the toolbox and reload the tab");
  await closeToolbox();
  await reloadPage();

  info(
    "Open the toolbox with the inspector selected, so we can get network messages"
  );
  await openInspector();

  info("Log different type of messages to fill the cache");
  await logMessages();

  info("Select the console");
  hud = await openConsole();

  await testMessagesVisibility(hud);

  info("Close the toolbox");
  await closeToolbox();

  info("Open the console again");
  hud = await openConsole();
  // The network messages don't persist.
  await testMessagesVisibility(hud, false);
});

async function logMessages() {
  await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () {
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    const wait = () =>
      new Promise(res => content.wrappedJSObject.setTimeout(res, 100));

    content.wrappedJSObject.console.log("log Bazzle");
    await wait();

    await content.wrappedJSObject.logException();
    await wait();

    await content.wrappedJSObject.fetch(
      "http://mochi.test:8888/browser/devtools/client/webconsole/test/browser/sjs_cors-test-server.sjs?1",
      { mode: "cors" }
    );
    await wait();

    content.wrappedJSObject.console.error("error Bazzle");
    await wait();

    await content.wrappedJSObject.logException();
    await wait();

    await content.wrappedJSObject.fetch(
      "http://mochi.test:8888/browser/devtools/client/webconsole/test/browser/sjs_cors-test-server.sjs?2"
    );

    content.wrappedJSObject.console.info("info Bazzle");
    await wait();
  });
}

async function testMessagesVisibility(hud, checkNetworkMessage = true) {
  // wait for the last logged message to be displayed
  await waitFor(() => findConsoleAPIMessage(hud, "info Bazzle", ".info"));

  const messages = Array.from(hud.ui.outputNode.querySelectorAll(".message"));
  const EXPECTED_MESSAGES = [
    {
      text: "log Bazzle",
      category: "log",
    },
    {
      text: "foo.unknown is not a function",
      category: "error",
    },
    {
      text: "sjs_cors-test-server.sjs?1",
      category: "network",
    },
    {
      text: "error Bazzle",
      category: "error",
    },
    {
      text: "foo.unknown is not a function",
      category: "error",
    },
    {
      text: "sjs_cors-test-server.sjs?2",
      category: "network",
    },
    {
      text: "info Bazzle",
      category: "info",
    },
  ].filter(({ category }) => checkNetworkMessage || category != "network");

  // Clone the original array so we can use it later
  const expectedMessages = [...EXPECTED_MESSAGES];
  for (const message of messages) {
    const [expectedMessage] = expectedMessages;
    if (
      message.classList.contains(expectedMessage.category) &&
      message.textContent.includes(expectedMessage.text)
    ) {
      ok(
        true,
        `The ${expectedMessage.category} message "${expectedMessage.text}" is visible at the expected place`
      );
      expectedMessages.shift();
      if (expectedMessages.length === 0) {
        ok(
          true,
          "All the expected messages were found at the expected position"
        );
        break;
      }
    }
  }

  if (expectedMessages.length) {
    ok(
      false,
      `Some messages are not visible or not in the expected order. Expected to find: \n\n${EXPECTED_MESSAGES.map(
        ({ text }) => text
      ).join("\n")}\n\nGot: \n\n${messages
        .map(message => `${message.querySelector(".message-body").textContent}`)
        .join("\n")}`
    );
  }

  // We can't assert the CSS warning position, so we only check that it's visible.
  await waitFor(
    () => findWarningMessage(hud, "cssColorBug611032", ".css"),
    "Couldn't find the CSS warning message"
  );
  ok(true, "css warning message is visible");
}