Bug 1597378 - Migrate profiler popup tests; r=julienw

This commit adds tests for the profiler popup, and migrates some of the
older ones to use about:profiling instead.

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

--HG--
rename : devtools/client/performance-new/test/browser/browser_popup-env-restart-button.js => devtools/client/performance-new/test/browser/browser_aboutprofiling-env-restart-button.js
rename : devtools/client/performance-new/test/browser/browser_popup-features-disabled.js => devtools/client/performance-new/test/browser/browser_aboutprofiling-features-disabled.js
rename : devtools/client/performance-new/test/browser/browser_popup-end-to-end-click.js => devtools/client/performance-new/test/browser/browser_popup-record-capture.js
extra : moz-landing-system : lando
This commit is contained in:
Greg Tatum 2020-02-25 20:41:15 +00:00
Родитель f34a461b3d
Коммит 7a74223d84
13 изменённых файлов: 224 добавлений и 174 удалений

Просмотреть файл

@ -11,6 +11,10 @@ support-files =
# about:profiling tests are nightly only until the feature is released, and
# the feature is not enabled on android at all, since we rely on remote debugging.
[browser_aboutprofiling-env-restart-button.js]
skip-if = !nightly_build || os == 'android'
[browser_aboutprofiling-features-disabled.js]
skip-if = !nightly_build || os == 'android'
[browser_aboutprofiling-features.js]
skip-if = !nightly_build || os == 'android'
[browser_aboutprofiling-threads.js]
@ -22,6 +26,5 @@ skip-if = !nightly_build || os == 'android'
[browser_webchannel-enable-menu-button.js]
skip-if = !nightly_build || os == 'android'
[browser_popup-end-to-end-click.js]
[browser_popup-env-restart-button.js]
[browser_popup-features-disabled.js]
[browser_popup-record-capture.js]
[browser_popup-record-discard.js]

Просмотреть файл

@ -0,0 +1,81 @@
/* 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 that the popup offers to restart the browser to set an enviroment flag."
);
if (!Services.profiler.GetFeatures().includes("jstracer")) {
ok(
true,
"JS tracer is not supported on this platform, or is currently disabled. Skip the rest of the test."
);
return;
}
{
info("Ensure that JS Tracer is not currently enabled.");
const {
getEnvironmentVariable,
} = require("devtools/client/performance-new/browser");
ok(
!getEnvironmentVariable("JS_TRACE_LOGGING"),
"The JS_TRACE_LOGGING is not currently enabled."
);
}
ok(
false,
"This test was migrated from the initial popup implementation to " +
"about:profiling, however JS Tracer was disabled at the time. When " +
"re-enabling JS Tracer, please audit that this text works as expected, " +
"especially in the UI."
);
await withAboutProfiling(async document => {
{
info(
"Test that there is offer to restart the browser when first loading up the popup."
);
const noRestartButton = maybeGetElementFromDocumentByText(
document,
"Restart"
);
ok(!noRestartButton, "There is no button to restart the browser.");
}
const jsTracerFeature = await getElementFromDocumentByText(
document,
"JSTracer"
);
{
info("Toggle the jstracer feature on.");
jsTracerFeature.click();
const restartButton = await getElementFromDocumentByText(
document,
"Restart"
);
ok(
restartButton,
"There is now a button to offer to restart the browser"
);
}
{
info("Toggle the jstracer feature back off.");
jsTracerFeature.click();
const noRestartButton = maybeGetElementFromDocumentByText(
document,
"Restart"
);
ok(!noRestartButton, "The offer to restart the browser goes away.");
}
});
});

Просмотреть файл

@ -0,0 +1,69 @@
/* 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 that features that are disabled on the platform are disabled in about:profiling."
);
const supportedFeatures = Services.profiler.GetFeatures();
const allFeatures = Services.profiler.GetAllFeatures();
const unsupportedFeatures = allFeatures.filter(
feature => !supportedFeatures.includes(feature)
);
if (unsupportedFeatures.length === 0) {
ok(true, "This platform has no unsupported features. Skip this test.");
return;
}
await withAboutProfiling(async document => {
{
info("Find and click a supported feature to toggle it.");
const [firstSupportedFeature] = supportedFeatures;
const checkbox = getFeatureCheckbox(document, firstSupportedFeature);
const initialValue = checkbox.checked;
info("Click the supported checkbox.");
checkbox.click();
is(
initialValue,
!checkbox.checked,
"A supported feature can be toggled."
);
checkbox.click();
}
{
info("Find and click an unsupported feature, it should be disabled.");
const [firstUnsupportedFeature] = unsupportedFeatures;
const checkbox = getFeatureCheckbox(document, firstUnsupportedFeature);
is(checkbox.checked, false, "The unsupported feature is not checked.");
info("Click the unsupported checkbox.");
checkbox.click();
is(checkbox.checked, false, "After clicking it, it's still not checked.");
}
});
const { revertRecordingPreferences } = ChromeUtils.import(
"resource://devtools/client/performance-new/popup/background.jsm.js"
);
revertRecordingPreferences();
});
/**
* @param {HTMLDocument} document
* @param {string} feature
* @return {HTMLElement}
*/
function getFeatureCheckbox(document, feature) {
const element = document.querySelector(`input[value="${feature}"]`);
if (!element) {
throw new Error("Could not find the checkbox for the feature: " + feature);
}
return element;
}

