Skip to content

Commit

Permalink
Bug 1611817 - Migrate remaining chrome tests to devtools browser test…
Browse files Browse the repository at this point in the history
…s; r=julienw

Differential Revision: https://phabricator.services.mozilla.com/D65153

--HG--
extra : moz-landing-system : lando
  • Loading branch information
gregtatum committed Mar 9, 2020
1 parent 24b1c74 commit 9e6847f
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 530 deletions.
3 changes: 2 additions & 1 deletion devtools/client/performance-new/@types/perf.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {

export interface PanelWindow {
gToolbox?: any;
gInit(perfFront: PerfFront, preferenceFront: PageContext): void;
gStore?: Store;
gInit(perfFront: PerfFront, pageContext: PageContext): void;
gDestroy(): void;
gReportReady?(): void;
gIsPanelDestroyed?: boolean;
Expand Down
12 changes: 12 additions & 0 deletions devtools/client/performance-new/initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* @typedef {import("./@types/perf").PreferenceFront} PreferenceFront
* @typedef {import("./@types/perf").RecordingStateFromPreferences} RecordingStateFromPreferences
* @typedef {import("./@types/perf").PageContext} PageContext
* @typedef {import("./@types/perf").PanelWindow} PanelWindow
* @typedef {import("./@types/perf").Store} Store
*/
"use strict";

Expand Down Expand Up @@ -94,6 +96,16 @@ async function gInit(perfFront, pageContext, openAboutProfiling) {
};
}

{
// Expose the store as a global, for testing.
const anyWindow = /** @type {any} */ (window);
const panelWindow = /** @type {PanelWindow} */ (anyWindow);
// The store variable is a `ReduxStore`, not our `Store` type, as defined
// in perf.d.ts. Coerce it into the `Store` type.
const anyStore = /** @type {any} */ (store);
panelWindow.gStore = anyStore;
}

// Do some initialization, especially with privileged things that are part of the
// the browser.
store.dispatch(
Expand Down
1 change: 0 additions & 1 deletion devtools/client/performance-new/moz.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ DevToolsModules(
)

BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini']
XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']

with Files('**'):
Expand Down
3 changes: 3 additions & 0 deletions devtools/client/performance-new/test/browser/browser.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ support-files =
[browser_aboutprofiling-threads-behavior.js]
[browser_aboutprofiling-presets.js]
[browser_aboutprofiling-presets-custom.js]
[browser_devtools-interrupted.js]
[browser_devtools-presets.js]
[browser_devtools-previously-started.js]
[browser_devtools-private-window.js]
[browser_devtools-record-capture.js]
[browser_devtools-record-discard.js]
[browser_webchannel-enable-menu-button.js]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* 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";

add_task(async function test() {
info("Test what happens when a recording is interrupted by another tool.");

const {
revertRecordingPreferences,
stopProfiler: stopProfilerByAnotherTool,
} = ChromeUtils.import(
"resource://devtools/client/performance-new/popup/background.jsm.js"
);

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

const startRecording = await getActiveButtonFromText(
document,
"Start recording"
);
info("Click to start recording");
startRecording.click();

info("Wait until the profiler UI has updated to show that it is ready.");
await getActiveButtonFromText(document, "Capture recording");

info("Stop the profiler by another tool.");

stopProfilerByAnotherTool();

info("Check that the user was notified of this interruption.");
await getElementFromDocumentByText(
document,
"The recording was stopped by another tool."
);

is(
getRecordingState(),
"available-to-record",
"The client is ready to record again, even though it was interrupted."
);
});

revertRecordingPreferences();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* 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";

add_task(async function test() {
info(
"Test what happens if the profiler was previously started by another tool."
);

const { revertRecordingPreferences, startProfiler } = ChromeUtils.import(
"resource://devtools/client/performance-new/popup/background.jsm.js"
);

info("Start the profiler before DevTools is loaded.");
startProfiler("aboutprofiling");

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

is(
getRecordingState(),
"not-yet-known",
"The component starts out in an unknown state."
);

const cancelRecording = await getActiveButtonFromText(
document,
"Cancel recording"
);

is(
getRecordingState(),
"recording",
"The profiler is reflecting the recording state."
);

info("Click the button to cancel the recording");
cancelRecording.click();

is(
getRecordingState(),
"request-to-stop-profiler",
"We can request to stop the profiler."
);

await getActiveButtonFromText(document, "Start recording");

is(
getRecordingState(),
"available-to-record",
"The profiler is now available to record."
);
});

revertRecordingPreferences();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* 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";

add_task(async function test() {
info("Test opening a private browsing window while the profiler is active.");

const { revertRecordingPreferences } = ChromeUtils.import(
"resource://devtools/client/performance-new/popup/background.jsm.js"
);

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

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

ok(!startRecording.disabled, "The start recording button is not disabled.");
is(
getRecordingState(),
"available-to-record",
"The panel is available to record."
);

const privateWindow = await BrowserTestUtils.openNewBrowserWindow({
private: true,
});

await getElementFromDocumentByText(
document,
"The profiler is disabled when Private Browsing is enabled"
);

ok(
startRecording.disabled,
"The start recording button is disabled when a private browsing window is open."
);

is(
getRecordingState(),
"locked-by-private-browsing",
"The client knows about the private window."
);

info("Closing the private window");
await BrowserTestUtils.closeWindow(privateWindow);

info("Finally wait for the start recording button to become active again.");
await getActiveButtonFromText(document, "Start recording");

is(
getRecordingState(),
"available-to-record",
"The panel is available to record again."
);
});

revertRecordingPreferences();
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,71 @@
"use strict";

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

await setProfilerFrontendUrl(
"http://example.com/browser/devtools/client/performance-new/test/browser/fake-frontend.html"
);

await withDevToolsPanel(async document => {
{
const button = await getActiveButtonFromText(document, "Start recording");
info("Click the button to start recording");
button.click();
}

{
const button = await getActiveButtonFromText(
document,
"Capture recording"
);
info("Click the button to capture the recording.");
button.click();
}
const getRecordingState = setupGetRecordingState(document);

is(
getRecordingState(),
"not-yet-known",
"The component starts out in an unknown state."
);

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."
);

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

is(
getRecordingState(),
"recording",
"Once the Capture recording button is available, the actor has started " +
"its 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."
);

info(
"If the DevTools successfully injects a profile into the page, then the " +
Expand Down
17 changes: 17 additions & 0 deletions devtools/client/performance-new/test/browser/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,3 +593,20 @@ function setReactFriendlyInputValue(input, value) {
// 'change' instead of 'input', see https://github.com/facebook/react/issues/11488#issuecomment-381590324
input.dispatchEvent(new Event("change", { bubbles: true }));
}

/**
* The recording state is the internal state machine that represents the async
* operations that are going on in the profiler. This function sets up a helper
* that will obtain the Redux store and query this internal state. This is useful
* for unit testing purposes.
*
* @param {Document} document
*/
function setupGetRecordingState(document) {
const selectors = require("devtools/client/performance-new/store/selectors");
const store = document.defaultView.gStore;
if (!store) {
throw new Error("Could not find the redux store on the window object.");
}
return () => selectors.getRecordingState(store.getState());
}
8 changes: 0 additions & 8 deletions devtools/client/performance-new/test/chrome/chrome.ini

This file was deleted.

Loading

0 comments on commit 9e6847f

Please sign in to comment.