summaryrefslogtreecommitdiffstats
path: root/devtools/client/performance-new/test/browser/browser_interaction-between-interfaces.js
blob: 1268cf818dd16183fcfe31ea0b5b9e91aec267b7 (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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
/* 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/. */
/* eslint-disable max-nested-callbacks */
"use strict";

add_task(async function test_change_in_popup() {
  // This test assumes that the Web Developer preset is set by default, which is
  // not the case on Nightly and custom builds.
  BackgroundJSM.changePreset(
    "aboutprofiling",
    "web-developer",
    Services.profiler.GetFeatures()
  );

  info(
    "Test that changing settings in the popup changes settings in the devtools panel and about:profiling too."
  );

  const browserWindow = window;
  const browserDocument = document;

  await makeSureProfilerPopupIsEnabled();
  await withDevToolsPanel(
    "about:profiling",
    async (devtoolsDocument, aboutProfilingDocument) => {
      await withPopupOpen(browserWindow, async () => {
        const presetsInPopup = browserDocument.getElementById(
          "PanelUI-profiler-presets"
        );

        const presetsInDevtools = await getNearestInputFromText(
          devtoolsDocument,
          "Settings"
        );

        const webdev = await getNearestInputFromText(
          aboutProfilingDocument,
          "Web Developer"
        );
        const graphics = await getNearestInputFromText(
          aboutProfilingDocument,
          "Graphics"
        );
        const media = await getNearestInputFromText(
          aboutProfilingDocument,
          "Media"
        );

        // Default situation
        ok(
          webdev.checked,
          "By default the Web Developer preset is selected in the about:profiling interface."
        );
        is(
          presetsInDevtools.value,
          "web-developer",
          "The presets default to webdev mode in the devtools panel."
        );
        is(
          presetsInPopup.value,
          "web-developer",
          "The presets default to webdev mode in the popup."
        );

        // Select "graphics" using the popup
        ok(!graphics.checked, "The Graphics preset is not checked.");

        presetsInPopup.menupopup.openPopup();
        presetsInPopup.menupopup.activateItem(
          await getElementByLabel(presetsInPopup, "Graphics")
        );

        await TestUtils.waitForCondition(
          () => !webdev.checked,
          "After selecting the preset in the popup, waiting until the Web Developer preset isn't selected anymore in the about:profiling interface."
        );
        await TestUtils.waitForCondition(
          () => graphics.checked,
          "After selecting the preset in the popup, waiting until the Graphics preset is checked in the about:profiling interface."
        );
        await TestUtils.waitForCondition(
          () => presetsInDevtools.value === "graphics",
          "After selecting the preset in the popup, waiting until the preset is changed to Graphics in the devtools panel too."
        );
        await TestUtils.waitForCondition(
          () => presetsInPopup.value === "graphics",
          "After selecting the preset in the popup, waiting until the preset is changed to Graphics in the popup."
        );

        // Select "firefox frontend" using the popup
        ok(!media.checked, "The Media preset is not checked.");

        presetsInPopup.menupopup.openPopup();
        presetsInPopup.menupopup.activateItem(
          await getElementByLabel(presetsInPopup, "Media")
        );

        await TestUtils.waitForCondition(
          () => !graphics.checked,
          "After selecting the preset in the popup, waiting until the Graphics preset is not checked anymore in the about:profiling interface."
        );
        await TestUtils.waitForCondition(
          () => media.checked,
          "After selecting the preset in the popup, waiting until the Media preset is checked in the about:profiling interface."
        );
        await TestUtils.waitForCondition(
          () => presetsInDevtools.value === "media",
          "After selecting the preset in the popup, waiting until the preset is changed to Firefox Front-end in the devtools panel."
        );
        await TestUtils.waitForCondition(
          () => presetsInPopup.value === "media",
          "After selecting the preset in the popup, waiting until the preset is changed to Media in the popup."
        );
      });
    }
  );
});

// In the following tests we don't look at changes in the popup. Indeed because
// the popup rerenders each time it's open, we don't need to mirror it.
add_task(async function test_change_in_about_profiling() {
  // This test assumes that the Web Developer preset is set by default, which is
  // not the case on Nightly and custom builds, or after previous tests.
  BackgroundJSM.changePreset(
    "aboutprofiling",
    "web-developer",
    Services.profiler.GetFeatures()
  );

  info(
    "Test that changing settings in about:profiling changes settings in the devtools panel too."
  );

  await withDevToolsPanel(
    "about:profiling",
    async (devtoolsDocument, aboutProfilingDocument) => {
      const presetsInDevtools = await getNearestInputFromText(
        devtoolsDocument,
        "Settings"
      );

      const webdev = await getNearestInputFromText(
        aboutProfilingDocument,
        "Web Developer"
      );
      const graphics = await getNearestInputFromText(
        aboutProfilingDocument,
        "Graphics"
      );
      const media = await getNearestInputFromText(
        aboutProfilingDocument,
        "Media"
      );
      const custom = await getNearestInputFromText(
        aboutProfilingDocument,
        "Custom"
      );

      // Default values
      ok(
        webdev.checked,
        "By default the Web Developer preset is selected in the about:profiling interface."
      );
      is(
        presetsInDevtools.value,
        "web-developer",
        "The presets default to webdev mode in the devtools panel."
      );

      // Change the preset in about:profiling, check it changes also in the
      // devtools panel.
      ok(!graphics.checked, "The Graphics preset is not checked.");
      graphics.click();
      ok(
        graphics.checked,
        "After clicking the input, the Graphics preset is now checked in about:profiling."
      );
      await TestUtils.waitForCondition(
        () => presetsInDevtools.value === "graphics",
        "The preset was changed to Graphics in the devtools panel too."
      );

      ok(!media.checked, "The Media preset is not checked.");
      media.click();
      ok(
        media.checked,
        "After clicking the input, the Media preset is now checked in about:profiling."
      );
      await TestUtils.waitForCondition(
        () => presetsInDevtools.value === "media",
        "The preset was changed to Media in the devtools panel too."
      );

      // Now let's try to change some configuration!
      info(
        "Increase the interval by an arbitrary amount. The input range will " +
          "scale that to the final value presented to the profiler."
      );
      const intervalInput = await getNearestInputFromText(
        aboutProfilingDocument,
        "Sampling interval:"
      );
      setReactFriendlyInputValue(
        intervalInput,
        Number(intervalInput.value) + 1
      );
      ok(
        custom.checked,
        "After changing the interval, the Custom preset is now checked in about:profiling."
      );
      await TestUtils.waitForCondition(
        () => presetsInDevtools.value === "custom",
        "The preset was changed to Custom in the devtools panel too."
      );

      ok(
        getDevtoolsCustomPresetContent(devtoolsDocument).includes(
          "Interval: 2 ms"
        ),
        "The new interval should be in the custom preset description"
      );

      // Let's check some thread as well
      info("Change the threads values using the checkboxes");

      const styleThreadInput = await getNearestInputFromText(
        aboutProfilingDocument,
        "StyleThread"
      );
      ok(
        !styleThreadInput.checked,
        "The StyleThread thread isn't checked by default."
      );

      info("Click the StyleThread checkbox.");
      styleThreadInput.click();

      // For some reason, it's not possible to directly match "StyleThread".
      const threadsLine = (
        await getElementFromDocumentByText(devtoolsDocument, "Threads")
      ).parentElement;
      await TestUtils.waitForCondition(
        () => threadsLine.textContent.includes("StyleThread"),
        "Waiting that StyleThread is displayed in the devtools panel."
      );
      ok(
        getDevtoolsCustomPresetContent(devtoolsDocument).includes(
          "StyleThread"
        ),
        "The StyleThread thread should be listed in the custom preset description"
      );
      styleThreadInput.click();
      await TestUtils.waitForCondition(
        () => !threadsLine.textContent.includes("StyleThread"),
        "Waiting until the StyleThread disappears from the devtools panel."
      );
      ok(
        !getDevtoolsCustomPresetContent(devtoolsDocument).includes(
          "StyleThread"
        ),
        "The StyleThread thread should no longer be listed in the custom preset description"
      );

      info("Change the threads values using the input.");
      const threadInput = await getNearestInputFromText(
        aboutProfilingDocument,
        "Add custom threads by name"
      );

      function setThreadInputValue(newThreadValue) {
        // Actually set the new value.
        setReactFriendlyInputValue(threadInput, newThreadValue);
        // The settings are actually changed on the blur event.
        threadInput.dispatchEvent(new FocusEvent("blur"));
      }

      let newThreadValue = "GeckoMain,Foo";
      setThreadInputValue(newThreadValue);
      await TestUtils.waitForCondition(
        () => threadsLine.textContent.includes("Foo"),
        "Waiting for Foo to be displayed in the devtools panel."
      );

      // The code detecting changes to the thread list has a fast path
      // to detect that the list of threads has changed if the 2 lists
      // have different lengths. Exercise the slower code path by changing
      // the list of threads to a list with the same number of threads.
      info("Change the thread list again to a list of the same length");
      newThreadValue = "GeckoMain,Dummy";
      is(
        threadInput.value.split(",").length,
        newThreadValue.split(",").length,
        "The new value should have the same count of threads as the old value, please double check the test code."
      );
      setThreadInputValue(newThreadValue);
      checkDevtoolsCustomPresetContent(
        devtoolsDocument,
        `
          Interval: 2 ms
          Threads: GeckoMain, Dummy
          JavaScript
          Native Stacks
          CPU Utilization
          Audio Callback Tracing
          IPC Messages
          Process CPU Utilization
        `
      );
    }
  );
});

add_task(async function test_change_in_devtools_panel() {
  // This test assumes that the Web Developer preset is set by default, which is
  // not the case on Nightly and custom builds, or after previous tests.
  BackgroundJSM.changePreset(
    "aboutprofiling",
    "web-developer",
    Services.profiler.GetFeatures()
  );

  info(
    "Test that changing settings in the devtools panel changes settings in about:profiling too."
  );

  await withDevToolsPanel(
    "about:profiling",
    async (devtoolsDocument, aboutProfilingDocument) => {
      const presetsInDevtools = await getNearestInputFromText(
        devtoolsDocument,
        "Settings"
      );

      const webdev = await getNearestInputFromText(
        aboutProfilingDocument,
        "Web Developer"
      );
      const graphics = await getNearestInputFromText(
        aboutProfilingDocument,
        "Graphics"
      );
      const media = await getNearestInputFromText(
        aboutProfilingDocument,
        "Media"
      );

      // Default values
      ok(
        webdev.checked,
        "By default the Web Developer preset is selected in the about:profiling interface."
      );
      is(
        presetsInDevtools.value,
        "web-developer",
        "The presets default to webdev mode in the devtools panel."
      );

      // Change the preset in devtools panel, check it changes also in
      // about:profiling.
      ok(
        !graphics.checked,
        "The Graphics preset is not checked in about:profiling."
      );

      setReactFriendlyInputValue(presetsInDevtools, "graphics");
      await TestUtils.waitForCondition(
        () => graphics.checked,
        "After changing the preset in the devtools panel, the Graphics preset is now checked in about:profiling."
      );
      await TestUtils.waitForCondition(
        () => presetsInDevtools.value === "graphics",
        "The preset was changed to Graphics in the devtools panel too."
      );

      // Change another preset now
      ok(!media.checked, "The Media preset is not checked.");
      setReactFriendlyInputValue(presetsInDevtools, "media");
      await TestUtils.waitForCondition(
        () => media.checked,
        "After changing the preset in the devtools panel, the Media preset is now checked in about:profiling."
      );
      await TestUtils.waitForCondition(
        () => presetsInDevtools.value === "media",
        "The preset was changed to Media in the devtools panel too."
      );
    }
  );
});