summaryrefslogtreecommitdiffstats
path: root/devtools/client/performance-new/test/browser/browser_devtools-record-capture.js
blob: 4f0accf3eb06a49b9326042ba231616716baf10b (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
/* 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/. */

"use strict";

const FRONTEND_BASE_HOST = "http://example.com";
const FRONTEND_BASE_PATH =
  "/browser/devtools/client/performance-new/test/browser/fake-frontend.html";
const FRONTEND_BASE_URL = FRONTEND_BASE_HOST + FRONTEND_BASE_PATH;

add_setup(async function setup() {
  // The active tab view isn't enabled in all configurations. Let's make sure
  // it's enabled in these tests.
  SpecialPowers.pushPrefEnv({
    set: [["devtools.performance.recording.active-tab-view.enabled", true]],
  });
});

add_task(async function test() {
  info(
    "Test that DevTools can capture profiles. This function also unit tests the " +
      "internal RecordingState of the client."
  );

  // 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()
  );

  await setProfilerFrontendUrl(FRONTEND_BASE_HOST, FRONTEND_BASE_PATH);

  await withDevToolsPanel(async document => {
    const getRecordingState = setupGetRecordingState(document);

    // The initial state of the profiler UI is racy, as it calls out to the PerfFront
    // to get the status of the profiler. This can race with the initialization of
    // the test. Most of the the time the result is "not-yet-known", but rarely
    // the PerfFront will win this race. Allow for both outcomes of the race in this
    // test.
    ok(
      getRecordingState() === "not-yet-known" ||
        getRecordingState() === "available-to-record",
      "The component starts out in an unknown state or is already available to record."
    );

    // First check for "firefox-platform" preset which will have no "view" query
    // string because this is where our traditional "full" view opens up.
    await setPresetCaptureAndAssertUrl({
      document,
      preset: "firefox-platform",
      expectedUrl: FRONTEND_BASE_URL,
      getRecordingState,
    });

    // Now, let's check for "web-developer" preset. This will open up the frontend
    // with "active-tab" view query string. Frontend will understand and open the active tab view for it.
    await setPresetCaptureAndAssertUrl({
      document,
      preset: "web-developer",
      expectedUrl: FRONTEND_BASE_URL + "?view=active-tab&implementation=js",
      getRecordingState,
    });
  });
});

add_task(async function test_in_private_window() {
  info("Test that DevTools can capture profiles in a private window.");

  // 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()
  );

  await setProfilerFrontendUrl(FRONTEND_BASE_HOST, FRONTEND_BASE_PATH);

  info("Open a private window.");
  const privateWindow = await BrowserTestUtils.openNewBrowserWindow({
    private: true,
  });

  await withDevToolsPanel(async document => {
    const getRecordingState = setupGetRecordingState(document);

    // The initial state of the profiler UI is racy, as it calls out to the PerfFront
    // to get the status of the profiler. This can race with the initialization of
    // the test. Most of the the time the result is "not-yet-known", but rarely
    // the PerfFront will win this race. Allow for both outcomes of the race in this
    // test.
    ok(
      getRecordingState() === "not-yet-known" ||
        getRecordingState() === "available-to-record",
      "The component starts out in an unknown state or is already available to record."
    );

    // First check for "firefox-platform" preset which will have no "view" query
    // string because this is where our traditional "full" view opens up.
    // Note that this utility will check for a new tab in the main non-private
    // window, which is exactly what we want here.
    await setPresetCaptureAndAssertUrl({
      document,
      preset: "firefox-platform",
      expectedUrl: FRONTEND_BASE_URL,
      getRecordingState,
    });

    // Now, let's check for "web-developer" preset. This will open up the frontend
    // with "active-tab" view query string. Frontend will understand and open the active tab view for it.
    await setPresetCaptureAndAssertUrl({
      document,
      preset: "web-developer",
      expectedUrl: FRONTEND_BASE_URL + "?view=active-tab&implementation=js",
      getRecordingState,
    });
  }, privateWindow);

  await BrowserTestUtils.closeWindow(privateWindow);
});

async function setPresetCaptureAndAssertUrl({
  document,
  preset,
  expectedUrl,
  getRecordingState,
}) {
  const presetsInDevtools = await getNearestInputFromText(document, "Settings");
  setReactFriendlyInputValue(presetsInDevtools, preset);

  const startRecording = await getActiveButtonFromText(
    document,
    "Start recording"
  );

  is(
    getRecordingState(),
    "available-to-record",
    "After talking to the actor, we're ready to record."
  );

  info("Click the button to start recording");
  startRecording.click();

  is(
    getRecordingState(),
    "request-to-start-recording",
    "Clicking the start recording button sends in a request to start recording."
  );

  is(
    document.defaultView.gToolbox.isHighlighted("performance"),
    false,
    "The Performance panel in not highlighted yet."
  );

  const captureRecording = await getActiveButtonFromText(
    document,
    "Capture recording"
  );

  is(
    getRecordingState(),
    "recording",
    "Once the Capture recording button is available, the actor has started " +
      "its recording"
  );

  is(
    document.defaultView.gToolbox.isHighlighted("performance"),
    true,
    "The Performance Panel in the Devtools Tab is highlighted when the profiler " +
      "is recording"
  );

  info("Click the button to capture the recording.");
  captureRecording.click();

  is(
    getRecordingState(),
    "request-to-get-profile-and-stop-profiler",
    "We have requested to stop the profiler."
  );

  await getActiveButtonFromText(document, "Start recording");
  is(
    getRecordingState(),
    "available-to-record",
    "The profiler is available to record again."
  );

  is(
    document.defaultView.gToolbox.isHighlighted("performance"),
    false,
    "The Performance panel in not highlighted anymore when the profiler is stopped"
  );

  info(
    "If the DevTools successfully injects a profile into the page, then the " +
      "fake frontend will rename the title of the page."
  );

  await waitForTabUrl({
    initialTitle: "Waiting on the profile",
    successTitle: "Profile received",
    errorTitle: "Error",
    expectedUrl,
  });
}