Bug 1302062 - Use React on performance recording list; r=jsantell

--HG--
extra : rebase_source : 72db3e85afc693f6ebb2688855b2509bc4f7d6bb
This commit is contained in:
Greg Tatum 2016-09-20 09:47:59 -05:00
parent 548a4d6be0
commit 8cc8c5166b
33 changed files with 541 additions and 268 deletions

View File

@ -8,6 +8,8 @@ DevToolsModules(
'jit-optimizations.js', 'jit-optimizations.js',
'recording-button.js', 'recording-button.js',
'recording-controls.js', 'recording-controls.js',
'recording-list-item.js',
'recording-list.js',
'waterfall-header.js', 'waterfall-header.js',
'waterfall-tree-row.js', 'waterfall-tree-row.js',
'waterfall-tree.js', 'waterfall-tree.js',

View File

@ -0,0 +1,49 @@
/* 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 {DOM, createClass} = require("devtools/client/shared/vendor/react");
const {div, li, span, button} = DOM;
const {L10N} = require("devtools/client/performance/modules/global");
module.exports = createClass({
displayName: "Recording List Item",
render() {
const {
label,
duration,
onSelect,
onSave,
isLoading,
isSelected,
isRecording
} = this.props;
const className = `recording-list-item ${isSelected ? "selected" : ""}`;
let durationText;
if (isLoading) {
durationText = L10N.getStr("recordingsList.loadingLabel");
} else if (isRecording) {
durationText = L10N.getStr("recordingsList.recordingLabel");
} else {
durationText = L10N.getFormatStr("recordingsList.durationLabel", duration);
}
return (
li({ className, onClick: onSelect },
div({ className: "recording-list-item-label" },
label
),
div({ className: "recording-list-item-footer" },
span({ className: "recording-list-item-duration" }, durationText),
button({ className: "recording-list-item-save", onClick: onSave },
L10N.getStr("recordingsList.saveLabel")
)
)
)
);
}
});

View File

@ -0,0 +1,23 @@
/* 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 {DOM, createClass} = require("devtools/client/shared/vendor/react");
const {L10N} = require("devtools/client/performance/modules/global");
const {ul, div} = DOM;
module.exports = createClass({
displayName: "Recording List",
render() {
const {
items,
itemComponent: Item,
} = this.props;
return items.length > 0
? ul({ className: "recording-list" }, ...items.map(Item))
: div({ className: "recording-list-empty" }, L10N.getStr("noRecordingsText"));
}
});

View File

@ -27,13 +27,16 @@ Object.defineProperty(this, "EVENTS", {
}); });
/* exported React, ReactDOM, JITOptimizationsView, RecordingControls, RecordingButton, /* exported React, ReactDOM, JITOptimizationsView, RecordingControls, RecordingButton,
Waterfall, Services, promise, EventEmitter, DevToolsUtils, system */ RecordingList, RecordingListItem, Services, Waterfall, promise, EventEmitter,
DevToolsUtils, system */
var React = require("devtools/client/shared/vendor/react"); var React = require("devtools/client/shared/vendor/react");
var ReactDOM = require("devtools/client/shared/vendor/react-dom"); var ReactDOM = require("devtools/client/shared/vendor/react-dom");
var Waterfall = React.createFactory(require("devtools/client/performance/components/waterfall")); var Waterfall = React.createFactory(require("devtools/client/performance/components/waterfall"));
var JITOptimizationsView = React.createFactory(require("devtools/client/performance/components/jit-optimizations")); var JITOptimizationsView = React.createFactory(require("devtools/client/performance/components/jit-optimizations"));
var RecordingControls = React.createFactory(require("devtools/client/performance/components/recording-controls")); var RecordingControls = React.createFactory(require("devtools/client/performance/components/recording-controls"));
var RecordingButton = React.createFactory(require("devtools/client/performance/components/recording-button")); var RecordingButton = React.createFactory(require("devtools/client/performance/components/recording-button"));
var RecordingList = React.createFactory(require("devtools/client/performance/components/recording-list"));
var RecordingListItem = React.createFactory(require("devtools/client/performance/components/recording-list-item"));
var Services = require("Services"); var Services = require("Services");
var promise = require("promise"); var promise = require("promise");

View File

@ -84,7 +84,9 @@
<hbox id="recordings-controls"> <hbox id="recordings-controls">
<html:div id='recording-controls-mount'/> <html:div id='recording-controls-mount'/>
</hbox> </hbox>
<vbox id="recordings-list" class="theme-sidebar" flex="1"/> <vbox id="recordings-list" class="theme-sidebar" flex="1">
<html:div id="recording-list-mount"/>
</vbox>
</vbox> </vbox>
<!-- Main panel content --> <!-- Main panel content -->

View File

@ -34,11 +34,18 @@ add_task(function* () {
JsCallTreeView._populateCallTree(threadNode); JsCallTreeView._populateCallTree(threadNode);
JsCallTreeView.emit(EVENTS.UI_JS_CALL_TREE_RENDERED); JsCallTreeView.emit(EVENTS.UI_JS_CALL_TREE_RENDERED);
let firstTreeItem = $("#js-calltree-view .call-tree-item");
// DE-XUL: There are focus issues with XUL. Focus first, then synthesize the clicks
// so that keyboard events work correctly.
firstTreeItem.focus();
let count = 0; let count = 0;
let onFocus = () => count++; let onFocus = () => count++;
JsCallTreeView.on("focus", onFocus); JsCallTreeView.on("focus", onFocus);
click($("#js-calltree-view .call-tree-item")); click(firstTreeItem);
key("VK_DOWN"); key("VK_DOWN");
key("VK_DOWN"); key("VK_DOWN");
key("VK_DOWN"); key("VK_DOWN");

View File

@ -10,6 +10,7 @@
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls"); const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils"); const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -21,7 +22,7 @@ add_task(function* () {
yield console.profileEnd("rust"); yield console.profileEnd("rust");
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView, WaterfallView } = panel.panelWin; let { PerformanceController, WaterfallView } = panel.panelWin;
yield waitUntil(() => PerformanceController.getRecordings().length == 1); yield waitUntil(() => PerformanceController.getRecordings().length == 1);
yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce); yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce);
@ -31,9 +32,11 @@ add_task(function* () {
is(recordings[0].isConsole(), true, "Recording came from console.profile."); is(recordings[0].isConsole(), true, "Recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "Correct label in the recording model."); is(recordings[0].getLabel(), "rust", "Correct label in the recording model.");
is(RecordingsView.selectedItem.attachment, recordings[0], const selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The profile from console should be selected as it's the only one."); "The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
yield teardownToolboxAndRemoveTab(panel); yield teardownToolboxAndRemoveTab(panel);

View File

@ -13,6 +13,7 @@ const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab }
const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils"); const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { times } = require("devtools/client/performance/test/helpers/event-utils"); const { times } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -24,7 +25,7 @@ add_task(function* () {
yield console.profile("rust2"); yield console.profile("rust2");
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
yield waitUntil(() => PerformanceController.getRecordings().length == 2); yield waitUntil(() => PerformanceController.getRecordings().length == 2);
@ -37,9 +38,10 @@ add_task(function* () {
is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2)."); is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2)."); is(recordings[1].isRecording(), true, "Recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0], const selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The first console recording should be selected."); "The first console recording should be selected.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
// Ensure overview is still rendering. // Ensure overview is still rendering.

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils"); const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -23,7 +24,7 @@ add_task(function* () {
yield console.profile("rust2"); yield console.profile("rust2");
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView, WaterfallView } = panel.panelWin; let { PerformanceController, WaterfallView } = panel.panelWin;
yield waitUntil(() => PerformanceController.getRecordings().length == 2); yield waitUntil(() => PerformanceController.getRecordings().length == 2);
yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce); yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce);
@ -37,9 +38,10 @@ add_task(function* () {
is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2)."); is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2)."); is(recordings[1].isRecording(), true, "Recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0], const selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The first console recording should be selected."); "The first console recording should be selected.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
let stopped = waitForRecordingStoppedEvents(panel, { let stopped = waitForRecordingStoppedEvents(panel, {

View File

@ -12,6 +12,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils"); const { times } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -20,7 +21,7 @@ add_task(function* () {
}); });
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, { let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
@ -35,9 +36,10 @@ add_task(function* () {
is(recordings[0].getLabel(), "rust", "Correct label in the recording model."); is(recordings[0].getLabel(), "rust", "Correct label in the recording model.");
is(recordings[0].isRecording(), true, "Recording is still recording."); is(recordings[0].isRecording(), true, "Recording is still recording.");
is(RecordingsView.selectedItem.attachment, recordings[0], const selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The profile from console should be selected as it's the only one."); "The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
// Ensure overview is still rendering. // Ensure overview is still rendering.

View File

@ -12,6 +12,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils"); const { times } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -20,7 +21,7 @@ add_task(function* () {
}); });
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, { let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
@ -35,9 +36,10 @@ add_task(function* () {
is(recordings[0].getLabel(), "rust", "Correct label in the recording model (1)."); is(recordings[0].getLabel(), "rust", "Correct label in the recording model (1).");
is(recordings[0].isRecording(), true, "Recording is still recording (1)."); is(recordings[0].isRecording(), true, "Recording is still recording (1).");
is(RecordingsView.selectedItem.attachment, recordings[0], let selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The profile from console should be selected as it's the only one."); "The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
// Ensure overview is still rendering. // Ensure overview is still rendering.
@ -70,9 +72,10 @@ add_task(function* () {
is(recordings[1].getLabel(), "rust", "Correct label in the recording model (2)."); is(recordings[1].getLabel(), "rust", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2)."); is(recordings[1].isRecording(), true, "Recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0], selected = getSelectedRecording(panel);
is(selected, recordings[0],
"The profile from console should still be selected"); "The profile from console should still be selected");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust", is(selected.getLabel(), "rust",
"The profile label for the first recording is correct."); "The profile label for the first recording is correct.");
stopped = waitForRecordingStoppedEvents(panel, { stopped = waitForRecordingStoppedEvents(panel, {

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils"); const { times } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -19,7 +20,7 @@ add_task(function* () {
}); });
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, { let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
@ -30,7 +31,7 @@ add_task(function* () {
let recordings = PerformanceController.getRecordings(); let recordings = PerformanceController.getRecordings();
is(recordings.length, 1, "A recording found in the performance panel."); is(recordings.length, 1, "A recording found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(getSelectedRecording(panel), recordings[0],
"The first console recording should be selected."); "The first console recording should be selected.");
// Ensure overview is still rendering. // Ensure overview is still rendering.
@ -52,7 +53,7 @@ add_task(function* () {
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "Two recordings found in the performance panel."); is(recordings.length, 2, "Two recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(getSelectedRecording(panel), recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
// Ensure overview is still rendering. // Ensure overview is still rendering.
@ -69,7 +70,7 @@ add_task(function* () {
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "Two recordings found in the performance panel."); is(recordings.length, 2, "Two recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(getSelectedRecording(panel), recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
is(recordings[0].isRecording(), false, is(recordings[0].isRecording(), false,
"The first console recording should no longer be recording."); "The first console recording should no longer be recording.");
@ -86,7 +87,7 @@ add_task(function* () {
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "Two recordings found in the performance panel."); is(recordings.length, 2, "Two recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(getSelectedRecording(panel), recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
is(recordings[1].isRecording(), false, is(recordings[1].isRecording(), false,
"The second console recording should no longer be recording."); "The second console recording should no longer be recording.");

View File

@ -12,6 +12,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { idleWait } = require("devtools/client/performance/test/helpers/wait-utils"); const { idleWait } = require("devtools/client/performance/test/helpers/wait-utils");
const { getSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { target, console } = yield initConsoleInNewTab({ let { target, console } = yield initConsoleInNewTab({
@ -20,7 +21,7 @@ add_task(function* () {
}); });
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView } = panel.panelWin; let { PerformanceController } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, { let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
@ -54,11 +55,12 @@ add_task(function* () {
yield started; yield started;
let recordings = PerformanceController.getRecordings(); let recordings = PerformanceController.getRecordings();
let selected = getSelectedRecording(panel);
is(recordings.length, 3, "Three recordings found in the performance panel."); is(recordings.length, 3, "Three recordings found in the performance panel.");
is(recordings[0].getLabel(), "", "Checking label of recording 1"); is(recordings[0].getLabel(), "", "Checking label of recording 1");
is(recordings[1].getLabel(), "1", "Checking label of recording 2"); is(recordings[1].getLabel(), "1", "Checking label of recording 2");
is(recordings[2].getLabel(), "2", "Checking label of recording 3"); is(recordings[2].getLabel(), "2", "Checking label of recording 3");
is(RecordingsView.selectedItem.attachment, recordings[0], is(selected, recordings[0],
"The first console recording should be selected."); "The first console recording should be selected.");
is(recordings[0].isRecording(), true, is(recordings[0].isRecording(), true,
@ -81,9 +83,10 @@ add_task(function* () {
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
selected = getSelectedRecording(panel);
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel."); is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(selected, recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
is(recordings[0].isRecording(), true, "The not most recent recording should not stop " + is(recordings[0].isRecording(), true, "The not most recent recording should not stop " +
@ -97,9 +100,10 @@ add_task(function* () {
console.profileEnd("fxos"); console.profileEnd("fxos");
yield idleWait(1000); yield idleWait(1000);
selected = getSelectedRecording(panel);
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel."); is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(selected, recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
is(recordings[0].isRecording(), true, is(recordings[0].isRecording(), true,
@ -122,9 +126,10 @@ add_task(function* () {
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
selected = getSelectedRecording(panel);
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel."); is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(selected, recordings[0],
"The first console recording should still be selected."); "The first console recording should still be selected.");
is(recordings[0].isRecording(), true, is(recordings[0].isRecording(), true,
@ -141,9 +146,10 @@ add_task(function* () {
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
selected = getSelectedRecording(panel);
recordings = PerformanceController.getRecordings(); recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel."); is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0], is(selected, recordings[0],
"The first console recording should be selected."); "The first console recording should be selected.");
is(recordings[0].isRecording(), false, is(recordings[0].isRecording(), false,

View File

@ -13,6 +13,31 @@ const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab }
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions"); const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { once, times } = require("devtools/client/performance/test/helpers/event-utils"); const { once, times } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
/**
* The following are bit flag constants that are used to represent the state of a
* recording.
*/
// Represents a manually recorded profile, if a user hit the record button.
const MANUAL = 0;
// Represents a recorded profile from console.profile().
const CONSOLE = 1;
// Represents a profile that is currently recording.
const RECORDING = 2;
// Represents a profile that is currently selected.
const SELECTED = 4;
/**
* Utility function to provide a meaningful inteface for testing that the bits
* match for the recording state.
* @param {integer} expected - The expected bit values packed in an integer.
* @param {integer} actual - The actual bit values packed in an integer.
*/
function hasBitFlag(expected, actual) {
return !!(expected & actual);
}
add_task(function* () { add_task(function* () {
// This test seems to take a very long time to finish on Linux VMs. // This test seems to take a very long time to finish on Linux VMs.
@ -24,22 +49,27 @@ add_task(function* () {
}); });
let { panel } = yield initPerformanceInTab({ tab: target.tab }); let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, RecordingsView, OverviewView } = panel.panelWin; let { EVENTS, PerformanceController, OverviewView } = panel.panelWin;
info("Starting console.profile()..."); info("Recording 1 - Starting console.profile()...");
let started = waitForRecordingStartedEvents(panel, { let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
skipWaitingForBackendReady: true skipWaitingForBackendReady: true
}); });
yield console.profile("rust"); yield console.profile("rust");
yield started; yield started;
testRecordings(PerformanceController, [C + S + R]); testRecordings(PerformanceController, [
CONSOLE + SELECTED + RECORDING
]);
info("Starting manual recording..."); info("Recording 2 - Starting manual recording...");
yield startRecording(panel); yield startRecording(panel);
testRecordings(PerformanceController, [C + R, R + S]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + RECORDING + SELECTED
]);
info("Starting console.profile(\"3\")..."); info("Recording 3 - Starting console.profile(\"3\")...");
started = waitForRecordingStartedEvents(panel, { started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
skipWaitingForBackendReady: true, skipWaitingForBackendReady: true,
@ -51,9 +81,13 @@ add_task(function* () {
}); });
yield console.profile("3"); yield console.profile("3");
yield started; yield started;
testRecordings(PerformanceController, [C + R, R + S, C + R]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + RECORDING + SELECTED,
CONSOLE + RECORDING
]);
info("Starting console.profile(\"4\")..."); info("Recording 4 - Starting console.profile(\"4\")...");
started = waitForRecordingStartedEvents(panel, { started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
skipWaitingForBackendReady: true, skipWaitingForBackendReady: true,
@ -65,9 +99,14 @@ add_task(function* () {
}); });
yield console.profile("4"); yield console.profile("4");
yield started; yield started;
testRecordings(PerformanceController, [C + R, R + S, C + R, C + R]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + RECORDING + SELECTED,
CONSOLE + RECORDING,
CONSOLE + RECORDING
]);
info("Ending console.profileEnd()..."); info("Recording 4 - Ending console.profileEnd()...");
let stopped = waitForRecordingStoppedEvents(panel, { let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
skipWaitingForBackendReady: true, skipWaitingForBackendReady: true,
@ -80,27 +119,48 @@ add_task(function* () {
}); });
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
testRecordings(PerformanceController, [C + R, R + S, C + R, C]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + RECORDING + SELECTED,
CONSOLE + RECORDING,
CONSOLE
]);
info("Select last recording..."); info("Recording 4 - Select last recording...");
let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 3; setSelectedRecording(panel, 3);
yield recordingSelected; yield recordingSelected;
testRecordings(PerformanceController, [C + R, R, C + R, C + S]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + RECORDING,
CONSOLE + RECORDING,
CONSOLE + SELECTED
]);
ok(!OverviewView.isRendering(), ok(!OverviewView.isRendering(),
"Stop rendering overview when a completed recording is selected."); "Stop rendering overview when a completed recording is selected.");
info("Stop manual recording..."); info("Recording 2 - Stop manual recording.");
yield stopRecording(panel); yield stopRecording(panel);
testRecordings(PerformanceController, [C + R, S, C + R, C]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL + SELECTED,
CONSOLE + RECORDING,
CONSOLE
]);
ok(!OverviewView.isRendering(), ok(!OverviewView.isRendering(),
"Stop rendering overview when a completed recording is selected."); "Stop rendering overview when a completed recording is selected.");
info("Select first recording..."); info("Recording 1 - Select first recording.");
recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED); recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield recordingSelected; yield recordingSelected;
testRecordings(PerformanceController, [C + R + S, 0, C + R, C]); testRecordings(PerformanceController, [
CONSOLE + RECORDING + SELECTED,
MANUAL,
CONSOLE + RECORDING,
CONSOLE
]);
ok(OverviewView.isRendering(), ok(OverviewView.isRendering(),
"Should be rendering overview a recording in progress is selected."); "Should be rendering overview a recording in progress is selected.");
@ -122,7 +182,12 @@ add_task(function* () {
}); });
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
testRecordings(PerformanceController, [C + R + S, 0, C, C]); testRecordings(PerformanceController, [
CONSOLE + RECORDING + SELECTED,
MANUAL,
CONSOLE,
CONSOLE
]);
ok(OverviewView.isRendering(), ok(OverviewView.isRendering(),
"Should be rendering overview a recording in progress is selected."); "Should be rendering overview a recording in progress is selected.");
@ -131,9 +196,15 @@ add_task(function* () {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL } expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
}); });
info("Start one more manual recording..."); info("Recording 5 - Start one more manual recording.");
yield startRecording(panel); yield startRecording(panel);
testRecordings(PerformanceController, [C + R, 0, C, C, R + S]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL,
CONSOLE,
CONSOLE,
MANUAL + RECORDING + SELECTED
]);
ok(OverviewView.isRendering(), ok(OverviewView.isRendering(),
"Should be rendering overview a recording in progress is selected."); "Should be rendering overview a recording in progress is selected.");
@ -142,13 +213,19 @@ add_task(function* () {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL } expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
}); });
info("Stop manual recording..."); info("Recording 5 - Stop manual recording.");
yield stopRecording(panel); yield stopRecording(panel);
testRecordings(PerformanceController, [C + R, 0, C, C, S]); testRecordings(PerformanceController, [
CONSOLE + RECORDING,
MANUAL,
CONSOLE,
CONSOLE,
MANUAL + SELECTED
]);
ok(!OverviewView.isRendering(), ok(!OverviewView.isRendering(),
"Stop rendering overview when a completed recording is selected."); "Stop rendering overview when a completed recording is selected.");
info("Ending console.profileEnd()..."); info("Recording 1 - Ending console.profileEnd()...");
stopped = waitForRecordingStoppedEvents(panel, { stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings // only emitted for manual recordings
skipWaitingForBackendReady: true, skipWaitingForBackendReady: true,
@ -161,31 +238,31 @@ add_task(function* () {
}); });
yield console.profileEnd(); yield console.profileEnd();
yield stopped; yield stopped;
testRecordings(PerformanceController, [C, 0, C, C, S]); testRecordings(PerformanceController, [
CONSOLE,
MANUAL,
CONSOLE,
CONSOLE,
MANUAL + SELECTED
]);
ok(!OverviewView.isRendering(), ok(!OverviewView.isRendering(),
"Stop rendering overview when a completed recording is selected."); "Stop rendering overview when a completed recording is selected.");
yield teardownToolboxAndRemoveTab(panel); yield teardownToolboxAndRemoveTab(panel);
}); });
// is console function testRecordings(controller, expectedBitFlags) {
const C = 1;
// is recording
const R = 2;
// is selected
const S = 4;
function testRecordings(controller, expected) {
let recordings = controller.getRecordings(); let recordings = controller.getRecordings();
let current = controller.getCurrentRecording(); let current = controller.getCurrentRecording();
is(recordings.length, expected.length, "Expected number of recordings."); is(recordings.length, expectedBitFlags.length, "Expected number of recordings.");
recordings.forEach((recording, i) => { recordings.forEach((recording, i) => {
ok(recording.isConsole() == !!(expected[i] & C), const expected = expectedBitFlags[i];
is(recording.isConsole(), hasBitFlag(expected, CONSOLE),
`Recording ${i + 1} has expected console state.`); `Recording ${i + 1} has expected console state.`);
ok(recording.isRecording() == !!(expected[i] & R), is(recording.isRecording(), hasBitFlag(expected, RECORDING),
`Recording ${i + 1} has expected console state.`); `Recording ${i + 1} has expected console state.`);
ok((recording == current) == !!(expected[i] & S), is((recording == current), hasBitFlag(expected, SELECTED),
`Recording ${i + 1} has expected selected state.`); `Recording ${i + 1} has expected selected state.`);
}); });
} }

View File

@ -14,6 +14,7 @@ const { UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -24,7 +25,6 @@ add_task(function* () {
let { let {
EVENTS, EVENTS,
$, $,
RecordingsView,
DetailsView, DetailsView,
WaterfallView, WaterfallView,
MemoryCallTreeView, MemoryCallTreeView,
@ -80,7 +80,7 @@ add_task(function* () {
// Select the first recording with no memory data. // Select the first recording with no memory data.
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED); selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED); rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
yield rendered; yield rendered;
@ -94,7 +94,7 @@ add_task(function* () {
// Go back to the recording with memory data. // Go back to the recording with memory data.
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED); rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield rendered; yield rendered;
ok(DetailsView.isViewSelected(WaterfallView), ok(DetailsView.isViewSelected(WaterfallView),

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording, getSelectedRecordingIndex } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -22,7 +23,6 @@ add_task(function* () {
EVENTS, EVENTS,
$, $,
PerformanceController, PerformanceController,
RecordingsView,
WaterfallView WaterfallView
} = panel.panelWin; } = panel.panelWin;
@ -84,11 +84,12 @@ add_task(function* () {
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
let rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED); let rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
yield rendered; yield rendered;
is(RecordingsView.selectedIndex, 0, let selectedIndex = getSelectedRecordingIndex(panel);
is(selectedIndex, 0,
"The first recording was selected again."); "The first recording was selected again.");
is(waterfallBtn.hidden, false, is(waterfallBtn.hidden, false,
@ -103,10 +104,11 @@ add_task(function* () {
"The `memory-calltree` button is hidden when first recording selected."); "The `memory-calltree` button is hidden when first recording selected.");
selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield selected; yield selected;
is(RecordingsView.selectedIndex, 1, selectedIndex = getSelectedRecordingIndex(panel);
is(selectedIndex, 1,
"The second recording was selected again."); "The second recording was selected again.");
is(waterfallBtn.hidden, true, is(waterfallBtn.hidden, true,
@ -124,7 +126,8 @@ add_task(function* () {
yield stopRecording(panel); yield stopRecording(panel);
yield rendered; yield rendered;
is(RecordingsView.selectedIndex, 1, selectedIndex = getSelectedRecordingIndex(panel);
is(selectedIndex, 1,
"The second recording is still selected."); "The second recording is still selected.");
is(waterfallBtn.hidden, false, is(waterfallBtn.hidden, false,

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecording, getDurationLabelText } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -18,12 +19,11 @@ add_task(function* () {
win: window win: window
}); });
let { EVENTS, L10N, $, PerformanceController, RecordingsView } = panel.panelWin; let { EVENTS, L10N, PerformanceController } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
let durationLabel = $(".recording-item-duration", RecordingsView.selectedItem.target); is(getDurationLabelText(panel, 0),
is(durationLabel.getAttribute("value"),
L10N.getStr("recordingsList.recordingLabel"), L10N.getStr("recordingsList.recordingLabel"),
"The duration node should show the 'recording' message while recording"); "The duration node should show the 'recording' message while recording");
@ -36,14 +36,15 @@ add_task(function* () {
let everythingStopped = stopRecording(panel); let everythingStopped = stopRecording(panel);
yield recordingStopping; yield recordingStopping;
is(durationLabel.getAttribute("value"), is(getDurationLabelText(panel, 0),
L10N.getStr("recordingsList.loadingLabel"), L10N.getStr("recordingsList.loadingLabel"),
"The duration node should show the 'loading' message while stopping"); "The duration node should show the 'loading' message while stopping");
yield recordingStopped; yield recordingStopped;
is(durationLabel.getAttribute("value"), const selected = getSelectedRecording(panel);
is(getDurationLabelText(panel, 0),
L10N.getFormatStr("recordingsList.durationLabel", L10N.getFormatStr("recordingsList.durationLabel",
RecordingsView.selectedItem.attachment.getDuration().toFixed(0)), selected.getDuration().toFixed(0)),
"The duration node should show the duration after the record has stopped"); "The duration node should show the duration after the record has stopped");
yield everythingStopped; yield everythingStopped;

View File

@ -13,6 +13,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecordingIndex, setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -20,7 +21,7 @@ add_task(function* () {
win: window win: window
}); });
let { EVENTS, $, PerformanceController, RecordingsView } = panel.panelWin; let { EVENTS, $, PerformanceController } = panel.panelWin;
let detailsContainer = $("#details-pane-container"); let detailsContainer = $("#details-pane-container");
let recordingNotice = $("#recording-notice"); let recordingNotice = $("#recording-notice");
let loadingNotice = $("#loading-notice"); let loadingNotice = $("#loading-notice");
@ -52,7 +53,7 @@ add_task(function* () {
info("While the 2nd record is still going, switch to the first one."); info("While the 2nd record is still going, switch to the first one.");
let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield recordingSelected; yield recordingSelected;
recordingStopping = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, { recordingStopping = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
@ -66,14 +67,14 @@ add_task(function* () {
yield recordingStopping; yield recordingStopping;
is(detailsContainer.selectedPanel, detailsPane, is(detailsContainer.selectedPanel, detailsPane,
"The details panel is still shown while the 2nd record is being stopped."); "The details panel is still shown while the 2nd record is being stopped.");
is(RecordingsView.selectedIndex, 0, is(getSelectedRecordingIndex(panel), 0,
"The first record is still selected."); "The first record is still selected.");
yield recordingStopped; yield recordingStopped;
is(detailsContainer.selectedPanel, detailsPane, is(detailsContainer.selectedPanel, detailsPane,
"The details panel is still shown after the 2nd record has stopped."); "The details panel is still shown after the 2nd record has stopped.");
is(RecordingsView.selectedIndex, 1, is(getSelectedRecordingIndex(panel), 1,
"The second record is now selected."); "The second record is now selected.");
yield everythingStopped; yield everythingStopped;

View File

@ -9,13 +9,13 @@ requestLongerTimeout(2);
* Tests that the JIT Optimizations view renders optimization data * Tests that the JIT Optimizations view renders optimization data
* if on, and displays selected frames on focus. * if on, and displays selected frames on focus.
*/ */
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
Services.prefs.setBoolPref(INVERT_PREF, false); Services.prefs.setBoolPref(INVERT_PREF, false);
function* spawnTest() { function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL); let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, $$, window, PerformanceController } = panel.panelWin; let { EVENTS, $, $$, window, PerformanceController } = panel.panelWin;
let { OverviewView, DetailsView, OptimizationsListView, JsCallTreeView, RecordingsView } = panel.panelWin; let { OverviewView, DetailsView, OptimizationsListView, JsCallTreeView } = panel.panelWin;
let profilerData = { threads: [gThread] }; let profilerData = { threads: [gThread] };
@ -58,14 +58,14 @@ function* spawnTest() {
let select = once(PerformanceController, EVENTS.RECORDING_SELECTED); let select = once(PerformanceController, EVENTS.RECORDING_SELECTED);
rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED); rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield Promise.all([select, rendered]); yield Promise.all([select, rendered]);
isHidden = $("#jit-optimizations-view").classList.contains("hidden"); isHidden = $("#jit-optimizations-view").classList.contains("hidden");
ok(isHidden, "opts view is hidden when switching recordings"); ok(isHidden, "opts view is hidden when switching recordings");
rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED); rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield rendered; yield rendered;
rendered = once(JsCallTreeView, "focus"); rendered = once(JsCallTreeView, "focus");

View File

@ -13,6 +13,7 @@ const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtoo
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils"); const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { isVisible } = require("devtools/client/performance/test/helpers/dom-utils"); const { isVisible } = require("devtools/client/performance/test/helpers/dom-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -20,7 +21,7 @@ add_task(function* () {
win: window win: window
}); });
let { $, EVENTS, PerformanceController, RecordingsView, OverviewView } = panel.panelWin; let { $, EVENTS, PerformanceController, OverviewView } = panel.panelWin;
// Enable memory to test. // Enable memory to test.
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true); Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true);
@ -53,12 +54,12 @@ add_task(function* () {
"Overview graphs hidden again when starting new recording."); "Overview graphs hidden again when starting new recording.");
is(updated, 1, "Overview graphs have not been updated again."); is(updated, 1, "Overview graphs have not been updated again.");
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
is(isVisible($("#overview-pane")), true, is(isVisible($("#overview-pane")), true,
"Overview graphs no longer hidden when switching back to complete recording."); "Overview graphs no longer hidden when switching back to complete recording.");
is(updated, 1, "Overview graphs have not been updated again."); is(updated, 1, "Overview graphs have not been updated again.");
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
is(isVisible($("#overview-pane")), false, is(isVisible($("#overview-pane")), false,
"Overview graphs hidden again when going back to inprogress recording."); "Overview graphs hidden again when going back to inprogress recording.");
is(updated, 1, "Overview graphs have not been updated again."); is(updated, 1, "Overview graphs have not been updated again.");

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -23,7 +24,6 @@ add_task(function* () {
$, $,
PerformanceController, PerformanceController,
PerformanceView, PerformanceView,
RecordingsView
} = panel.panelWin; } = panel.panelWin;
let MAIN_CONTAINER = $("#performance-view"); let MAIN_CONTAINER = $("#performance-view");
@ -42,7 +42,7 @@ add_task(function* () {
is(DETAILS_CONTAINER.selectedPanel, RECORDING, "Showing recording panel."); is(DETAILS_CONTAINER.selectedPanel, RECORDING, "Showing recording panel.");
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
is(PerformanceView.getState(), "recorded", is(PerformanceView.getState(), "recorded",
@ -51,7 +51,7 @@ add_task(function* () {
is(DETAILS_CONTAINER.selectedPanel, DETAILS, "Showing recorded panel."); is(DETAILS_CONTAINER.selectedPanel, DETAILS, "Showing recorded panel.");
selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield selected; yield selected;
is(PerformanceView.getState(), "recording", is(PerformanceView.getState(), "recording",

View File

@ -15,6 +15,7 @@ const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab }
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils"); const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
// Make sure the profiler module is stopped so we can set a new buffer limit. // Make sure the profiler module is stopped so we can set a new buffer limit.
@ -36,7 +37,6 @@ add_task(function* () {
$, $,
PerformanceController, PerformanceController,
PerformanceView, PerformanceView,
RecordingsView
} = panel.panelWin; } = panel.panelWin;
// Set a fast profiler-status update interval. // Set a fast profiler-status update interval.
@ -88,7 +88,7 @@ add_task(function* () {
// Select the console recording. // Select the console recording.
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield selected; yield selected;
yield waitUntil(function* () { yield waitUntil(function* () {
@ -109,7 +109,7 @@ add_task(function* () {
yield console.profileEnd("rust"); yield console.profileEnd("rust");
selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
yield waitUntil(function* () { yield waitUntil(function* () {

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording, getRecordingsCount, getSelectedRecordingIndex } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -18,7 +19,7 @@ add_task(function* () {
win: window win: window
}); });
let { EVENTS, PerformanceController, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
@ -26,18 +27,18 @@ add_task(function* () {
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"There should be two recordings visible."); "There should be two recordings visible.");
is(RecordingsView.selectedIndex, 1, is(getSelectedRecordingIndex(panel), 1,
"The second recording item should be selected."); "The second recording item should be selected.");
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"There should still be two recordings visible."); "There should still be two recordings visible.");
is(RecordingsView.selectedIndex, 0, is(getSelectedRecordingIndex(panel), 0,
"The first recording item should be selected."); "The first recording item should be selected.");
yield teardownToolboxAndRemoveTab(panel); yield teardownToolboxAndRemoveTab(panel);

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { getSelectedRecordingIndex, setSelectedRecording, getRecordingsCount } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
// This test seems to take a very long time to finish on Linux VMs. // This test seems to take a very long time to finish on Linux VMs.
@ -21,38 +22,37 @@ add_task(function* () {
win: window win: window
}); });
let { EVENTS, PerformanceController, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
yield startRecording(panel); yield startRecording(panel);
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"There should be two recordings visible."); "There should be two recordings visible.");
is(RecordingsView.selectedIndex, 1, is(getSelectedRecordingIndex(panel), 1,
"The new recording item should be selected."); "The new recording item should be selected.");
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"There should still be two recordings visible."); "There should still be two recordings visible.");
is(RecordingsView.selectedIndex, 0, is(getSelectedRecordingIndex(panel), 0,
"The first recording item should be selected now."); "The first recording item should be selected now.");
selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield selected; yield selected;
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"There should still be two recordings visible."); "There should still be two recordings visible.");
is(RecordingsView.selectedIndex, 1, is(getSelectedRecordingIndex(panel), 1,
"The second recording item should be selected again."); "The second recording item should be selected again.");
yield stopRecording(panel); yield stopRecording(panel);
yield teardownToolboxAndRemoveTab(panel); yield teardownToolboxAndRemoveTab(panel);
}); });

View File

@ -12,6 +12,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils"); const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -19,7 +20,7 @@ add_task(function* () {
win: window win: window
}); });
let { $, EVENTS, PerformanceController, RecordingsView } = panel.panelWin; let { $, EVENTS, PerformanceController } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
@ -29,7 +30,7 @@ add_task(function* () {
info("Selecting recording #0 and waiting for it to be displayed."); info("Selecting recording #0 and waiting for it to be displayed.");
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED); let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield selected; yield selected;
ok($("#main-record-button").classList.contains("checked"), ok($("#main-record-button").classList.contains("checked"),

View File

@ -10,6 +10,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_MEMORY_PREF, UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs"); const { UI_ENABLE_MEMORY_PREF, UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording, waitForAllWidgetsRendered } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording, waitForAllWidgetsRendered } = require("devtools/client/performance/test/helpers/actions");
const { setSelectedRecording } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPerformanceInNewTab({ let { panel } = yield initPerformanceInNewTab({
@ -17,7 +18,7 @@ add_task(function* () {
win: window win: window
}); });
let { DetailsView, DetailsSubview, RecordingsView } = panel.panelWin; let { DetailsView, DetailsSubview } = panel.panelWin;
// Enable memory to test the memory overview. // Enable memory to test the memory overview.
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true); Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true);
@ -43,13 +44,13 @@ add_task(function* () {
yield stopRecording(panel); yield stopRecording(panel);
let rerender = waitForAllWidgetsRendered(panel); let rerender = waitForAllWidgetsRendered(panel);
RecordingsView.selectedIndex = 0; setSelectedRecording(panel, 0);
yield rerender; yield rerender;
ok(true, "All widgets were rendered when selecting the first recording."); ok(true, "All widgets were rendered when selecting the first recording.");
rerender = waitForAllWidgetsRendered(panel); rerender = waitForAllWidgetsRendered(panel);
RecordingsView.selectedIndex = 1; setSelectedRecording(panel, 1);
yield rerender; yield rerender;
ok(true, "All widgets were rendered when selecting the second recording."); ok(true, "All widgets were rendered when selecting the second recording.");

View File

@ -10,6 +10,7 @@
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls"); const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPanelInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPanelInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { getRecordingsCount } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPanelInNewTab({ let { panel } = yield initPanelInNewTab({
@ -18,13 +19,13 @@ add_task(function* () {
win: window win: window
}); });
let { PerformanceController, PerformanceView, RecordingsView } = panel.panelWin; let { PerformanceController, PerformanceView } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
is(RecordingsView.itemCount, 1, is(getRecordingsCount(panel), 1,
"RecordingsView should have one recording."); "The recordings list should have one recording.");
isnot(PerformanceView.getState(), "empty", isnot(PerformanceView.getState(), "empty",
"PerformanceView should not be in an empty state."); "PerformanceView should not be in an empty state.");
isnot(PerformanceController.getCurrentRecording(), null, isnot(PerformanceController.getCurrentRecording(), null,
@ -33,8 +34,8 @@ add_task(function* () {
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"RecordingsView should have two recordings."); "The recordings list should have two recordings.");
isnot(PerformanceView.getState(), "empty", isnot(PerformanceView.getState(), "empty",
"PerformanceView should not be in an empty state."); "PerformanceView should not be in an empty state.");
isnot(PerformanceController.getCurrentRecording(), null, isnot(PerformanceController.getCurrentRecording(), null,
@ -42,8 +43,8 @@ add_task(function* () {
yield PerformanceController.clearRecordings(); yield PerformanceController.clearRecordings();
is(RecordingsView.itemCount, 0, is(getRecordingsCount(panel), 0,
"RecordingsView should be empty."); "The recordings list should be empty.");
is(PerformanceView.getState(), "empty", is(PerformanceView.getState(), "empty",
"PerformanceView should be in an empty state."); "PerformanceView should be in an empty state.");
is(PerformanceController.getCurrentRecording(), null, is(PerformanceController.getCurrentRecording(), null,

View File

@ -11,6 +11,7 @@ const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPanelInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils"); const { initPanelInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions"); const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { times, once } = require("devtools/client/performance/test/helpers/event-utils"); const { times, once } = require("devtools/client/performance/test/helpers/event-utils");
const { getRecordingsCount } = require("devtools/client/performance/test/helpers/recording-utils");
add_task(function* () { add_task(function* () {
let { panel } = yield initPanelInNewTab({ let { panel } = yield initPanelInNewTab({
@ -19,13 +20,13 @@ add_task(function* () {
win: window win: window
}); });
let { EVENTS, PerformanceController, PerformanceView, RecordingsView } = panel.panelWin; let { EVENTS, PerformanceController, PerformanceView } = panel.panelWin;
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
is(RecordingsView.itemCount, 1, is(getRecordingsCount(panel), 1,
"RecordingsView should have one recording."); "The recordings list should have one recording.");
isnot(PerformanceView.getState(), "empty", isnot(PerformanceView.getState(), "empty",
"PerformanceView should not be in an empty state."); "PerformanceView should not be in an empty state.");
isnot(PerformanceController.getCurrentRecording(), null, isnot(PerformanceController.getCurrentRecording(), null,
@ -33,8 +34,8 @@ add_task(function* () {
yield startRecording(panel); yield startRecording(panel);
is(RecordingsView.itemCount, 2, is(getRecordingsCount(panel), 2,
"RecordingsView should have two recordings."); "The recordings list should have two recordings.");
isnot(PerformanceView.getState(), "empty", isnot(PerformanceView.getState(), "empty",
"PerformanceView should not be in an empty state."); "PerformanceView should not be in an empty state.");
isnot(PerformanceController.getCurrentRecording(), null, isnot(PerformanceController.getCurrentRecording(), null,
@ -50,8 +51,8 @@ add_task(function* () {
yield recordingDeleted; yield recordingDeleted;
yield recordingStopped; yield recordingStopped;
is(RecordingsView.itemCount, 0, is(getRecordingsCount(panel), 0,
"RecordingsView should be empty."); "The recordings list should be empty.");
is(PerformanceView.getState(), "empty", is(PerformanceView.getState(), "empty",
"PerformanceView should be in an empty state."); "PerformanceView should be in an empty state.");
is(PerformanceController.getCurrentRecording(), null, is(PerformanceController.getCurrentRecording(), null,
@ -61,8 +62,8 @@ add_task(function* () {
yield startRecording(panel); yield startRecording(panel);
yield stopRecording(panel); yield stopRecording(panel);
is(RecordingsView.itemCount, 1, is(getRecordingsCount(panel), 1,
"RecordingsView should have one recording."); "The recordings list should have one recording.");
yield teardownToolboxAndRemoveTab(panel); yield teardownToolboxAndRemoveTab(panel);
}); });

View File

@ -12,7 +12,7 @@ var { CATEGORY_MASK } = require("devtools/client/performance/modules/categories"
function* spawnTest() { function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL); let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, $$, window, PerformanceController } = panel.panelWin; let { EVENTS, $, $$, window, PerformanceController } = panel.panelWin;
let { OverviewView, DetailsView, JsCallTreeView, RecordingsView } = panel.panelWin; let { OverviewView, DetailsView, JsCallTreeView } = panel.panelWin;
let profilerData = { threads: [gThread] }; let profilerData = { threads: [gThread] };

View File

@ -12,6 +12,7 @@ DevToolsModules(
'panel-utils.js', 'panel-utils.js',
'prefs.js', 'prefs.js',
'profiler-mm-utils.js', 'profiler-mm-utils.js',
'recording-utils.js',
'synth-utils.js', 'synth-utils.js',
'tab-utils.js', 'tab-utils.js',
'urls.js', 'urls.js',

View File

@ -0,0 +1,54 @@
/* 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";
/**
* These utilities provide a functional interface for accessing the particulars
* about the recording's details.
*/
/**
* Access the selected view from the panel's recording list.
*
* @param {object} panel - The current panel.
* @return {object} The recording model.
*/
exports.getSelectedRecording = function (panel) {
const view = panel.panelWin.RecordingsView;
return view.selected;
};
/**
* Set the selected index of the recording via the panel.
*
* @param {object} panel - The current panel.
* @return {number} index
*/
exports.setSelectedRecording = function (panel, index) {
const view = panel.panelWin.RecordingsView;
view.setSelectedByIndex(index);
return index;
};
/**
* Access the selected view from the panel's recording list.
*
* @param {object} panel - The current panel.
* @return {number} index
*/
exports.getSelectedRecordingIndex = function (panel) {
const view = panel.panelWin.RecordingsView;
return view.getSelectedIndex();
};
exports.getDurationLabelText = function (panel, elementIndex) {
const { $$ } = panel.panelWin;
const elements = $$(".recording-list-item-duration", panel.panelWin.document);
return elements[elementIndex].innerHTML;
};
exports.getRecordingsCount = function (panel) {
const { $$ } = panel.panelWin;
return $$(".recording-list-item", panel.panelWin.document).length;
};

View File

@ -9,13 +9,11 @@
/** /**
* Functions handling the recordings UI. * Functions handling the recordings UI.
*/ */
var RecordingsView = Heritage.extend(WidgetMethods, { var RecordingsView = {
/** /**
* Initialization function, called when the tool is started. * Initialization function, called when the tool is started.
*/ */
initialize: function () { initialize: function () {
this.widget = new SideMenuWidget($("#recordings-list"));
this._onSelect = this._onSelect.bind(this); this._onSelect = this._onSelect.bind(this);
this._onRecordingStateChange = this._onRecordingStateChange.bind(this); this._onRecordingStateChange = this._onRecordingStateChange.bind(this);
this._onNewRecording = this._onNewRecording.bind(this); this._onNewRecording = this._onNewRecording.bind(this);
@ -23,13 +21,75 @@ var RecordingsView = Heritage.extend(WidgetMethods, {
this._onRecordingDeleted = this._onRecordingDeleted.bind(this); this._onRecordingDeleted = this._onRecordingDeleted.bind(this);
this._onRecordingExported = this._onRecordingExported.bind(this); this._onRecordingExported = this._onRecordingExported.bind(this);
this.emptyText = L10N.getStr("noRecordingsText");
PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange); PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
PerformanceController.on(EVENTS.RECORDING_ADDED, this._onNewRecording); PerformanceController.on(EVENTS.RECORDING_ADDED, this._onNewRecording);
PerformanceController.on(EVENTS.RECORDING_DELETED, this._onRecordingDeleted); PerformanceController.on(EVENTS.RECORDING_DELETED, this._onRecordingDeleted);
PerformanceController.on(EVENTS.RECORDING_EXPORTED, this._onRecordingExported); PerformanceController.on(EVENTS.RECORDING_EXPORTED, this._onRecordingExported);
this.widget.addEventListener("select", this._onSelect, false);
// DE-XUL: Begin migrating the recording sidebar to React. Temporarily hold state
// here.
this._listState = {
recordings: [],
labels: new WeakMap(),
selected: null,
};
this._listMount = PerformanceUtils.createHtmlMount($("#recording-list-mount"));
this._renderList();
},
/**
* Get the index of the currently selected recording. Only used by tests.
* @return {integer} index
*/
getSelectedIndex() {
const { recordings, selected } = this._listState;
return recordings.indexOf(selected);
},
/**
* Set the currently selected recording via its index. Only used by tests.
* @param {integer} index
*/
setSelectedByIndex(index) {
this._onSelect(this._listState.recordings[index]);
this._renderList();
},
/**
* DE-XUL: During the migration, this getter will access the selected recording from
* the private _listState object so that tests will continue to pass.
*/
get selected() {
return this._listState.selected;
},
/**
* DE-XUL: During the migration, this getter will access the number of recordings.
*/
get itemCount() {
return this._listState.recordings.length;
},
/**
* DE-XUL: Render the recording list using React.
*/
_renderList: function () {
const {recordings, labels, selected} = this._listState;
const recordingList = RecordingList({
itemComponent: RecordingListItem,
items: recordings.map(recording => ({
onSelect: () => this._onSelect(recording),
onSave: () => this._onSaveButtonClick(recording),
isLoading: !recording.isRecording() && !recording.isCompleted(),
isRecording: recording.isRecording(),
isSelected: recording === selected,
duration: recording.getDuration().toFixed(0),
label: labels.get(recording),
}))
});
ReactDOM.render(recordingList, this._listMount);
}, },
/** /**
@ -41,56 +101,6 @@ var RecordingsView = Heritage.extend(WidgetMethods, {
PerformanceController.off(EVENTS.RECORDING_ADDED, this._onNewRecording); PerformanceController.off(EVENTS.RECORDING_ADDED, this._onNewRecording);
PerformanceController.off(EVENTS.RECORDING_DELETED, this._onRecordingDeleted); PerformanceController.off(EVENTS.RECORDING_DELETED, this._onRecordingDeleted);
PerformanceController.off(EVENTS.RECORDING_EXPORTED, this._onRecordingExported); PerformanceController.off(EVENTS.RECORDING_EXPORTED, this._onRecordingExported);
this.widget.removeEventListener("select", this._onSelect, false);
},
/**
* Adds an empty recording to this container.
*
* @param RecordingModel recording
* A model for the new recording item created.
*/
addEmptyRecording: function (recording) {
let titleNode = document.createElement("label");
titleNode.className = "plain recording-item-title";
titleNode.setAttribute("crop", "end");
titleNode.setAttribute("value", recording.getLabel() ||
L10N.getFormatStr("recordingsList.itemLabel", this.itemCount + 1));
let durationNode = document.createElement("label");
durationNode.className = "plain recording-item-duration";
durationNode.setAttribute("value",
L10N.getStr("recordingsList.recordingLabel"));
let saveNode = document.createElement("label");
saveNode.className = "plain recording-item-save";
saveNode.addEventListener("click", this._onSaveButtonClick);
let hspacer = document.createElement("spacer");
hspacer.setAttribute("flex", "1");
let footerNode = document.createElement("hbox");
footerNode.className = "recording-item-footer";
footerNode.appendChild(durationNode);
footerNode.appendChild(hspacer);
footerNode.appendChild(saveNode);
let vspacer = document.createElement("spacer");
vspacer.setAttribute("flex", "1");
let contentsNode = document.createElement("vbox");
contentsNode.className = "recording-item";
contentsNode.setAttribute("flex", "1");
contentsNode.appendChild(titleNode);
contentsNode.appendChild(vspacer);
contentsNode.appendChild(footerNode);
// Append a recording item to this container.
return this.push([contentsNode], {
// Store the recording model that contains all the data to be
// rendered in the item.
attachment: recording
});
}, },
/** /**
@ -112,85 +122,55 @@ var RecordingsView = Heritage.extend(WidgetMethods, {
* Model of the recording that was started. * Model of the recording that was started.
*/ */
_onRecordingStateChange: function (_, state, recording) { _onRecordingStateChange: function (_, state, recording) {
let recordingItem = this.getItemForPredicate(e => e.attachment === recording); const { recordings, labels } = this._listState;
if (!recordingItem) {
recordingItem = this.addEmptyRecording(recording); if (!recordings.includes(recording)) {
recordings.push(recording);
labels.set(recording, recording.getLabel() ||
L10N.getFormatStr("recordingsList.itemLabel", recordings.length));
// If this is a manual recording, immediately select it, or // If this is a manual recording, immediately select it, or
// select a console profile if its the only one // select a console profile if its the only one
if (!recording.isConsole() || this.selectedIndex === -1) { if (!recording.isConsole() || !this._listState.selected) {
this.selectedItem = recordingItem; this._onSelect(recording);
} }
} }
recordingItem.isRecording = recording.isRecording(); // Determine if the recording needs to be selected.
const isCompletedManualRecording = !recording.isConsole() && recording.isCompleted();
// This recording is in the process of stopping. if (recording.isImported() || isCompletedManualRecording) {
if (!recording.isRecording() && !recording.isCompleted()) { this._onSelect(recording);
// Mark the corresponding item as loading.
let durationNode = $(".recording-item-duration", recordingItem.target);
durationNode.setAttribute("value", L10N.getStr("recordingsList.loadingLabel"));
} }
// Render the recording item with finalized information (timing, etc) this._renderList();
if (recording.isCompleted() && !recordingItem.finalized) {
this.finalizeRecording(recordingItem);
// Select the recording if it was a manual recording only
if (!recording.isConsole()) {
this.forceSelect(recordingItem);
}
}
// Auto select imported items.
if (recording.isImported()) {
this.selectedItem = recordingItem;
}
}, },
/** /**
* Clears out all non-console recordings. * Clears out all non-console recordings.
*/ */
_onRecordingDeleted: function (_, recording) { _onRecordingDeleted: function (_, recording) {
let recordingItem = this.getItemForPredicate(e => e.attachment === recording); const { recordings } = this._listState;
this.remove(recordingItem); const index = recordings.indexOf(recording);
}, if (index === -1) {
throw new Error("Attempting to remove a recording that doesn't exist.");
/** }
* Adds recording data to a recording item in this container. recordings.splice(index, 1);
* this._renderList();
* @param Item recordingItem
* An item inserted via `RecordingsView.addEmptyRecording`.
*/
finalizeRecording: function (recordingItem) {
let model = recordingItem.attachment;
recordingItem.finalized = true;
let saveNode = $(".recording-item-save", recordingItem.target);
saveNode.setAttribute("value",
L10N.getStr("recordingsList.saveLabel"));
let durationMillis = model.getDuration().toFixed(0);
let durationNode = $(".recording-item-duration", recordingItem.target);
durationNode.setAttribute("value",
L10N.getFormatStr("recordingsList.durationLabel", durationMillis));
}, },
/** /**
* The select listener for this container. * The select listener for this container.
*/ */
_onSelect: Task.async(function* ({ detail: recordingItem }) { _onSelect: Task.async(function* (recording) {
if (!recordingItem) { this._listState.selected = recording;
return; this.emit(EVENTS.UI_RECORDING_SELECTED, recording);
} this._renderList();
let model = recordingItem.attachment;
this.emit(EVENTS.UI_RECORDING_SELECTED, model);
}), }),
/** /**
* The click listener for the "save" button of each item in this container. * The click listener for the "save" button of each item in this container.
*/ */
_onSaveButtonClick: function (e) { _onSaveButtonClick: function (recording) {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, L10N.getStr("recordingsList.saveDialogTitle"), fp.init(window, L10N.getStr("recordingsList.saveDialogTitle"),
Ci.nsIFilePicker.modeSave); Ci.nsIFilePicker.modeSave);
@ -202,8 +182,7 @@ var RecordingsView = Heritage.extend(WidgetMethods, {
if (result == Ci.nsIFilePicker.returnCancel) { if (result == Ci.nsIFilePicker.returnCancel) {
return; return;
} }
let recordingItem = this.getItemForElement(e.target); this.emit(EVENTS.UI_EXPORT_RECORDING, recording, fp.file);
this.emit(EVENTS.UI_EXPORT_RECORDING, recordingItem.attachment, fp.file);
}}); }});
}, },
@ -211,13 +190,11 @@ var RecordingsView = Heritage.extend(WidgetMethods, {
if (recording.isConsole()) { if (recording.isConsole()) {
return; return;
} }
let recordingItem = this.getItemForPredicate(e => e.attachment === recording); const name = file.leafName.replace(/\..+$/, "");
let titleNode = $(".recording-item-title", recordingItem.target); this._listState.labels.set(recording, name);
titleNode.setAttribute("value", file.leafName.replace(/\..+$/, "")); this._renderList();
}, }
};
toString: () => "[object RecordingsView]"
});
/** /**
* Convenient way of emitting events from the RecordingsView. * Convenient way of emitting events from the RecordingsView.

View File

@ -144,33 +144,81 @@
line-height: 0; line-height: 0;
} }
#recordings-list { .theme-sidebar {
max-width: 300px; position: relative;
} }
.recording-item { /**
padding: 4px; * DE-XUL: This is probably only needed for the html:div inside of a vbox.
*/
#recordings-list > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
} }
.recording-item-title { .recording-list {
width: var(--sidebar-width);
min-width: var(--sidebar-width);
margin: 0;
padding: 0;
background-color: var(--theme-sidebar-background);
border-inline-end: 1px solid var(--theme-splitter-color);
}
.recording-list-item {
display: flex;
flex-direction: column;
color: var(--theme-body-color);
border-bottom: 1px solid rgba(128,128,128,0.15);
padding: 8px;
cursor: default;
}
.recording-list-item.selected {
background-color: var(--theme-selection-background);
color: var(--theme-selection-color);
}
.recording-list-empty {
padding: 8px;
}
.recording-list-item-label {
font-size: 110%; font-size: 110%;
} }
.recording-item-footer { .recording-list-item-footer {
padding-top: 4px; padding-top: 4px;
font-size: 90%; font-size: 90%;
display: flex;
justify-content: space-between;
} }
.recording-item-save { .recording-list-item-save {
background: none;
border: none;
text-decoration: underline; text-decoration: underline;
cursor: pointer; cursor: pointer;
font-size: 90%;
padding:0;
} }
.recording-item-duration, .recording-list-item-duration,
.recording-item-save { .recording-list-item-save {
color: var(--theme-body-color-alt); color: var(--theme-body-color-alt);
} }
.recording-list-item.selected .recording-list-item-duration,
.recording-list-item.selected .recording-list-item-save {
color: var(--theme-body-color-alt);
color: var(--theme-selection-color);
}
#recordings-list .selected label { #recordings-list .selected label {
/* Text inside a selected item should not be custom colored. */ /* Text inside a selected item should not be custom colored. */
color: inherit !important; color: inherit !important;