Просмотреть файл

@ -12,7 +12,7 @@ add_task(async function test() {
"This test assumes that the JavaScript feature is available on every platform."
);
await openAboutProfiling(async document => {
await withAboutProfiling(async document => {
const jsInput = await getNearestInputFromText(document, "JavaScript");
ok(

Просмотреть файл

@ -14,7 +14,7 @@ add_task(async function test() {
return;
}
await openAboutProfiling(async document => {
await withAboutProfiling(async document => {
const webdevPreset = await getNearestInputFromText(
document,
"Web Developer"

Просмотреть файл

@ -12,7 +12,7 @@ add_task(async function test() {
return;
}
await openAboutProfiling(async document => {
await withAboutProfiling(async document => {
const webdev = await getNearestInputFromText(document, "Web Developer");
ok(webdev.checked, "By default the Web Developer preset is selected.");

Просмотреть файл

@ -6,7 +6,7 @@
add_task(async function test() {
info("Test that about:profiling can be loaded, and the threads changed.");
await openAboutProfiling(async document => {
await withAboutProfiling(async document => {
const geckoMainLabel = await getElementFromDocumentByText(
document,
"GeckoMain"

Просмотреть файл

@ -1,67 +0,0 @@
/* 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 that the popup offers to restart the browser to set an enviroment flag."
);
if (!Services.profiler.GetFeatures().includes("jstracer")) {
ok(
true,
"JS tracer is not supported on this platform, or is currently disabled. Skip the rest of the test."
);
return;
}
{
info("Ensure that JS Tracer is not currently enabled.");
const {
getEnvironmentVariable,
} = require("devtools/client/performance-new/browser");
ok(
!getEnvironmentVariable("JS_TRACE_LOGGING"),
"The JS_TRACE_LOGGING is not currently enabled."
);
}
await makeSureProfilerPopupIsEnabled();
toggleOpenProfilerPopup();
{
info("Open up the features section.");
const features = await getElementFromPopupByText("Features:");
features.click();
}
{
info(
"Test that there is offer to restart the browser when first loading up the popup."
);
const noRestartButton = maybeGetElementFromPopupByText("Restart");
ok(!noRestartButton, "There is no button to restart the browser.");
}
const jsTracerFeature = await getElementFromPopupByText("JSTracer");
{
info("Toggle the jstracer feature on.");
jsTracerFeature.click();
const restartButton = await getElementFromPopupByText("Restart");
ok(restartButton, "There is now a button to offer to restart the browser");
}
{
info("Toggle the jstracer feature back off.");
jsTracerFeature.click();
const noRestartButton = maybeGetElementFromPopupByText("Restart");
ok(!noRestartButton, "The offer to restart the browser goes away.");
}
await closePopup();
});

Просмотреть файл

@ -1,69 +0,0 @@
/* 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 that the popup offers to restart the browser to set an enviroment flag."
);
const supportedFeatures = Services.profiler.GetFeatures();
const allFeatures = Services.profiler.GetAllFeatures();
const unsupportedFeatures = allFeatures.filter(
feature => !supportedFeatures.includes(feature)
);
if (unsupportedFeatures.length === 0) {
ok(true, "This platform has no unsupported features. Skip this test.");
return;
}
await makeSureProfilerPopupIsEnabled();
toggleOpenProfilerPopup();
{
info("Open up the features section.");
const features = await getElementFromPopupByText("Features:");
features.click();
}
{
info("Find and click a supported feature to toggle it.");
const [firstSupportedFeature] = supportedFeatures;
const checkbox = getFeatureCheckbox(firstSupportedFeature);
const initialValue = checkbox.checked;
info("Click the supported checkbox.");
checkbox.click();
is(initialValue, !checkbox.checked, "A supported feature can be toggled.");
checkbox.click();
}
{
info("Find and click an unsupported feature, it should be disabled.");
const [firstUnsupportedFeature] = unsupportedFeatures;
const checkbox = getFeatureCheckbox(firstUnsupportedFeature);
is(checkbox.checked, false, "The unsupported feature is not checked.");
info("Click the unsupported checkbox.");
checkbox.click();
is(checkbox.checked, false, "After clicking it, it's still not checked.");
}
await closePopup();
});
/**
* @param {string} feature
* @return {HTMLElement}
*/
function getFeatureCheckbox(feature) {
const element = getIframeDocument().querySelector(
`input[value="${feature}"]`
);
if (!element) {
throw new Error("Could not find the checkbox for the feature: " + feature);
}
return element;
}

Просмотреть файл

@ -13,16 +13,16 @@ add_task(async function test() {
"http://example.com/browser/devtools/client/performance-new/test/browser/fake-frontend.html"
);
await makeSureProfilerPopupIsEnabled();
toggleOpenProfilerPopup();
await toggleOpenProfilerPopup();
{
const button = await getElementFromPopupByText("Start recording");
const button = await getElementByLabel(document, "Start Recording");
info("Click the button to start recording.");
button.click();
}
{
const button = await getElementFromPopupByText("Capture recording");
const button = await getElementByLabel(document, "Capture");
info("Click the button to capture the recording.");
button.click();
}

Просмотреть файл

@ -0,0 +1,34 @@
/* 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 that the profiler popup recording can be discarded.");
await setProfilerFrontendUrl(
"http://example.com/browser/devtools/client/performance-new/test/browser/fake-frontend.html"
);
await makeSureProfilerPopupIsEnabled();
await toggleOpenProfilerPopup();
{
const button = await getElementByLabel(document, "Start Recording");
info("Click the button to start recording.");
button.click();
}
{
const button = await getElementByLabel(document, "Discard");
info("Click the button to discard the recording.");
button.click();
}
{
const button = await getElementByLabel(document, "Start Recording");
ok(
Boolean(button),
"The popup reverted back to be able to start recording again"
);
}
});

Просмотреть файл

@ -71,6 +71,21 @@ async function waitUntil(condition, message) {
}
}
/**
* This function looks inside of a document for some element that has a label.
* It runs in a loop every requestAnimationFrame until it finds the element. If
* it doesn't find the element it throws an error.
*
* @param {string} label
* @returns {Promise<HTMLElement>}
*/
function getElementByLabel(document, label) {
return waitUntil(
() => document.querySelector(`[label="${label}"]`),
`Trying to find the button with the label "${label}".`
);
}
/**
* This function will select a node from the XPath.
* @returns {HTMLElement?}
@ -85,27 +100,6 @@ function getElementByXPath(document, path) {
).singleNodeValue;
}
/**
* This function looks inside of the profiler popup's iframe for some element
* that contains some text. It runs in a loop every requestAnimationFrame until
* it finds an element. If it doesn't find the element it throws an error.
* It also doesn't assume the popup will be visible yet, as this popup showing
* is an async event.
* @param {string} text
* @param {number} maxTicks (optional)
* @returns {Promise<HTMLElement>}
*/
async function getElementFromPopupByText(text) {
const xpath = `//*[contains(text(), '${text}')]`;
return waitUntil(() => {
const iframe = document.getElementById("PanelUI-profilerIframe");
if (iframe) {
return getElementByXPath(iframe.contentDocument, xpath);
}
return null;
}, `Trying to find the element with the text "${text}".`);
}
/**
* This function looks inside of a document for some element that contains
* the given text. It runs in a loop every requestAnimationFrame until it
@ -122,16 +116,18 @@ async function getElementFromDocumentByText(document, text) {
`Trying to find the element with the text "${text}".`
);
}
/**
* This function is similar to getElementFromPopupByText, but it immediately
* This function is similar to getElementFromDocumentByText, but it immediately
* returns and does not wait for an element to exist.
* @param {HTMLDocument} document
* @param {string} text
* @returns {HTMLElement?}
*/
function maybeGetElementFromPopupByText(text) {
function maybeGetElementFromDocumentByText(document, text) {
info(`Immediately trying to find the element with the text "${text}".`);
const xpath = `//*[contains(text(), '${text}')]`;
return getElementByXPath(getIframeDocument(), xpath);
return getElementByXPath(document, xpath);
}
/**
@ -188,9 +184,10 @@ async function makeSureProfilerPopupIsEnabled() {
/**
* This function toggles the profiler menu button, and then uses user gestures
* to click it open.
* to click it open. It waits a tick to make sure it has a chance to initialize.
* @return {Promise<void>}
*/
function toggleOpenProfilerPopup() {
async function toggleOpenProfilerPopup() {
info("Toggle open the profiler popup.");
info("> Find the profiler menu button.");
@ -201,6 +198,7 @@ function toggleOpenProfilerPopup() {
info("> Trigger a click on the profiler menu button.");
profilerButton.click();
await tick();
}
/**
@ -322,7 +320,7 @@ async function closePopup() {
* @param {(Document) => T} callback
* @returns {Promise<T>}
*/
function openAboutProfiling(callback) {
function withAboutProfiling(callback) {
info("Begin to open about:profiling in a new tab.");
return BrowserTestUtils.withNewTab(
"about:profiling",

Просмотреть файл

@ -196,7 +196,7 @@ function createPerfComponent() {
const reducers = require("devtools/client/performance-new/store/reducers");
const actions = require("devtools/client/performance-new/store/actions");
const selectors = require("devtools/client/performance-new/store/selectors");
const { getRecordingPreferencesFromBrowser } = ChromeUtils.import(
const { getRecordingPreferencesFromBrowser, presets } = ChromeUtils.import(
"resource://devtools/client/performance-new/popup/background.jsm.js"
);
@ -223,6 +223,7 @@ function createPerfComponent() {
receiveProfile: receiveProfileMock,
recordingPreferences: getRecordingPreferencesFromBrowser(),
setRecordingPreferences: recordingPreferencesMock,
presets,
getSymbolTableGetter: () => noop,
pageContext: "devtools",
supportedFeatures: perfFrontMock.getSupportedFeatures(),