MozReview-Commit-ID: BAdnrVKIL0l
This commit is contained in:
Wes Kocher 2016-03-16 16:51:50 -07:00
Родитель d2a9ec7408 056d92a49d
Коммит df770973e9
213 изменённых файлов: 5611 добавлений и 4980 удалений

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

@ -183,6 +183,11 @@ const PanelUI = {
},
handleEvent: function(aEvent) {
// Ignore context menus and menu button menus showing and hiding:
if (aEvent.type.startsWith("popup") &&
aEvent.target != this.panel) {
return;
}
switch (aEvent.type) {
case "popupshowing":
this._adjustLabelsForAutoHyphens();

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

@ -145,4 +145,5 @@ skip-if = os == "mac"
[browser_1096763_seen_widgets_post_reset.js]
[browser_1161838_inserted_new_default_buttons.js]
[browser_bootstrapped_custom_toolbar.js]
[browser_customizemode_contextmenu_menubuttonstate.js]
[browser_panel_toggle.js]

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

@ -0,0 +1,24 @@
"use strict";
add_task(function*() {
ok(!PanelUI.menuButton.hasAttribute("open"), "Menu button should not be 'pressed' outside customize mode");
yield startCustomizing();
is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode");
let contextMenu = document.getElementById("customizationPanelItemContextMenu");
let shownPromise = popupShown(contextMenu);
let newWindowButton = document.getElementById("wrapper-new-window-button");
EventUtils.synthesizeMouse(newWindowButton, 2, 2, {type: "contextmenu", button: 2});
yield shownPromise;
is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode after opening a context menu");
let hiddenContextPromise = popupHidden(contextMenu);
contextMenu.hidePopup();
yield hiddenContextPromise;
is(PanelUI.menuButton.getAttribute("open"), "true", "Menu button should be 'pressed' when in customize mode after hiding a context menu");
yield endCustomizing();
ok(!PanelUI.menuButton.hasAttribute("open"), "Menu button should not be 'pressed' after ending customize mode");
});

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

@ -49,9 +49,13 @@ function* navigate(usage, options) {
yield helpers.listenOnce(options.browser, "load", true);
is(options.window.location.href, PAGE_3, "page 3 loaded");
let toolboxReady = gDevTools.once("toolbox-ready");
yield usage.stop();
ok(!usage.isRunning(), "csscoverage not is running");
yield toolboxReady;
}
/**

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

@ -8,7 +8,8 @@
const { Cc, Ci, Cu } = require("chrome");
const l10n = require("gcli/l10n");
const { gDevTools } = require("devtools/client/framework/devtools");
loader.lazyRequireGetter(this, "gDevTools",
"devtools/client/framework/devtools", true);
/**
* The commands and converters that are exported to GCLI

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

@ -0,0 +1,60 @@
/* 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";
// Register about:devtools-toolbox which allows to open a devtools toolbox
// in a Firefox tab or a custom html iframe in browser.html
const { Ci, Cu, Cm, components } = require("chrome");
const Services = require("Services");
const { XPCOMUtils } = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
const { nsIAboutModule } = Ci;
function AboutURL() {}
AboutURL.prototype = {
uri: Services.io.newURI("chrome://devtools/content/framework/toolbox.xul",
null, null),
classDescription: "about:devtools-toolbox",
classID: components.ID("11342911-3135-45a8-8d71-737a2b0ad469"),
contractID: "@mozilla.org/network/protocol/about;1?what=devtools-toolbox",
QueryInterface: XPCOMUtils.generateQI([nsIAboutModule]),
newChannel: function(aURI, aLoadInfo) {
let chan = Services.io.newChannelFromURIWithLoadInfo(this.uri, aLoadInfo);
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
return chan;
},
getURIFlags: function(aURI) {
return nsIAboutModule.ALLOW_SCRIPT || nsIAboutModule.ENABLE_INDEXED_DB;
}
};
AboutURL.createInstance = function(outer, iid) {
if (outer) {
throw Cr.NS_ERROR_NO_AGGREGATION;
}
return new AboutURL();
};
exports.register = function () {
if (Cm.isCIDRegistered(AboutURL.prototype.classID)) {
console.error("Trying to register " + AboutURL.prototype.classDescription +
" more than once.");
} else {
Cm.registerFactory(AboutURL.prototype.classID,
AboutURL.prototype.classDescription,
AboutURL.prototype.contractID,
AboutURL);
}
}
exports.unregister = function () {
if (Cm.isCIDRegistered(AboutURL.prototype.classID)) {
Cm.unregisterFactory(AboutURL.prototype.classID, AboutURL);
}
}

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

@ -15,6 +15,7 @@ const {defaultTools: DefaultTools, defaultThemes: DefaultThemes} =
require("devtools/client/definitions");
const EventEmitter = require("devtools/shared/event-emitter");
const {JsonView} = require("devtools/client/jsonview/main");
const AboutDevTools = require("devtools/client/framework/about-devtools-toolbox");
const FORBIDDEN_IDS = new Set(["toolbox", ""]);
const MAX_ORDINAL = 99;
@ -35,6 +36,8 @@ this.DevTools = function DevTools() {
// JSON Viewer for 'application/json' documents.
JsonView.initialize();
AboutDevTools.register();
EventEmitter.decorate(this);
Services.obs.addObserver(this._teardown, "devtools-unloaded", false);
@ -470,6 +473,7 @@ DevTools.prototype = {
for (let [target, toolbox] of this._toolboxes) {
toolbox.destroy();
}
AboutDevTools.unregister();
},
/**

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

@ -10,6 +10,7 @@ TEST_HARNESS_FILES.xpcshell.devtools.client.framework.test += [
]
DevToolsModules(
'about-devtools-toolbox.js',
'attach-thread.js',
'devtools-browser.js',
'devtools.js',
@ -17,6 +18,7 @@ DevToolsModules(
'selection.js',
'sidebar.js',
'source-location.js',
'target-from-url.js',
'target.js',
'toolbox-highlighter-utils.js',
'toolbox-hosts.js',

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

@ -0,0 +1,106 @@
/* 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 { Cu, Ci } = require("chrome");
const { TargetFactory } = require("devtools/client/framework/target");
const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/main");
const { Task } = require("resource://gre/modules/Task.jsm");
/**
* Construct a Target for a given URL object having various query parameters:
*
* type: tab, process
* {String} The type of target to connect to. Currently tabs and processes are supported types.
*
* If type="tab":
* id:
* {Number} the tab outerWindowID
* chrome: Optional
* {Boolean} Force the creation of a chrome target. Gives more privileges to the tab
* actor. Allows chrome execution in the webconsole and see chrome files in
* the debugger. (handy when contributing to firefox)
*
* If type="process":
* id:
* {Number} the process id to debug. Default to 0, which is the parent process.
*
* @param {URL} url
* The url to fetch query params from.
*
* @return A target object
*/
exports.targetFromURL = Task.async(function*(url) {
let params = url.searchParams;
let type = params.get("type");
if (!type) {
throw new Error("targetFromURL, missing type parameter");
}
let id = params.get("id");
// Allows to spawn a chrome enabled target for any context
// (handy to debug chrome stuff in a child process)
let chrome = params.has("chrome");
// Once about:debugging start supporting remote targets and use this helper,
// client will also be defined by url params.
let client = createClient();
yield client.connect();
let form, isTabActor;
if (type === "tab") {
// Fetch target for a remote tab
id = parseInt(id);
if (isNaN(id)) {
throw new Error("targetFromURL, wrong tab id:'" + id + "', should be a number");
}
try {
let response = yield client.getTab({ outerWindowID: id })
form = response.tab;
} catch(ex) {
if (ex.error == "noTab") {
throw new Error("targetFromURL, tab with outerWindowID:'" + id+ "' doesn't exist");
}
throw ex;
}
} else if (type == "process") {
// Fetch target for a remote chrome actor
DebuggerServer.allowChromeProcess = true;
try {
id = parseInt(id);
if (isNaN(id)) {
id = 0;
}
let response = yield client.getProcess(id);
form = response.form;
chrome = true;
if (id != 0) {
// Child process are not exposing tab actors and only support debugger+console
isTabActor = false;
}
} catch(ex) {
if (ex.error == "noProcess") {
throw new Error("targetFromURL, process with id:'" + id+ "' doesn't exist");
}
throw ex;
}
} else {
throw new Error("targetFromURL, unsupported type='" + type + "' parameter");
}
return TargetFactory.forRemoteTab({ client, form, chrome, isTabActor });
});
function createClient() {
// Setup a server if we don't have one already running
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
return new DebuggerClient(DebuggerServer.connectPipe());
}

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

@ -29,6 +29,7 @@ support-files =
[browser_new_activation_workflow.js]
[browser_source-location-01.js]
[browser_source-location-02.js]
[browser_target_from_url.js]
[browser_target_events.js]
[browser_target_remote.js]
[browser_target_support.js]

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

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TEST_URI = "data:text/html;charset=utf-8," +
"<p>browser_target-from-url.js</p>";
const { targetFromURL } = require("devtools/client/framework/target-from-url");
function assertIsTabTarget(target, chrome=false) {
is(target.url, TEST_URI);
is(target.isLocalTab, false);
is(target.chrome, chrome);
is(target.isTabActor, true);
is(target.isRemote, true);
}
add_task(function*() {
let tab = yield addTab(TEST_URI);
let browser = tab.linkedBrowser;
let target;
info("Test invalid type");
try {
yield targetFromURL(new URL("http://foo?type=x"));
ok(false, "Shouldn't pass");
} catch(e) {
is(e.message, "targetFromURL, unsupported type='x' parameter");
}
info("Test tab");
let windowId = browser.outerWindowID;
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId));
assertIsTabTarget(target);
info("Test tab with chrome privileges");
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId + "&chrome"));
assertIsTabTarget(target, true);
info("Test invalid tab id");
try {
yield targetFromURL(new URL("http://foo?type=tab&id=1"));
ok(false, "Shouldn't pass");
} catch(e) {
is(e.message, "targetFromURL, tab with outerWindowID:'1' doesn't exist");
}
info("Test parent process");
target = yield targetFromURL(new URL("http://foo?type=process"));
let topWindow = Services.wm.getMostRecentWindow("navigator:browser");
is(target.url, topWindow.location.href);
is(target.isLocalTab, false);
is(target.chrome, true);
is(target.isTabActor, true);
is(target.isRemote, true);
yield target.client.close();
gBrowser.removeCurrentTab();
});

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

@ -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";
// URL constructor doesn't support about: scheme
let href = window.location.href.replace("about:", "http://");
let url = new window.URL(href);
// Only use this method to attach the toolbox if some query parameters are given
if (url.search.length > 1) {
const Cu = Components.utils;
const Ci = Components.interfaces;
const { gDevTools } = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
const { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
const { targetFromURL } = require("devtools/client/framework/target-from-url");
const { Toolbox } = require("devtools/client/framework/toolbox");
const { TargetFactory } = require("devtools/client/framework/target");
const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/main");
const { Task } = require("resource://gre/modules/Task.jsm");
// `host` is the frame element loading the toolbox.
let host = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.containerElement;
if (url.searchParams.has("target")) {
// Attach toolbox to a given browser iframe (<xul:browser> or <html:iframe
// mozbrowser>) whose reference is set on the host iframe.
// `iframe` is the targeted document to debug
let iframe = host.wrappedJSObject ? host.wrappedJSObject.target
: host.target;
// Need to use a xray and query some interfaces to have
// attributes and behavior expected by devtools codebase
iframe = XPCNativeWrapper(iframe);
iframe.QueryInterface(Ci.nsIFrameLoaderOwner);
if (iframe) {
// Fake a xul:tab object as we don't have one.
// linkedBrowser is the only one attribute being queried by client.getTab
let tab = { linkedBrowser: iframe };
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
}
let client = new DebuggerClient(DebuggerServer.connectPipe());
Task.spawn(function*() {
yield client.connect();
// Creates a target for a given browser iframe.
let response = yield client.getTab({ tab });
let form = response.tab;
let target = yield TargetFactory.forRemoteTab({client, form, chrome: false});
let options = { customIframe: host };
yield gDevTools.showToolbox(target, null, Toolbox.HostType.CUSTOM, options);
});
}
} else {
targetFromURL(url).then(target => {
let options = { customIframe: host };
return gDevTools.showToolbox(target, null, Toolbox.HostType.CUSTOM, options);
}).then(null, e => {
window.alert("Unable to start the toolbox:" + e.message);
});
}
}

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

@ -183,7 +183,7 @@ Toolbox.HostType = {
};
Toolbox.prototype = {
_URL: "chrome://devtools/content/framework/toolbox.xul",
_URL: "about:devtools-toolbox",
_prefs: {
LAST_HOST: "devtools.toolbox.host",
@ -358,7 +358,14 @@ Toolbox.prototype = {
let iframe = yield this._host.create();
let domReady = promise.defer();
iframe.setAttribute("src", this._URL);
// Prevent reloading the document when the toolbox is opened in a tab
let location = iframe.contentWindow.location.href;
if (!location.startsWith(this._URL)) {
iframe.setAttribute("src", this._URL);
} else {
// Update the URL so that onceDOMReady watch for the right url.
this._URL = location;
}
iframe.setAttribute("aria-label", toolboxStrings("toolbox.label"));
let domHelper = new DOMHelpers(iframe.contentWindow);
domHelper.onceDOMReady(() => domReady.resolve(), this._URL);
@ -699,7 +706,10 @@ Toolbox.prototype = {
zoomValue = Math.max(zoomValue, MIN_ZOOM);
zoomValue = Math.min(zoomValue, MAX_ZOOM);
let contViewer = this.frame.docShell.contentViewer;
let docShell = this.frame.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let contViewer = docShell.contentViewer;
contViewer.fullZoom = zoomValue;

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

@ -23,6 +23,8 @@
src="chrome://global/content/viewSourceUtils.js"/>
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript;version=1.8"
src="chrome://devtools/content/framework/toolbox-init.js"/>
<commandset id="editMenuCommands"/>
<keyset id="editMenuKeys"/>

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

@ -5,6 +5,8 @@
"use strict";
const l10n = require("gcli/l10n");
loader.lazyRequireGetter(this, "gDevTools",
"devtools/client/framework/devtools", true);
exports.items = [{
item: "command",
@ -22,8 +24,6 @@ exports.items = [{
],
exec: function(args, context) {
let target = context.environment.target;
let {gDevTools} = require("devtools/client/framework/devtools");
return gDevTools.showToolbox(target, "inspector").then(toolbox => {
toolbox.getCurrentPanel().selection.setNode(args.selector, "gcli");
});

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

@ -113,6 +113,7 @@ devtools.jar:
content/framework/toolbox-options.xul (framework/toolbox-options.xul)
content/framework/toolbox-options.js (framework/toolbox-options.js)
content/framework/toolbox.xul (framework/toolbox.xul)
content/framework/toolbox-init.js (framework/toolbox-init.js)
content/framework/options-panel.css (framework/options-panel.css)
content/framework/toolbox-process-window.xul (framework/toolbox-process-window.xul)
* content/framework/toolbox-process-window.js (framework/toolbox-process-window.js)

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

@ -3,107 +3,106 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
module.exports = {
// Fired by the PerformanceController and OptionsView when a pref changes.
const ControllerEvents = {
// Fired when a performance pref changes (either because the user changed it
// via the tool's UI, by changing something about:config or programatically).
PREF_CHANGED: "Performance:PrefChanged",
// Fired by the PerformanceController when the devtools theme changes.
// Fired when the devtools theme changes.
THEME_CHANGED: "Performance:ThemeChanged",
// Emitted by the PerformanceView when the state (display mode) changes,
// for example when switching between "empty", "recording" or "recorded".
// This causes certain panels to be hidden or visible.
UI_STATE_CHANGED: "Performance:UI:StateChanged",
// When a new recording model is received by the controller.
RECORDING_ADDED: "Performance:RecordingAdded",
// Emitted by the PerformanceView on clear button click
UI_CLEAR_RECORDINGS: "Performance:UI:ClearRecordings",
// When a recording model gets removed from the controller.
RECORDING_DELETED: "Performance:RecordingDeleted",
// Emitted by the PerformanceView on record button click
UI_START_RECORDING: "Performance:UI:StartRecording",
UI_STOP_RECORDING: "Performance:UI:StopRecording",
// Emitted by the PerformanceView on import button click
UI_IMPORT_RECORDING: "Performance:UI:ImportRecording",
// Emitted by the RecordingsView on export button click
UI_EXPORT_RECORDING: "Performance:UI:ExportRecording",
// When a new recording is being tracked in the panel.
NEW_RECORDING: "Performance:NewRecording",
// When a new recording can't be successfully created when started.
NEW_RECORDING_FAILED: "Performance:NewRecordingFailed",
// When a recording is started or stopped or stopping via the PerformanceController
// When a recording model becomes "started", "stopping" or "stopped".
RECORDING_STATE_CHANGE: "Performance:RecordingStateChange",
// Emitted by the PerformanceController or RecordingView
// when a recording model is selected
// When a recording is offering information on the profiler's circular buffer.
RECORDING_PROFILER_STATUS_UPDATE: "Performance:RecordingProfilerStatusUpdate",
// When a recording model becomes marked as selected.
RECORDING_SELECTED: "Performance:RecordingSelected",
// When recordings have been cleared out
RECORDINGS_CLEARED: "Performance:RecordingsCleared",
// When starting a recording is attempted and fails because the backend
// does not permit it at this time.
BACKEND_FAILED_AFTER_RECORDING_START: "Performance:BackendFailedRecordingStart",
// When a recording is exported via the PerformanceController
// When a recording is started and the backend has started working.
BACKEND_READY_AFTER_RECORDING_START: "Performance:BackendReadyRecordingStart",
// When a recording is stopped and the backend has finished cleaning up.
BACKEND_READY_AFTER_RECORDING_STOP: "Performance:BackendReadyRecordingStop",
// When a recording is exported.
RECORDING_EXPORTED: "Performance:RecordingExported",
// Emitted by the PerformanceController when a recording is imported.
// Unless you're interested in specifically imported recordings, like in tests
// or telemetry, you should probably use the normal RECORDING_STATE_CHANGE in the UI.
// When a recording is imported.
RECORDING_IMPORTED: "Performance:RecordingImported",
// When the front has updated information on the profiler's circular buffer
PROFILER_STATUS_UPDATED: "Performance:BufferUpdated",
// When the PerformanceView updates the display of the buffer status
UI_BUFFER_STATUS_UPDATED: "Performance:UI:BufferUpdated",
// Emitted by the OptimizationsListView when it renders new optimization
// data and clears the optimization data
OPTIMIZATIONS_RESET: "Performance:UI:OptimizationsReset",
OPTIMIZATIONS_RENDERED: "Performance:UI:OptimizationsRendered",
// Emitted by the OverviewView when more data has been rendered
OVERVIEW_RENDERED: "Performance:UI:OverviewRendered",
FRAMERATE_GRAPH_RENDERED: "Performance:UI:OverviewFramerateRendered",
MARKERS_GRAPH_RENDERED: "Performance:UI:OverviewMarkersRendered",
MEMORY_GRAPH_RENDERED: "Performance:UI:OverviewMemoryRendered",
// Emitted by the OverviewView when a range has been selected in the graphs
OVERVIEW_RANGE_SELECTED: "Performance:UI:OverviewRangeSelected",
// Emitted by the DetailsView when a subview is selected
DETAILS_VIEW_SELECTED: "Performance:UI:DetailsViewSelected",
// Emitted by the WaterfallView when it has been rendered
WATERFALL_RENDERED: "Performance:UI:WaterfallRendered",
// Emitted by the JsCallTreeView when a call tree has been rendered
JS_CALL_TREE_RENDERED: "Performance:UI:JsCallTreeRendered",
// Emitted by the JsFlameGraphView when it has been rendered
JS_FLAMEGRAPH_RENDERED: "Performance:UI:JsFlameGraphRendered",
// Emitted by the MemoryCallTreeView when a call tree has been rendered
MEMORY_CALL_TREE_RENDERED: "Performance:UI:MemoryCallTreeRendered",
// Emitted by the MemoryFlameGraphView when it has been rendered
MEMORY_FLAMEGRAPH_RENDERED: "Performance:UI:MemoryFlameGraphRendered",
// When a source is shown in the JavaScript Debugger at a specific location.
SOURCE_SHOWN_IN_JS_DEBUGGER: "Performance:UI:SourceShownInJsDebugger",
SOURCE_NOT_FOUND_IN_JS_DEBUGGER: "Performance:UI:SourceNotFoundInJsDebugger",
// These are short hands for the RECORDING_STATE_CHANGE event to make refactoring
// tests easier and in rare cases (telemetry). UI components should use
// RECORDING_STATE_CHANGE in almost all cases,
RECORDING_STARTED: "Performance:RecordingStarted",
RECORDING_WILL_STOP: "Performance:RecordingWillStop",
RECORDING_STOPPED: "Performance:RecordingStopped",
// Fired by the PerformanceController when `populateWithRecordings` is finished.
RECORDINGS_SEEDED: "Performance:RecordingsSeeded",
// Emitted by the PerformanceController when `PerformanceController.stopRecording()`
// is completed; used in tests, to know when a manual UI click is finished.
CONTROLLER_STOPPED_RECORDING: "Performance:Controller:StoppedRecording",
};
const ViewEvents = {
// Emitted by the `ToolbarView` when a preference changes.
UI_PREF_CHANGED: "Performance:UI:PrefChanged",
// When the state (display mode) changes, for example when switching between
// "empty", "recording" or "recorded". This causes certain parts of the UI
// to be hidden or visible.
UI_STATE_CHANGED: "Performance:UI:StateChanged",
// Emitted by the `PerformanceView` on clear button click.
UI_CLEAR_RECORDINGS: "Performance:UI:ClearRecordings",
// Emitted by the `PerformanceView` on record button click.
UI_START_RECORDING: "Performance:UI:StartRecording",
UI_STOP_RECORDING: "Performance:UI:StopRecording",
// Emitted by the `PerformanceView` on import/export button click.
UI_IMPORT_RECORDING: "Performance:UI:ImportRecording",
UI_EXPORT_RECORDING: "Performance:UI:ExportRecording",
// Emitted by the `PerformanceView` when the profiler's circular buffer
// status has been rendered.
UI_RECORDING_PROFILER_STATUS_RENDERED: "Performance:UI:RecordingProfilerStatusRendered",
// When a recording is selected in the UI.
UI_RECORDING_SELECTED: "Performance:UI:RecordingSelected",
// Emitted by the `DetailsView` when a subview is selected
UI_DETAILS_VIEW_SELECTED: "Performance:UI:DetailsViewSelected",
// Emitted by the `OverviewView` after something has been rendered.
UI_OVERVIEW_RENDERED: "Performance:UI:OverviewRendered",
UI_MARKERS_GRAPH_RENDERED: "Performance:UI:OverviewMarkersRendered",
UI_MEMORY_GRAPH_RENDERED: "Performance:UI:OverviewMemoryRendered",
UI_FRAMERATE_GRAPH_RENDERED: "Performance:UI:OverviewFramerateRendered",
// Emitted by the `OverviewView` when a range has been selected in the graphs.
UI_OVERVIEW_RANGE_SELECTED: "Performance:UI:OverviewRangeSelected",
// Emitted by the `WaterfallView` when it has been rendered.
UI_WATERFALL_RENDERED: "Performance:UI:WaterfallRendered",
// Emitted by the `JsCallTreeView` when it has been rendered.
UI_JS_CALL_TREE_RENDERED: "Performance:UI:JsCallTreeRendered",
// Emitted by the `JsFlameGraphView` when it has been rendered.
UI_JS_FLAMEGRAPH_RENDERED: "Performance:UI:JsFlameGraphRendered",
// Emitted by the `MemoryCallTreeView` when it has been rendered.
UI_MEMORY_CALL_TREE_RENDERED: "Performance:UI:MemoryCallTreeRendered",
// Emitted by the `MemoryFlameGraphView` when it has been rendered.
UI_MEMORY_FLAMEGRAPH_RENDERED: "Performance:UI:MemoryFlameGraphRendered",
};
module.exports = Object.assign({}, ControllerEvents, ViewEvents);

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

@ -0,0 +1,9 @@
/* 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";
exports.Constants = {
FRAMERATE_GRAPH_LOW_RES_INTERVAL: 100, // ms
FRAMERATE_GRAPH_HIGH_RES_INTERVAL: 16, // ms
};

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

@ -22,15 +22,15 @@ function PerformanceTelemetry (emitter) {
this._emitter = emitter;
this._telemetry = new Telemetry();
this.onFlagEvent = this.onFlagEvent.bind(this);
this.onRecordingStopped = this.onRecordingStopped.bind(this);
this.onRecordingStateChange = this.onRecordingStateChange.bind(this);
this.onViewSelected = this.onViewSelected.bind(this);
for (let [event] of EVENT_MAP_FLAGS) {
this._emitter.on(event, this.onFlagEvent);
}
this._emitter.on(EVENTS.RECORDING_STOPPED, this.onRecordingStopped);
this._emitter.on(EVENTS.DETAILS_VIEW_SELECTED, this.onViewSelected);
this._emitter.on(EVENTS.RECORDING_STATE_CHANGE, this.onRecordingStateChange);
this._emitter.on(EVENTS.UI_DETAILS_VIEW_SELECTED, this.onViewSelected);
if (DevToolsUtils.testing) {
this.recordLogs();
@ -46,8 +46,8 @@ PerformanceTelemetry.prototype.destroy = function () {
for (let [event] of EVENT_MAP_FLAGS) {
this._emitter.off(event, this.onFlagEvent);
}
this._emitter.off(EVENTS.RECORDING_STOPPED, this.onRecordingStopped);
this._emitter.off(EVENTS.DETAILS_VIEW_SELECTED, this.onViewSelected);
this._emitter.off(EVENTS.RECORDING_STATE_CHANGE, this.onRecordingStateChange);
this._emitter.off(EVENTS.UI_DETAILS_VIEW_SELECTED, this.onViewSelected);
this._emitter = null;
};
@ -55,7 +55,11 @@ PerformanceTelemetry.prototype.onFlagEvent = function (eventName, ...data) {
this._telemetry.log(EVENT_MAP_FLAGS.get(eventName), true);
};
PerformanceTelemetry.prototype.onRecordingStopped = function (_, model) {
PerformanceTelemetry.prototype.onRecordingStateChange = function (_, status, model) {
if (status != "recording-stopped") {
return;
}
if (model.isConsole()) {
this._telemetry.log("DEVTOOLS_PERFTOOLS_CONSOLE_RECORDING_COUNT", true);
} else {

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

@ -9,6 +9,7 @@ DIRS += [
]
DevToolsModules(
'constants.js',
'global.js',
'io.js',
'markers.js',

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

@ -7,6 +7,7 @@ DIRS += [
'components',
'legacy',
'modules',
'test',
]
DevToolsModules(

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

@ -14,7 +14,7 @@ loader.lazyRequireGetter(this, "EventEmitter",
function PerformancePanel(iframeWindow, toolbox) {
this.panelWin = iframeWindow;
this._toolbox = toolbox;
this.toolbox = toolbox;
EventEmitter.decorate(this);
}
@ -36,7 +36,7 @@ PerformancePanel.prototype = {
let deferred = promise.defer();
this._opening = deferred.promise;
this.panelWin.gToolbox = this._toolbox;
this.panelWin.gToolbox = this.toolbox;
this.panelWin.gTarget = this.target;
this._checkRecordingStatus = this._checkRecordingStatus.bind(this);
@ -55,7 +55,7 @@ PerformancePanel.prototype = {
this.panelWin.gFront = front;
let { PerformanceController, EVENTS } = this.panelWin;
PerformanceController.on(EVENTS.NEW_RECORDING, this._checkRecordingStatus);
PerformanceController.on(EVENTS.RECORDING_ADDED, this._checkRecordingStatus);
PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._checkRecordingStatus);
yield this.panelWin.startupPerformance();
@ -74,7 +74,7 @@ PerformancePanel.prototype = {
// DevToolPanel API
get target() {
return this._toolbox.target;
return this.toolbox.target;
},
destroy: Task.async(function*() {
@ -84,7 +84,7 @@ PerformancePanel.prototype = {
}
let { PerformanceController, EVENTS } = this.panelWin;
PerformanceController.off(EVENTS.NEW_RECORDING, this._checkRecordingStatus);
PerformanceController.off(EVENTS.RECORDING_ADDED, this._checkRecordingStatus);
PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._checkRecordingStatus);
yield this.panelWin.shutdownPerformance();
this.emit("destroyed");
@ -93,9 +93,9 @@ PerformancePanel.prototype = {
_checkRecordingStatus: function () {
if (this.panelWin.PerformanceController.isRecording()) {
this._toolbox.highlightTool("performance");
this.toolbox.highlightTool("performance");
} else {
this._toolbox.unhighlightTool("performance");
this.toolbox.unhighlightTool("performance");
}
}
};

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

@ -115,14 +115,14 @@ var PerformanceController = {
this._prefs.registerObserver();
this._prefs.on("pref-changed", this._onPrefChanged);
ToolbarView.on(EVENTS.PREF_CHANGED, this._onPrefChanged);
ToolbarView.on(EVENTS.UI_PREF_CHANGED, this._onPrefChanged);
PerformanceView.on(EVENTS.UI_START_RECORDING, this.startRecording);
PerformanceView.on(EVENTS.UI_STOP_RECORDING, this.stopRecording);
PerformanceView.on(EVENTS.UI_IMPORT_RECORDING, this.importRecording);
PerformanceView.on(EVENTS.UI_CLEAR_RECORDINGS, this.clearRecordings);
RecordingsView.on(EVENTS.UI_EXPORT_RECORDING, this.exportRecording);
RecordingsView.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelectFromView);
DetailsView.on(EVENTS.DETAILS_VIEW_SELECTED, this._pipe);
RecordingsView.on(EVENTS.UI_RECORDING_SELECTED, this._onRecordingSelectFromView);
DetailsView.on(EVENTS.UI_DETAILS_VIEW_SELECTED, this._pipe);
gDevTools.on("pref-changed", this._onThemeChanged);
}),
@ -135,14 +135,14 @@ var PerformanceController = {
this._prefs.off("pref-changed", this._onPrefChanged);
this._prefs.unregisterObserver();
ToolbarView.off(EVENTS.PREF_CHANGED, this._onPrefChanged);
ToolbarView.off(EVENTS.UI_PREF_CHANGED, this._onPrefChanged);
PerformanceView.off(EVENTS.UI_START_RECORDING, this.startRecording);
PerformanceView.off(EVENTS.UI_STOP_RECORDING, this.stopRecording);
PerformanceView.off(EVENTS.UI_IMPORT_RECORDING, this.importRecording);
PerformanceView.off(EVENTS.UI_CLEAR_RECORDINGS, this.clearRecordings);
RecordingsView.off(EVENTS.UI_EXPORT_RECORDING, this.exportRecording);
RecordingsView.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelectFromView);
DetailsView.off(EVENTS.DETAILS_VIEW_SELECTED, this._pipe);
RecordingsView.off(EVENTS.UI_RECORDING_SELECTED, this._onRecordingSelectFromView);
DetailsView.off(EVENTS.UI_DETAILS_VIEW_SELECTED, this._pipe);
gDevTools.off("pref-changed", this._onThemeChanged);
},
@ -247,12 +247,16 @@ var PerformanceController = {
sampleFrequency: this.getPref("profiler-sample-frequency")
};
let recordingStarted = yield gFront.startRecording(options);
// In some cases, like when the target has a private browsing tab,
// recording is not currently supported because of the profiler module.
// Present a notification in this case alerting the user of this issue.
if (!(yield gFront.startRecording(options))) {
this.emit(EVENTS.NEW_RECORDING_FAILED);
if (!recordingStarted) {
this.emit(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START);
PerformanceView.setState("unavailable");
} else {
this.emit(EVENTS.BACKEND_READY_AFTER_RECORDING_START);
}
}),
@ -262,13 +266,7 @@ var PerformanceController = {
stopRecording: Task.async(function *() {
let recording = this.getLatestManualRecording();
yield gFront.stopRecording(recording);
// Emit another stop event here, as a lot of tests use
// the RECORDING_STOPPED event, but in the case of a UI click on a button,
// the RECORDING_STOPPED event happens from the server, where this request may
// not have yet finished, so listen to this in tests that fail because the `stopRecording`
// request is not yet completed. Should only be used in that scenario.
this.emit(EVENTS.CONTROLLER_STOPPED_RECORDING);
this.emit(EVENTS.BACKEND_READY_AFTER_RECORDING_STOP);
}),
/**
@ -326,7 +324,7 @@ var PerformanceController = {
*/
importRecording: Task.async(function*(_, file) {
let recording = yield gFront.importRecording(file);
this._addNewRecording(recording);
this._addRecordingIfUnknown(recording);
this.emit(EVENTS.RECORDING_IMPORTED, recording);
}),
@ -399,21 +397,19 @@ var PerformanceController = {
* Fired from the front on any event. Propagates to other handlers from here.
*/
_onFrontEvent: function (eventName, ...data) {
if (eventName === "profiler-status") {
this._onProfilerStatusUpdated(...data);
return;
switch (eventName) {
case "profiler-status":
let [profilerStatus] = data;
this.emit(EVENTS.RECORDING_PROFILER_STATUS_UPDATE, profilerStatus);
break;
case "recording-started":
case "recording-stopping":
case "recording-stopped":
let [recordingModel] = data;
this._addRecordingIfUnknown(recordingModel);
this.emit(EVENTS.RECORDING_STATE_CHANGE, eventName, recordingModel);
break;
}
if (["recording-started", "recording-stopped", "recording-stopping"].indexOf(eventName) !== -1) {
this._onRecordingStateChange(eventName, ...data);
}
},
/**
* Emitted when the front updates PerformanceRecording's buffer status.
*/
_onProfilerStatusUpdated: function (data) {
this.emit(EVENTS.PROFILER_STATUS_UPDATED, data);
},
/**
@ -421,40 +417,10 @@ var PerformanceController = {
*
* @param {PerformanceRecordingFront} recording
*/
_addNewRecording: function (recording) {
_addRecordingIfUnknown: function (recording) {
if (this._recordings.indexOf(recording) === -1) {
this._recordings.push(recording);
this.emit(EVENTS.NEW_RECORDING, recording);
}
},
/**
* Fired when a recording model changes state.
*
* @param {string} state
* Can be "recording-started", "recording-stopped" or "recording-stopping".
* @param {PerformanceRecording} model
*/
_onRecordingStateChange: function (state, model) {
this._addNewRecording(model);
this.emit(EVENTS.RECORDING_STATE_CHANGE, state, model);
// Emit the state specific events for tests that I'm too
// lazy and frusterated to change right now. These events
// should only be used in tests and specific rare cases (telemetry),
// as the rest of the UI should react to general RECORDING_STATE_CHANGE
// events and NEW_RECORDING events to handle lazy recordings.
switch (state) {
case "recording-started":
this.emit(EVENTS.RECORDING_STARTED, model);
break;
case "recording-stopping":
this.emit(EVENTS.RECORDING_WILL_STOP, model);
break;
case "recording-stopped":
this.emit(EVENTS.RECORDING_STOPPED, model);
break;
this.emit(EVENTS.RECORDING_ADDED, recording);
}
},
@ -522,7 +488,7 @@ var PerformanceController = {
*/
populateWithRecordings: function (recordings=[]) {
for (let recording of recordings) {
PerformanceController._addNewRecording(recording);
PerformanceController._addRecordingIfUnknown(recording);
}
this.emit(EVENTS.RECORDINGS_SEEDED);
},

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

@ -66,10 +66,10 @@ var PerformanceView = {
// Bind to controller events to unlock the record button
PerformanceController.on(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
PerformanceController.on(EVENTS.PROFILER_STATUS_UPDATED, this._onProfilerStatusUpdated);
PerformanceController.on(EVENTS.RECORDING_PROFILER_STATUS_UPDATE, this._onProfilerStatusUpdated);
PerformanceController.on(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
PerformanceController.on(EVENTS.NEW_RECORDING, this._onRecordingStateChange);
PerformanceController.on(EVENTS.NEW_RECORDING_FAILED, this._onNewRecordingFailed);
PerformanceController.on(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
PerformanceController.on(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START, this._onNewRecordingFailed);
if (yield PerformanceController.canCurrentlyRecord()) {
this.setState("empty");
@ -96,10 +96,10 @@ var PerformanceView = {
this._clearButton.removeEventListener("click", this._onClearButtonClick);
PerformanceController.off(EVENTS.RECORDING_SELECTED, this._onRecordingSelected);
PerformanceController.off(EVENTS.PROFILER_STATUS_UPDATED, this._onProfilerStatusUpdated);
PerformanceController.off(EVENTS.RECORDING_PROFILER_STATUS_UPDATE, this._onProfilerStatusUpdated);
PerformanceController.off(EVENTS.RECORDING_STATE_CHANGE, this._onRecordingStateChange);
PerformanceController.off(EVENTS.NEW_RECORDING, this._onRecordingStateChange);
PerformanceController.off(EVENTS.NEW_RECORDING_FAILED, this._onNewRecordingFailed);
PerformanceController.off(EVENTS.RECORDING_ADDED, this._onRecordingStateChange);
PerformanceController.off(EVENTS.BACKEND_FAILED_AFTER_RECORDING_START, this._onNewRecordingFailed);
yield ToolbarView.destroy();
yield RecordingsView.destroy();
@ -181,7 +181,7 @@ var PerformanceView = {
}
$bufferLabel.value = L10N.getFormatStr("profiler.bufferFull", percent);
this.emit(EVENTS.UI_BUFFER_STATUS_UPDATED, percent);
this.emit(EVENTS.UI_RECORDING_PROFILER_STATUS_RENDERED, percent);
},
/**
@ -298,10 +298,10 @@ var PerformanceView = {
* Fired when the controller has updated information on the buffer's status.
* Update the buffer status display if shown.
*/
_onProfilerStatusUpdated: function (_, data) {
_onProfilerStatusUpdated: function (_, profilerStatus) {
// We only care about buffer status here, so check to see
// if it has position.
if (!data || data.position === void 0) {
if (!profilerStatus || profilerStatus.position === void 0) {
return;
}
// If this is our first buffer event, set the status and add a class

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

@ -12,12 +12,11 @@ support-files =
head.js
[browser_aaa-run-first-leaktest.js]
[browser_perf-categories-js-calltree.js]
[browser_perf-clear-01.js]
[browser_perf-clear-02.js]
skip-if = os == "linux" # Bug 1230031
[browser_perf-columns-js-calltree.js]
[browser_perf-columns-memory-calltree.js]
[browser_perf-button-states.js]
[browser_perf-calltree-js-categories.js]
[browser_perf-calltree-js-columns.js]
[browser_perf-calltree-js-events.js]
[browser_perf-calltree-memory-columns.js]
[browser_perf-console-record-01.js]
[browser_perf-console-record-02.js]
[browser_perf-console-record-03.js]
@ -27,129 +26,98 @@ skip-if = os == "linux" # Bug 1230031
[browser_perf-console-record-07.js]
[browser_perf-console-record-08.js]
[browser_perf-console-record-09.js]
[browser_perf-details-calltree-render.js]
[browser_perf-details-flamegraph-render.js]
[browser_perf-details-memory-calltree-render.js]
[browser_perf-details-memory-flamegraph-render.js]
[browser_perf-details-waterfall-gc-snap.js]
skip-if = true # Bug 1161817
[browser_perf-details-waterfall-render.js]
[browser_perf-details-01.js]
[browser_perf-details-02.js]
[browser_perf-details-03.js]
[browser_perf-details-04.js]
[browser_perf-details-05.js]
[browser_perf-details-06.js]
[browser_perf-details-07.js]
[browser_perf-events-calltree.js]
[browser_perf-details-01-toggle.js]
[browser_perf-details-02-utility-fun.js]
[browser_perf-details-03-without-allocations.js]
[browser_perf-details-04-toolbar-buttons.js]
[browser_perf-details-05-preserve-view.js]
[browser_perf-details-06-rerender-on-selection.js]
[browser_perf-details-07-bleed-events.js]
# [browser_perf-details-gc-snap.js] TODO bug 1256350
[browser_perf-details-render-00-waterfall.js]
[browser_perf-details-render-01-js-calltree.js]
[browser_perf-details-render-02-js-flamegraph.js]
[browser_perf-details-render-03-memory-calltree.js]
[browser_perf-details-render-04-memory-flamegraph.js]
[browser_perf-docload.js]
[browser_perf-highlighted.js]
[browser_perf-legacy-front-01.js]
[browser_perf-legacy-front-02.js]
[browser_perf-legacy-front-03.js]
[browser_perf-legacy-front-04.js]
[browser_perf-legacy-front-05.js]
[browser_perf-legacy-front-06.js]
[browser_perf-legacy-front-07.js]
[browser_perf-legacy-front-08.js]
[browser_perf-legacy-front-09.js]
[browser_perf-loading-01.js]
[browser_perf-loading-02.js]
[browser_perf-marker-details-01.js]
[browser_perf-markers-docload.js]
[browser_perf-options-01.js]
[browser_perf-options-02.js]
[browser_perf-options-03.js]
# [browser_perf-marker-details.js] TODO bug 1256350
[browser_perf-options-01-toggle-throw.js]
[browser_perf-options-02-toggle-throw-alt.js]
[browser_perf-options-03-toggle-meta.js]
[browser_perf-options-enable-framerate-01.js]
[browser_perf-options-enable-framerate-02.js]
[browser_perf-options-enable-memory-01.js]
[browser_perf-options-enable-memory-02.js]
[browser_perf-options-flatten-tree-recursion-01.js]
[browser_perf-options-flatten-tree-recursion-02.js]
[browser_perf-options-invert-call-tree-01.js]
[browser_perf-options-invert-call-tree-02.js]
[browser_perf-options-invert-flame-graph-01.js]
[browser_perf-options-invert-flame-graph-02.js]
[browser_perf-options-flatten-tree-recursion-01.js]
[browser_perf-options-flatten-tree-recursion-02.js]
[browser_perf-options-show-jit-optimizations.js]
[browser_perf-options-show-platform-data-01.js]
[browser_perf-options-show-platform-data-02.js]
[browser_perf-options-propagate-allocations.js]
[browser_perf-options-propagate-profiler.js]
[browser_perf-options-show-idle-blocks-01.js]
[browser_perf-options-show-idle-blocks-02.js]
[browser_perf-options-enable-memory-01.js]
[browser_perf-options-enable-memory-02.js]
[browser_perf-options-enable-framerate.js]
[browser_perf-options-allocations.js]
[browser_perf-options-profiler.js]
# [browser_perf-options-show-jit-optimizations.js] TODO bug 1256350
[browser_perf-options-show-platform-data-01.js]
[browser_perf-options-show-platform-data-02.js]
[browser_perf-overview-render-01.js]
[browser_perf-overview-render-02.js]
[browser_perf-overview-render-03.js]
[browser_perf-overview-render-04.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-overview-selection-01.js]
[browser_perf-overview-selection-02.js]
[browser_perf-overview-selection-03.js]
[browser_perf-overview-time-interval.js]
[browser_perf-private-browsing.js]
skip-if = os == 'linux' # bug 1210140
[browser_perf-states.js]
skip-if = debug # bug 1203888
[browser_perf-refresh.js]
[browser_perf-ui-recording.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-01.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-02.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-03.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-04.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-05.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-01.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-02.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-03.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-04.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-05.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recordings-io-06.js]
skip-if = os == 'linux' # bug 1186322
# [browser_perf-private-browsing.js] TODO bug 1256350
[browser_perf-range-changed-render.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-notices-01.js]
[browser_perf-recording-notices-02.js]
[browser_perf-recording-notices-03.js]
[browser_perf-recording-notices-04.js]
[browser_perf-recording-notices-05.js]
[browser_perf-recording-selected-01.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-selected-02.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-selected-03.js]
skip-if = os == 'linux' # bug 1186322
[browser_perf-recording-selected-04.js]
skip-if = os == 'linux' || debug # bug 1186322 for Linux, bug 1203895 for leaks
[browser_perf-theme-toggle-01.js]
[browser_perf-recordings-clear-01.js]
[browser_perf-recordings-clear-02.js]
# [browser_perf-recordings-io-01.js] TODO bug 1256350
# [browser_perf-recordings-io-02.js] TODO bug 1256350
# [browser_perf-recordings-io-03.js] TODO bug 1256350
# [browser_perf-recordings-io-04.js] TODO bug 1256350
# [browser_perf-recordings-io-05.js] TODO bug 1256350
# [browser_perf-recordings-io-06.js] TODO bug 1256350
[browser_perf-refresh.js]
[browser_perf-states.js]
[browser_perf-telemetry-01.js]
[browser_perf-telemetry-02.js]
[browser_perf-telemetry-03.js]
[browser_perf-telemetry-04.js]
[browser_profiler_tree-abstract-01.js]
[browser_profiler_tree-abstract-02.js]
[browser_profiler_tree-abstract-03.js]
[browser_profiler_tree-abstract-04.js]
[browser_profiler_tree-view-01.js]
[browser_profiler_tree-view-02.js]
[browser_profiler_tree-view-03.js]
[browser_profiler_tree-view-04.js]
[browser_profiler_tree-view-05.js]
[browser_profiler_tree-view-06.js]
[browser_profiler_tree-view-07.js]
[browser_profiler_tree-view-08.js]
[browser_profiler_tree-view-09.js]
[browser_profiler_tree-view-10.js]
[browser_profiler_tree-view-11.js]
[browser_timeline-filters-01.js]
skip-if = true # Bug 1176370
[browser_timeline-filters-02.js]
# [browser_perf-theme-toggle.js] TODO bug 1256350
[browser_perf-tree-abstract-01.js]
[browser_perf-tree-abstract-02.js]
[browser_perf-tree-abstract-03.js]
[browser_perf-tree-abstract-04.js]
[browser_perf-tree-view-01.js]
[browser_perf-tree-view-02.js]
[browser_perf-tree-view-03.js]
[browser_perf-tree-view-04.js]
[browser_perf-tree-view-05.js]
[browser_perf-tree-view-06.js]
[browser_perf-tree-view-07.js]
[browser_perf-tree-view-08.js]
[browser_perf-tree-view-09.js]
[browser_perf-tree-view-10.js]
# [browser_perf-tree-view-11.js] TODO bug 1256350
[browser_perf-ui-recording.js]
# [browser_timeline-filters-01.js] TODO bug 1256350
# [browser_timeline-filters-02.js] TODO bug 1256350
[browser_timeline-waterfall-background.js]
[browser_timeline-waterfall-generic.js]
[browser_timeline-waterfall-rerender.js]
skip-if = true # Bug 1170105
[browser_timeline-waterfall-sidebar.js]
skip-if = true # Bug 1161817
[browser_timeline-waterfall-workers.js]
# [browser_timeline-waterfall-rerender.js] TODO bug 1256350
# [browser_timeline-waterfall-sidebar.js] TODO bug 1256350
# [browser_timeline-waterfall-workers.js] TODO bug 1256350

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

@ -1,22 +1,28 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the performance tool leaks on initialization and sudden destruction.
* You can also use this initialization format as a template for other tests.
*/
function* spawnTest() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
add_task(function*() {
let { target, toolbox, panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
ok(target, "Should have a target available.");
ok(toolbox, "Should have a toolbox available.");
ok(panel, "Should have a panel available.");
ok(panel.panelWin.gToolbox, "Should have a toolbox reference on the panel window.");
ok(panel.panelWin.gTarget, "Should have a target reference on the panel window.");
ok(panel.panelWin.gToolbox, "Should have a toolbox reference on the panel window.");
ok(panel.panelWin.gFront, "Should have a front reference on the panel window.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,76 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the recording button states are set as expected.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $, EVENTS, PerformanceController, PerformanceView } = panel.panelWin;
let recordButton = $("#main-record-button");
ok(!recordButton.hasAttribute("checked"),
"The record button should not be checked yet.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked yet.");
let uiStartClick = once(PerformanceView, EVENTS.UI_START_RECORDING);
let recordingStarted = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-started" }
});
let backendStartReady = once(PerformanceController, EVENTS.BACKEND_READY_AFTER_RECORDING_START);
let uiStateRecording = once(PerformanceView, EVENTS.UI_STATE_CHANGED, {
expectedArgs: { "1": "recording" }
});
click(recordButton);
yield uiStartClick;
ok(recordButton.hasAttribute("checked"),
"The record button should now be checked.");
ok(recordButton.hasAttribute("locked"),
"The record button should be locked.");
yield recordingStarted;
ok(recordButton.hasAttribute("checked"),
"The record button should still be checked.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked.");
yield backendStartReady;
yield uiStateRecording;
let uiStopClick = once(PerformanceView, EVENTS.UI_STOP_RECORDING);
let recordingStopped = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopped" }
});
let backendStopReady = once(PerformanceController, EVENTS.BACKEND_READY_AFTER_RECORDING_STOP);
let uiStateRecorded = once(PerformanceView, EVENTS.UI_STATE_CHANGED, {
expectedArgs: { "1": "recorded" }
});
click(recordButton);
yield uiStopClick;
yield recordingStopped;
ok(!recordButton.hasAttribute("checked"),
"The record button should not be checked.");
ok(!recordButton.hasAttribute("locked"),
"The record button should not be locked.");
yield backendStopReady;
yield uiStateRecorded;
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the categories are shown in the js call tree when
* platform data is enabled.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_SHOW_PLATFORM_DATA_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { busyWait } = require("devtools/client/performance/test/helpers/wait-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, $$, DetailsView, JsCallTreeView } = panel.panelWin;
// Enable platform data to show the categories in the tree.
Services.prefs.setBoolPref(UI_SHOW_PLATFORM_DATA_PREF, true);
yield startRecording(panel);
yield busyWait(100); // To show the `Gecko` category in the tree.
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield rendered;
is($(".call-tree-cells-container").hasAttribute("categories-hidden"), false,
"The call tree cells container should show the categories now.");
ok(geckoCategoryPresent($$),
"A category node with the text `Gecko` is displayed in the tree.");
// Disable platform data to hide the categories.
Services.prefs.setBoolPref(UI_SHOW_PLATFORM_DATA_PREF, false);
is($(".call-tree-cells-container").getAttribute("categories-hidden"), "",
"The call tree cells container should hide the categories now.");
ok(!geckoCategoryPresent($$),
"A category node with the text `Gecko` doesn't exist in the tree anymore.");
yield teardownToolboxAndRemoveTab(panel);
});
function geckoCategoryPresent($$) {
for (let elem of $$(".call-tree-category")) {
if (elem.textContent.trim() == "Gecko") {
return true;
}
}
return false;
}

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

@ -1,28 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js call tree view renders the correct columns.
*/
function* spawnTest() {
// This test seems to take a long time to cleanup on Ubuntu VMs.
requestLongerTimeout(2);
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_SHOW_PLATFORM_DATA_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { busyWait } = require("devtools/client/performance/test/helpers/wait-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, $$, DetailsView, JsCallTreeView } = panel.panelWin;
// Enable platform data to show the `busyWait` function in the tree.
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, true);
// Enable platform data to show the platform functions in the tree.
Services.prefs.setBoolPref(UI_SHOW_PLATFORM_DATA_PREF, true);
yield startRecording(panel);
yield busyWait(1000);
let rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield busyWait(100); // To show the `busyWait` function in the tree.
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
yield rendered;
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
testCells($, $$, {
"duration": true,
"percentage": true,
@ -34,9 +45,8 @@ function* spawnTest() {
"function": true
});
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});
function testCells($, $$, visibleCells) {
for (let cell in visibleCells) {

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

@ -0,0 +1,51 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the call tree up/down events work for js calltrees.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { synthesizeProfile } = require("devtools/client/performance/test/helpers/synth-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { ThreadNode } = require("devtools/client/performance/modules/logic/tree-model");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, DetailsView, OverviewView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield rendered;
// Mock the profile used so we can get a deterministic tree created.
let profile = synthesizeProfile();
let threadNode = new ThreadNode(profile.threads[0], OverviewView.getTimeInterval());
JsCallTreeView._populateCallTree(threadNode);
JsCallTreeView.emit(EVENTS.UI_JS_CALL_TREE_RENDERED);
let count = 0;
let onFocus = () => count++;
JsCallTreeView.on("focus", onFocus);
click($("#js-calltree-view .call-tree-item"));
key("VK_DOWN");
key("VK_DOWN");
key("VK_DOWN");
key("VK_DOWN");
JsCallTreeView.off("focus", onFocus);
is(count, 4, "Several focus events are fired for the calltree.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,25 +1,37 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the memory call tree view renders the correct columns.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, $$, DetailsView, MemoryCallTreeView } = panel.panelWin;
// Enable memory to test.
Services.prefs.setBoolPref(MEMORY_PREF, true);
// Enable allocations to test.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield busyWait(100);
let rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
yield stopRecording(panel);
let rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
yield DetailsView.selectView("memory-calltree");
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
yield rendered;
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
testCells($, $$, {
"duration": false,
"percentage": false,
@ -37,9 +49,8 @@ function* spawnTest() {
"function": true
});
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});
function testCells($, $$, visibleCells) {
for (let cell in visibleCells) {

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

@ -1,49 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the categories are shown in the js call tree when platform data
* is enabled.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, $$, DetailsView, JsCallTreeView } = panel.panelWin;
// Enable platform data to show the categories.
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, true);
yield startRecording(panel);
yield busyWait(100);
let rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield stopRecording(panel);
yield DetailsView.selectView("js-calltree");
yield rendered;
is($(".call-tree-cells-container").hasAttribute("categories-hidden"), false,
"The call tree cells container should show the categories now.");
ok(geckoCategoryPresent($$),
"A category node with the text `Gecko` is displayed in the tree.");
// Disable platform data to show the categories.
Services.prefs.setBoolPref(PLATFORM_DATA_PREF, false);
is($(".call-tree-cells-container").getAttribute("categories-hidden"), "",
"The call tree cells container should hide the categories now.");
ok(!geckoCategoryPresent($$),
"A category node with the text `Gecko` doesn't exist in the tree anymore.");
yield teardown(panel);
finish();
}
function geckoCategoryPresent($$) {
for (let elem of $$('.call-tree-category')) {
if (elem.textContent.trim() == 'Gecko') {
return true
}
}
return false
}

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

@ -1,30 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that clearing recordings empties out the recordings list and toggles
* the empty notice state.
*/
var test = Task.async(function*() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, PerformanceView, RecordingsView, OverviewView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
yield startRecording(panel);
yield stopRecording(panel);
yield PerformanceController.clearRecordings();
is(RecordingsView.itemCount, 0,
"RecordingsView should be empty.");
is(PerformanceView.getState(), "empty",
"PerformanceView should be in an empty state.");
is(PerformanceController.getCurrentRecording(), null,
"There should be no current recording.");
yield teardown(panel);
finish();
});

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

@ -1,50 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that clearing recordings empties out the recordings list and stops
* a current recording if recording and can continue recording after.
*/
var test = Task.async(function*() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, PerformanceView, RecordingsView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
yield startRecording(panel);
let deleted = Promise.defer();
let deleteCount = 0;
function onDeleted () {
if (++deleteCount === 2) {
deleted.resolve();
PerformanceController.off(EVENTS.RECORDING_DELETED, onDeleted);
}
}
PerformanceController.on(EVENTS.RECORDING_DELETED, onDeleted);
let stopped = Promise.all([
once(PerformanceController, EVENTS.RECORDING_STOPPED),
deleted.promise
]);
PerformanceController.clearRecordings();
yield stopped;
is(RecordingsView.itemCount, 0,
"RecordingsView should be empty.");
is(PerformanceView.getState(), "empty",
"PerformanceView should be in an empty state.");
is(PerformanceController.getCurrentRecording(), null,
"There should be no current recording.");
// bug 1169146: Try another recording after clearing mid-recording
yield startRecording(panel);
yield stopRecording(panel);
yield teardown(panel);
finish();
});

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

@ -1,42 +1,41 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the profiler is populated by console recordings that have finished
* before it was opened.
*/
var WAIT_TIME = 10;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
function* spawnTest() {
let { target, toolbox, console } = yield initConsole(SIMPLE_URL);
let front = toolbox.performance;
add_task(function*() {
let { target, toolbox, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let profileStart = once(front, "recording-started");
console.profile("rust");
yield profileStart;
yield console.profile("rust");
yield console.profileEnd("rust");
busyWait(WAIT_TIME);
let profileEnd = once(front, "recording-stopped");
console.profileEnd("rust");
yield profileEnd;
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView, WaterfallView } = panel.panelWin;
yield gDevTools.showToolbox(target, "performance");
let panel = yield toolbox.getCurrentPanel().open();
let { panelWin: { PerformanceController, RecordingsView }} = panel;
yield waitUntil(() => PerformanceController.getRecordings().length == 1);
yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce);
let recordings = PerformanceController.getRecordings();
yield waitUntil(() => PerformanceController.getRecordings().length === 1);
is(recordings.length, 1, "one recording found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "correct label in the recording model.");
is(recordings.length, 1, "One recording found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "Correct label in the recording model.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The profile from console should be selected as its the only one in the RecordingsView.");
"The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,48 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the profiler is populated by in-progress console recordings
* when it is opened.
*/
function* spawnTest() {
let { target, toolbox, console } = yield initConsole(SIMPLE_URL);
let front = toolbox.performance;
const { Constants } = require("devtools/client/performance/modules/constants");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
const { times } = require("devtools/client/performance/test/helpers/event-utils");
let profileStart = once(front, "recording-started");
console.profile("rust");
yield profileStart;
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
profileStart = once(front, "recording-started");
console.profile("rust2");
yield profileStart;
yield console.profile("rust");
yield console.profile("rust2");
yield gDevTools.showToolbox(target, "performance");
let panel = yield toolbox.getCurrentPanel().open();
let { panelWin: { PerformanceController, RecordingsView }} = panel;
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
yield waitUntil(() => PerformanceController.getRecordings().length == 2);
yield waitUntil(() => PerformanceController.getRecordings().length === 2);
let recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "two recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile (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[1].isConsole(), true, "recording came from console.profile (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.length, 2, "Two recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile (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[1].isConsole(), true, "Recording came from console.profile (2).");
is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
let profileEnd = once(front, "recording-stopped");
console.profileEnd("rust");
yield profileEnd;
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
profileEnd = once(front, "recording-stopped");
console.profileEnd("rust2");
yield profileEnd;
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profileEnd("rust");
yield stopped;
yield teardown(panel);
finish();
}
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
});
yield console.profileEnd("rust2");
yield stopped;
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,48 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the profiler is populated by in-progress console recordings, and
* also console recordings that have finished before it was opened.
*/
function* spawnTest() {
let { target, toolbox, console } = yield initConsole(SIMPLE_URL);
let front = toolbox.performance;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
let profileStart = once(front, "recording-started");
console.profile("rust");
yield profileStart;
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let profileEnd = once(front, "recording-stopped");
console.profileEnd("rust");
yield profileEnd;
yield console.profile("rust");
yield console.profileEnd("rust");
yield console.profile("rust2");
profileStart = once(front, "recording-started");
console.profile("rust2");
yield profileStart;
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView, WaterfallView } = panel.panelWin;
yield gDevTools.showToolbox(target, "performance");
let panel = yield toolbox.getCurrentPanel().open();
let { panelWin: { PerformanceController, RecordingsView }} = panel;
yield waitUntil(() => PerformanceController.getRecordings().length == 2);
yield waitUntil(() => WaterfallView.wasRenderedAtLeastOnce);
yield waitUntil(() => PerformanceController.getRecordings().length === 2);
let recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "two recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile (1).");
is(recordings[0].getLabel(), "rust", "correct label in the recording model (1).");
is(recordings[0].isRecording(), false, "recording is still recording (1).");
is(recordings[1].isConsole(), true, "recording came from console.profile (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.length, 2, "Two recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile (1).");
is(recordings[0].getLabel(), "rust", "Correct label in the recording model (1).");
is(recordings[0].isRecording(), false, "Recording is still recording (1).");
is(recordings[1].isConsole(), true, "Recording came from console.profile (2).");
is(recordings[1].getLabel(), "rust2", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
profileEnd = once(front, "recording-stopped");
console.profileEnd("rust2");
yield profileEnd;
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
});
yield console.profileEnd("rust2");
yield stopped;
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,34 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the profiler can handle creation and stopping of console profiles
* after being opened.
*/
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, gFront, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
const { Constants } = require("devtools/client/performance/modules/constants");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils");
yield consoleProfile(panel.panelWin, "rust");
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profile("rust");
yield started;
let recordings = PerformanceController.getRecordings();
is(recordings.length, 1, "a recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "correct label in the recording model.");
is(recordings[0].isRecording(), true, "recording is still recording.");
is(recordings.length, 1, "One recording found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "Correct label in the recording model.");
is(recordings[0].isRecording(), true, "Recording is still recording.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
"The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
// Ensure overview is still rendering
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
yield consoleProfileEnd(panel.panelWin, "rust");
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profileEnd("rust");
yield stopped;
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,45 +1,89 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
"use strict";
/**
* Tests that multiple recordings with the same label (non-overlapping) appear
* in the recording list.
*/
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, gFront, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
const { Constants } = require("devtools/client/performance/modules/constants");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils");
yield consoleProfile(panel.panelWin, "rust");
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profile("rust");
yield started;
let recordings = PerformanceController.getRecordings();
is(recordings.length, 1, "a recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile.");
is(recordings[0].getLabel(), "rust", "correct label in the recording model.");
is(recordings[0].isRecording(), true, "recording is still recording.");
is(recordings.length, 1, "One recording found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile (1).");
is(recordings[0].getLabel(), "rust", "Correct label in the recording model (1).");
is(recordings[0].isRecording(), true, "Recording is still recording (1).");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
"The profile from console should be selected as it's the only one.");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
// Ensure overview is still rendering
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
yield consoleProfileEnd(panel.panelWin, "rust");
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profileEnd("rust");
yield stopped;
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("rust");
yield started;
yield consoleProfile(panel.panelWin, "rust");
recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "a recordings found in the performance panel.");
is(recordings[1].isConsole(), true, "recording came from console.profile.");
is(recordings[1].getLabel(), "rust", "correct label in the recording model.");
is(recordings[1].isRecording(), true, "recording is still recording.");
is(recordings.length, 2, "Two recordings found in the performance panel.");
is(recordings[1].isConsole(), true, "Recording came from console.profile (2).");
is(recordings[1].getLabel(), "rust", "Correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "Recording is still recording (2).");
yield consoleProfileEnd(panel.panelWin, "rust");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The profile from console should still be selected");
is(RecordingsView.selectedItem.attachment.getLabel(), "rust",
"The profile label for the first recording is correct.");
yield teardown(panel);
finish();
}
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
});
yield console.profileEnd("rust");
yield stopped;
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,54 +1,95 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that console recordings can overlap (not completely nested).
*/
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, gFront, PerformanceController, OverviewView, RecordingsView, WaterfallView } = panel.panelWin;
const { Constants } = require("devtools/client/performance/modules/constants");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { times } = require("devtools/client/performance/test/helpers/event-utils");
yield consoleProfile(panel.panelWin, "rust");
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, OverviewView, RecordingsView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profile("rust");
yield started;
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],
"The first console recording should be selected.");
yield consoleProfile(panel.panelWin, "golang");
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("golang");
yield started;
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],
"The first console recording should still be selected.");
// Ensure overview is still rendering
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
yield consoleProfileEnd(panel.panelWin, "rust");
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profileEnd("rust");
yield stopped;
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],
"The first console recording should still be selected.");
is(RecordingsView.selectedItem.attachment.isRecording(), false,
is(recordings[0].isRecording(), false,
"The first console recording should no longer be recording.");
let detailsRendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield consoleProfileEnd(panel.panelWin, "golang");
yield detailsRendered;
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
});
yield console.profileEnd("golang");
yield stopped;
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],
"The first console recording should still be selected.");
is(recordings[1].isRecording(), false,
"The second console recording should no longer be recording.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,48 +1,150 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that a call to console.profileEnd() with no label ends the
* most recent console recording, and console.profileEnd() with a label that does not
* match any pending recordings does nothing.
* most recent console recording, and console.profileEnd() with a label that
* does not match any pending recordings does nothing.
*/
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, gFront, PerformanceController, OverviewView, RecordingsView, WaterfallView } = panel.panelWin;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { waitForRecordingStartedEvents, waitForRecordingStoppedEvents } = require("devtools/client/performance/test/helpers/actions");
const { idleWait } = require("devtools/client/performance/test/helpers/wait-utils");
yield consoleProfile(panel.panelWin);
yield consoleProfile(panel.panelWin, "1");
yield consoleProfile(panel.panelWin, "2");
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController, RecordingsView } = panel.panelWin;
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profile();
yield started;
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("1");
yield started;
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("2");
yield started;
let recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "3 recordings found");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
yield consoleProfileEnd(panel.panelWin);
// First off a label-less profileEnd to make sure no other recordings close
consoleProfileEnd(panel.panelWin, "fxos");
yield idleWait(500);
recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "3 recordings found");
is(recordings.length, 3, "Three recordings found in the performance panel.");
is(recordings[0].getLabel(), "", "Checking label of recording 1");
is(recordings[1].getLabel(), "1", "Checking label of recording 2");
is(recordings[2].getLabel(), "2", "Checking label of recording 3");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
is(recordings[0].isRecording(), true,
"All recordings should now be started. (1)");
is(recordings[1].isRecording(), true,
"All recordings should now be started. (2)");
is(recordings[2].isRecording(), true,
"All recordings should now be started. (3)");
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
// the view state won't switch to "recorded" unless the new
// finished recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profileEnd();
yield stopped;
recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should still be selected.");
is(recordings[0].isRecording(), true,
"The not most recent recording should not stop when calling console.profileEnd with no args.");
is(recordings[1].isRecording(), true,
"The not most recent recording should not stop when calling console.profileEnd with no args.");
is(recordings[2].isRecording(), false,
"Only thw most recent recording should stop when calling console.profileEnd with no args.");
"Only the most recent recording should stop when calling console.profileEnd with no args.");
let detailsRendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield consoleProfileEnd(panel.panelWin);
yield consoleProfileEnd(panel.panelWin);
info("Trying to `profileEnd` a non-existent console recording.");
/* yield */ console.profileEnd("fxos");
yield idleWait(1000);
recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should still be selected.");
is(recordings[0].isRecording(), true,
"The first recording should not be ended yet.");
is(recordings[1].isRecording(), true,
"The second recording should not be ended yet.");
is(recordings[2].isRecording(), false,
"The third recording should still be ended.");
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
// the view state won't switch to "recorded" unless the new
// finished recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profileEnd();
yield stopped;
recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should still be selected.");
is(recordings[0].isRecording(), true,
"The first recording should not be ended yet.");
is(recordings[1].isRecording(), false,
"The second recording should not be ended yet.");
is(recordings[2].isRecording(), false,
"The third recording should still be ended.");
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profileEnd();
yield stopped;
recordings = PerformanceController.getRecordings();
is(recordings.length, 3, "Three recordings found in the performance panel.");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
is(recordings[0].isRecording(), false,
"All recordings should now be ended. (1)");
@ -51,12 +153,11 @@ function* spawnTest() {
is(recordings[2].isRecording(), false,
"All recordings should now be ended. (3)");
yield detailsRendered;
info("Trying to `profileEnd` with no pending recordings.");
/* yield */ console.profileEnd();
yield idleWait(1000);
consoleProfileEnd(panel.panelWin);
yield idleWait(500);
ok(true, "Calling additional console.profileEnd() with no argument and no pending recordings does not throw.");
ok(true, "Calling console.profileEnd() with no argument and no pending recordings does not throw.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,88 +1,181 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the profiler can correctly handle simultaneous console and manual
* recordings (via `console.profile` and clicking the record button).
*/
var C = 1; // is console
var R = 2; // is recording
var S = 4; // is selected
const { Constants } = require("devtools/client/performance/modules/constants");
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = 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");
function testRecordings (win, expected) {
let recordings = win.PerformanceController.getRecordings();
let current = win.PerformanceController.getCurrentRecording();
is(recordings.length, expected.length, "expected number of recordings");
recordings.forEach((recording, i) => {
ok(recording.isConsole() == !!(expected[i] & C), `recording ${i+1} has expected console state.`);
ok(recording.isRecording() == !!(expected[i] & R), `recording ${i+1} has expected console state.`);
ok((recording === current) == !!(expected[i] & S), `recording ${i+1} has expected selected state.`);
add_task(function*() {
// This test seems to take a very long time to finish on Linux VMs.
requestLongerTimeout(4);
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
}
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, OverviewView, RecordingsView, WaterfallView } = panel.panelWin;
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { EVENTS, PerformanceController, RecordingsView, OverviewView } = panel.panelWin;
info("Starting console.profile()...");
yield consoleProfile(panel.panelWin);
testRecordings(panel.panelWin, [C+S+R]);
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true
});
yield console.profile("rust");
yield started;
testRecordings(PerformanceController, [C+S+R]);
info("Starting manual recording...");
yield startRecording(panel);
testRecordings(panel.panelWin, [C+R, R+S]);
testRecordings(PerformanceController, [C+R, R+S]);
info("Starting console.profile(\"3\")...");
yield consoleProfile(panel.panelWin, "3");
testRecordings(panel.panelWin, [C+R, R+S, C+R]);
info("Starting console.profile(\"3\")...");
yield consoleProfile(panel.panelWin, "4");
testRecordings(panel.panelWin, [C+R, R+S, C+R, C+R]);
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("3");
yield started;
testRecordings(PerformanceController, [C+R, R+S, C+R]);
info("Starting console.profile(\"4\")...");
started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile("4");
yield started;
testRecordings(PerformanceController, [C+R, R+S, C+R, C+R]);
info("Ending console.profileEnd()...");
yield consoleProfileEnd(panel.panelWin);
let stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
// the view state won't switch to "recorded" unless the new
// finished recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profileEnd();
yield stopped;
testRecordings(PerformanceController, [C+R, R+S, C+R, C]);
testRecordings(panel.panelWin, [C+R, R+S, C+R, C]);
ok(OverviewView.isRendering(), "still rendering overview with manual recorded selected.");
let onSelected = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
info("Select last recording...");
let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 3;
yield onSelected;
testRecordings(panel.panelWin, [C+R, R, C+R, C+S]);
ok(!OverviewView.isRendering(), "stop rendering overview when selected completed recording.");
yield recordingSelected;
testRecordings(PerformanceController, [C+R, R, C+R, C+S]);
ok(!OverviewView.isRendering(), "Stop rendering overview when a completed recording is selected.");
info("Manually stop manual recording...");
yield stopRecording(panel);
testRecordings(panel.panelWin, [C+R, S, C+R, C]);
ok(!OverviewView.isRendering(), "stop rendering overview when selected completed recording.");
onSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
info("Select first recording...");
RecordingsView.selectedIndex = 0;
yield onSelected;
testRecordings(panel.panelWin, [C+R+S, 0, C+R, C]);
yield once(OverviewView, EVENTS.OVERVIEW_RENDERED);
ok(OverviewView.isRendering(), "should be rendering overview when selected recording in progress.");
info("Ending console.profileEnd()...");
yield consoleProfileEnd(panel.panelWin);
testRecordings(panel.panelWin, [C+R+S, 0, C, C]);
ok(OverviewView.isRendering(), "should still be rendering overview when selected recording in progress.");
info("Start one more manual recording...");
yield startRecording(panel);
testRecordings(panel.panelWin, [C+R, 0, C, C, R+S]);
ok(OverviewView.isRendering(), "should be rendering overview when selected recording in progress.");
info("Stop manual recording...");
yield stopRecording(panel);
testRecordings(panel.panelWin, [C+R, 0, C, C, S]);
ok(!OverviewView.isRendering(), "stop rendering overview when selected completed recording.");
testRecordings(PerformanceController, [C+R, S, C+R, C]);
ok(!OverviewView.isRendering(), "Stop rendering overview when a completed recording is selected.");
info("Select first recording...");
recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0;
yield recordingSelected;
testRecordings(PerformanceController, [C+R+S, 0, C+R, C]);
ok(OverviewView.isRendering(), "Should be rendering overview a recording in progress is selected.");
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
info("Ending console.profileEnd()...");
yield consoleProfileEnd(panel.panelWin);
testRecordings(panel.panelWin, [C, 0, C, C, S]);
ok(!OverviewView.isRendering(), "stop rendering overview when selected completed recording.");
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
// the view state won't switch to "recorded" unless the new
// finished recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profileEnd();
yield stopped;
testRecordings(PerformanceController, [C+R+S, 0, C, C]);
ok(OverviewView.isRendering(), "Should be rendering overview a recording in progress is selected.");
yield teardown(panel);
finish();
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
info("Start one more manual recording...");
yield startRecording(panel);
testRecordings(PerformanceController, [C+R, 0, C, C, R+S]);
ok(OverviewView.isRendering(), "Should be rendering overview a recording in progress is selected.");
// Ensure overview is still rendering.
yield times(OverviewView, EVENTS.UI_OVERVIEW_RENDERED, 3, {
expectedArgs: { "1": Constants.FRAMERATE_GRAPH_LOW_RES_INTERVAL }
});
info("Stop manual recording...");
yield stopRecording(panel);
testRecordings(PerformanceController, [C+R, 0, C, C, S]);
ok(!OverviewView.isRendering(), "Stop rendering overview when a completed recording is selected.");
info("Ending console.profileEnd()...");
stopped = waitForRecordingStoppedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when a finished recording is selected
skipWaitingForOverview: true,
skipWaitingForSubview: true,
// the view state won't switch to "recorded" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profileEnd();
yield stopped;
testRecordings(PerformanceController, [C, 0, C, C, S]);
ok(!OverviewView.isRendering(), "Stop rendering overview when a completed recording is selected.");
yield teardownToolboxAndRemoveTab(panel);
});
const C = 1; // is console
const R = 2; // is recording
const S = 4; // is selected
function testRecordings(controller, expected) {
let recordings = controller.getRecordings();
let current = controller.getCurrentRecording();
is(recordings.length, expected.length, "Expected number of recordings.");
recordings.forEach((recording, i) => {
ok(recording.isConsole() == !!(expected[i] & C),
`Recording ${i+1} has expected console state.`);
ok(recording.isRecording() == !!(expected[i] & R),
`Recording ${i+1} has expected console state.`);
ok((recording == current) == !!(expected[i] & S),
`Recording ${i+1} has expected selected state.`);
});
}

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

@ -1,41 +1,63 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that an error is not thrown when clearing out the recordings if there's
* an in-progress console profile and that console profiles are not cleared if in progress.
* an in-progress console profile and that console profiles are not cleared
* if in progress.
*/
function* spawnTest() {
PMM_loadFrameScripts(gBrowser);
let { target, toolbox, panel } = yield initPerformance(SIMPLE_URL);
let win = panel.panelWin;
let { gFront, PerformanceController } = win;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = 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");
add_task(function*() {
let { target, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let { panel } = yield initPerformanceInTab({ tab: target.tab });
let { PerformanceController } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
info("Starting console.profile()...");
yield consoleProfile(win);
let started = waitForRecordingStartedEvents(panel, {
// only emitted for manual recordings
skipWaitingForBackendReady: true,
// only emitted when an in-progress recording is selected
skipWaitingForOverview: true,
// the view state won't switch to "console-recording" unless the new
// in-progress recording is selected, which won't happen
skipWaitingForViewState: true,
});
yield console.profile();
yield started;
yield PerformanceController.clearRecordings();
let recordings = PerformanceController.getRecordings();
is(recordings.length, 1, "1 recording found");
is(recordings[0].isConsole(), true, "recording from console.profile is not cleared.");
info("Ending console.profileEnd()...");
consoleMethod("profileEnd");
// Wait for the front to receive the stopped event
yield once(gFront, "recording-stopped");
is(recordings.length, 1, "One recording found in the performance panel.");
is(recordings[0].isConsole(), true, "Recording came from console.profile.");
is(recordings[0].getLabel(), "", "Correct label in the recording model.");
is(PerformanceController.getCurrentRecording(), recordings[0],
"There current recording should be the first one.");
info("Attempting to end console.profileEnd()...");
yield console.profileEnd();
yield idleWait(1000);
// Wait an extra tick or two since the above promise will be resolved
// the same time as _onRecordingStateChange, which should not cause any throwing
yield idleWait(100);
ok(true, "Stopping an in-progress console profile after clearing recordings does not throw.");
yield PerformanceController.clearRecordings();
recordings = PerformanceController.getRecordings();
is(recordings.length, 0, "No recordings found");
is(PerformanceController.getCurrentRecording(), null,
"There should be no current recording.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,66 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the details view toggles subviews.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { command } = require("devtools/client/performance/test/helpers/input-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, DetailsView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
info("Checking views on startup.");
checkViews(DetailsView, $, "waterfall");
// Select calltree view.
let viewChanged = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED, { spreadArgs: true });
command($("toolbarbutton[data-view='js-calltree']"));
let [_, viewName] = yield viewChanged;
is(viewName, "js-calltree", "UI_DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, $, "js-calltree");
// Select js flamegraph view.
viewChanged = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED, { spreadArgs: true });
command($("toolbarbutton[data-view='js-flamegraph']"));
[_, viewName] = yield viewChanged;
is(viewName, "js-flamegraph", "UI_DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, $, "js-flamegraph");
// Select waterfall view.
viewChanged = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED, { spreadArgs: true });
command($("toolbarbutton[data-view='waterfall']"));
[_, viewName] = yield viewChanged;
is(viewName, "waterfall", "UI_DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, $, "waterfall");
yield teardownToolboxAndRemoveTab(panel);
});
function checkViews(DetailsView, $, currentView) {
for (let viewName in DetailsView.components) {
let button = $(`toolbarbutton[data-view="${viewName}"]`);
is(DetailsView.el.selectedPanel.id, DetailsView.components[currentView].id,
`DetailsView correctly has ${currentView} selected.`);
if (viewName == currentView) {
ok(button.getAttribute("checked"), `${viewName} button checked.`);
} else {
ok(!button.getAttribute("checked"), `${viewName} button not checked.`);
}
}
}

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

@ -1,54 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the details view toggles subviews.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, DetailsView, document: doc } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
info("views on startup");
checkViews(DetailsView, doc, "waterfall");
// Select calltree view
let viewChanged = onceSpread(DetailsView, EVENTS.DETAILS_VIEW_SELECTED);
command($("toolbarbutton[data-view='js-calltree']"));
let [_, viewName] = yield viewChanged;
is(viewName, "js-calltree", "DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, doc, "js-calltree");
// Select flamegraph view
viewChanged = onceSpread(DetailsView, EVENTS.DETAILS_VIEW_SELECTED);
command($("toolbarbutton[data-view='js-flamegraph']"));
[_, viewName] = yield viewChanged;
is(viewName, "js-flamegraph", "DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, doc, "js-flamegraph");
// Select waterfall view
viewChanged = onceSpread(DetailsView, EVENTS.DETAILS_VIEW_SELECTED);
command($("toolbarbutton[data-view='waterfall']"));
[_, viewName] = yield viewChanged;
is(viewName, "waterfall", "DETAILS_VIEW_SELECTED fired with view name");
checkViews(DetailsView, doc, "waterfall");
yield teardown(panel);
finish();
}
function checkViews (DetailsView, doc, currentView) {
for (let viewName in DetailsView.components) {
let button = doc.querySelector(`toolbarbutton[data-view="${viewName}"]`);
is(DetailsView.el.selectedPanel.id, DetailsView.components[currentView].id,
`DetailsView correctly has ${currentView} selected.`);
if (viewName === currentView) {
ok(button.getAttribute("checked"), `${viewName} button checked`);
} else {
ok(!button.getAttribute("checked"), `${viewName} button not checked`);
}
}
}

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

@ -0,0 +1,53 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the details view utility functions work as advertised.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, WaterfallView, JsCallTreeView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
// Select js calltree view.
let selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("js-calltree");
yield selected;
ok(DetailsView.isViewSelected(JsCallTreeView),
"The js calltree view is now selected in the details view.");
// Select js flamegraph view.
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("js-flamegraph");
yield selected;
ok(DetailsView.isViewSelected(JsFlameGraphView),
"The js flamegraph view is now selected in the details view.");
// Select waterfall view.
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("waterfall");
yield selected;
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is now selected in the details view.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,44 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the details view utility functions work as advertised.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView } = panel.panelWin;
let { WaterfallView, JsCallTreeView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
let selected = DetailsView.whenViewSelected(JsCallTreeView);
let notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("js-calltree");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(JsCallTreeView),
"The jscalltree view is now selected in the details view.");
selected = DetailsView.whenViewSelected(JsFlameGraphView);
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("js-flamegraph");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(JsFlameGraphView),
"The flamegraph view is now selected in the details view.");
selected = DetailsView.whenViewSelected(WaterfallView);
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("waterfall");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is now selected in the details view.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,119 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the details view hides the allocations buttons when a recording
* does not have allocations data ("withAllocations": false), and that when an
* allocations panel is selected to a panel that does not have allocations goes
* to a default panel instead.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, RecordingsView, DetailsView, WaterfallView, MemoryCallTreeView, MemoryFlameGraphView } = panel.panelWin;
let flameBtn = $("toolbarbutton[data-view='memory-flamegraph']");
let callBtn = $("toolbarbutton[data-view='memory-calltree']");
// Disable allocations to prevent recording them.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, false);
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
// Re-enable allocations to test.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
// The toolbar buttons will always be hidden when a recording isn't available,
// so make sure we have one that's finished.
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is still selected in the details view.");
is(callBtn.hidden, false,
"The `memory-calltree` button is shown when recording has memory data.");
is(flameBtn.hidden, false,
"The `memory-flamegraph` button is shown when recording has memory data.");
let selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
let rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
DetailsView.selectView("memory-calltree");
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(MemoryCallTreeView),
"The memory call tree view can now be selected.");
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
DetailsView.selectView("memory-flamegraph");
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(MemoryFlameGraphView),
"The memory flamegraph view can now be selected.");
// Select the first recording with no memory data.
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 0;
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is now selected when switching back to a recording that does not have memory data.");
is(callBtn.hidden, true,
"The `memory-calltree` button is hidden when recording has no memory data.");
is(flameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when recording has no memory data.");
// Go back to the recording with memory data.
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 1;
yield rendered;
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is still selected in the details view.");
is(callBtn.hidden, false,
"The `memory-calltree` button is shown when recording has memory data.");
is(flameBtn.hidden, false,
"The `memory-flamegraph` button is shown when recording has memory data.");
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
DetailsView.selectView("memory-calltree");
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(MemoryCallTreeView),
"The memory call tree view can be selected again after going back to the view with memory data.");
selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
DetailsView.selectView("memory-flamegraph");
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(MemoryFlameGraphView),
"The memory flamegraph view can be selected again after going back to the view with memory data.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,79 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the details view hides the memory buttons when a recording does not
* have memory data (withMemory: false), and that when a memory panel is selected,
* switching to a panel that does not have memory goes to a default panel instead.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, DetailsView } = panel.panelWin;
let { $, RecordingsView, WaterfallView, MemoryCallTreeView, MemoryFlameGraphView } = panel.panelWin;
Services.prefs.setBoolPref(ALLOCATIONS_PREF, false);
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
// The toolbar buttons will always be hidden when a recording isn't available,
// so make sure we have one that's finished.
yield startRecording(panel);
yield stopRecording(panel);
let flameBtn = $("toolbarbutton[data-view='memory-flamegraph']");
let callBtn = $("toolbarbutton[data-view='memory-calltree']");
is(flameBtn.hidden, false, "memory-flamegraph button shown when recording has memory data");
is(callBtn.hidden, false, "memory-calltree button shown when recording has memory data");
let selected = DetailsView.whenViewSelected(MemoryCallTreeView);
let notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
DetailsView.selectView("memory-calltree");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(MemoryCallTreeView),
"The memory call tree view can now be selected.");
selected = DetailsView.whenViewSelected(MemoryFlameGraphView);
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
DetailsView.selectView("memory-flamegraph");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(MemoryFlameGraphView),
"The memory flamegraph view can now be selected.");
// Select the first recording with no memory data
selected = DetailsView.whenViewSelected(WaterfallView);
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
RecordingsView.selectedIndex = 0;
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is now selected when switching back to a recording that does not have memory data");
is(flameBtn.hidden, true, "memory-flamegraph button hidden when recording does not have memory data");
is(callBtn.hidden, true, "memory-calltree button hidden when recording does not have memory data");
// Go back to the recording with memory data
let render = WaterfallView.once(EVENTS.WATERFALL_RENDERED);
RecordingsView.selectedIndex = 1;
yield render;
selected = DetailsView.whenViewSelected(MemoryCallTreeView);
notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
DetailsView.selectView("memory-calltree");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(MemoryCallTreeView),
"The memory call tree view can be selected again after going back to the view with memory data");
is(flameBtn.hidden, false, "memory-flamegraph button shown when recording has memory data");
is(callBtn.hidden, false, "memory-calltree button shown when recording has memory data");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,136 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the details view hides the toolbar buttons when a recording
* doesn't exist or is in progress.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, PerformanceController, RecordingsView, WaterfallView } = panel.panelWin;
let waterfallBtn = $("toolbarbutton[data-view='waterfall']");
let jsFlameBtn = $("toolbarbutton[data-view='js-flamegraph']");
let jsCallBtn = $("toolbarbutton[data-view='js-calltree']");
let memFlameBtn = $("toolbarbutton[data-view='memory-flamegraph']");
let memCallBtn = $("toolbarbutton[data-view='memory-calltree']");
is(waterfallBtn.hidden, true,
"The `waterfall` button is hidden when tool starts.");
is(jsFlameBtn.hidden, true,
"The `js-flamegraph` button is hidden when tool starts.");
is(jsCallBtn.hidden, true,
"The `js-calltree` button is hidden when tool starts.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when tool starts.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when tool starts.");
yield startRecording(panel);
is(waterfallBtn.hidden, true,
"The `waterfall` button is hidden when recording starts.");
is(jsFlameBtn.hidden, true,
"The `js-flamegraph` button is hidden when recording starts.");
is(jsCallBtn.hidden, true,
"The `js-calltree` button is hidden when recording starts.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when recording starts.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when recording starts.");
yield stopRecording(panel);
is(waterfallBtn.hidden, false,
"The `waterfall` button is visible when recording ends.");
is(jsFlameBtn.hidden, false,
"The `js-flamegraph` button is visible when recording ends.");
is(jsCallBtn.hidden, false,
"The `js-calltree` button is visible when recording ends.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when recording ends.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when recording ends.");
yield startRecording(panel);
is(waterfallBtn.hidden, true,
"The `waterfall` button is hidden when another recording starts.");
is(jsFlameBtn.hidden, true,
"The `js-flamegraph` button is hidden when another recording starts.");
is(jsCallBtn.hidden, true,
"The `js-calltree` button is hidden when another recording starts.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when another recording starts.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when another recording starts.");
let selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
let rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
RecordingsView.selectedIndex = 0;
yield selected;
yield rendered;
is(RecordingsView.selectedIndex, 0,
"The first recording was selected again.");
is(waterfallBtn.hidden, false,
"The `waterfall` button is visible when first recording selected.");
is(jsFlameBtn.hidden, false,
"The `js-flamegraph` button is visible when first recording selected.");
is(jsCallBtn.hidden, false,
"The `js-calltree` button is visible when first recording selected.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when first recording selected.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when first recording selected.");
selected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 1;
yield selected;
is(RecordingsView.selectedIndex, 1,
"The second recording was selected again.");
is(waterfallBtn.hidden, true,
"The `waterfall button` still is hidden when second recording selected.");
is(jsFlameBtn.hidden, true,
"The `js-flamegraph button` still is hidden when second recording selected.");
is(jsCallBtn.hidden, true,
"The `js-calltree button` still is hidden when second recording selected.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph button` still is hidden when second recording selected.");
is(memCallBtn.hidden, true,
"The `memory-calltree button` still is hidden when second recording selected.");
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
yield stopRecording(panel);
yield rendered;
is(RecordingsView.selectedIndex, 1,
"The second recording is still selected.");
is(waterfallBtn.hidden, false,
"The `waterfall` button is visible when second recording finished.");
is(jsFlameBtn.hidden, false,
"The `js-flamegraph` button is visible when second recording finished.");
is(jsCallBtn.hidden, false,
"The `js-calltree` button is visible when second recording finished.");
is(memFlameBtn.hidden, true,
"The `memory-flamegraph` button is hidden when second recording finished.");
is(memCallBtn.hidden, true,
"The `memory-calltree` button is hidden when second recording finished.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,92 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the details view hides the toolbar buttons when a recording
* doesn't exist or is in progress.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, $$, PerformanceController, RecordingsView, WaterfallView } = panel.panelWin;
let waterfallBtn = $("toolbarbutton[data-view='waterfall']");
let jsFlameBtn = $("toolbarbutton[data-view='js-flamegraph']");
let jsCallBtn = $("toolbarbutton[data-view='js-calltree']");
let memFlameBtn = $("toolbarbutton[data-view='memory-flamegraph']");
let memCallBtn = $("toolbarbutton[data-view='memory-calltree']");
is(waterfallBtn.hidden, true, "waterfall button hidden when tool starts.");
is(jsFlameBtn.hidden, true, "js-flamegraph button hidden when tool starts.");
is(jsCallBtn.hidden, true, "js-calltree button hidden when tool starts.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when tool starts.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when tool starts.");
yield startRecording(panel);
is(waterfallBtn.hidden, true, "waterfall button hidden when recording starts.");
is(jsFlameBtn.hidden, true, "js-flamegraph button hidden when recording starts.");
is(jsCallBtn.hidden, true, "js-calltree button hidden when recording starts.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when recording starts.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when recording starts.");
yield stopRecording(panel);
is(waterfallBtn.hidden, false, "waterfall button visible when recording ends.");
is(jsFlameBtn.hidden, false, "js-flamegraph button visible when recording ends.");
is(jsCallBtn.hidden, false, "js-calltree button visible when recording ends.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when recording ends.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when recording ends.");
yield startRecording(panel);
is(waterfallBtn.hidden, true, "waterfall button hidden when another recording starts.");
is(jsFlameBtn.hidden, true, "js-flamegraph button hidden when another recording starts.");
is(jsCallBtn.hidden, true, "js-calltree button hidden when another recording starts.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when another recording starts.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when another recording starts.");
let select = once(PerformanceController, EVENTS.RECORDING_SELECTED);
let render = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
mousedown(panel.panelWin, $$(".recording-item")[0]);
yield Promise.all([select, render]);
is(RecordingsView.selectedIndex, 0,
"The first recording was selected again.");
is(waterfallBtn.hidden, false, "waterfall button visible when first recording selected.");
is(jsFlameBtn.hidden, false, "js-flamegraph button visible when first recording selected.");
is(jsCallBtn.hidden, false, "js-calltree button visible when first recording selected.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when first recording selected.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when first recording selected.");
select = once(PerformanceController, EVENTS.RECORDING_SELECTED);
mousedown(panel.panelWin, $$(".recording-item")[1]);
yield select;
is(RecordingsView.selectedIndex, 1,
"The second recording was selected again.");
is(waterfallBtn.hidden, true, "waterfall button still hidden when second recording selected.");
is(jsFlameBtn.hidden, true, "js-flamegraph button still hidden when second recording selected.");
is(jsCallBtn.hidden, true, "js-calltree button still hidden when second recording selected.");
is(memFlameBtn.hidden, true, "memory-flamegraph button still hidden when second recording selected.");
is(memCallBtn.hidden, true, "memory-calltree button still hidden when second recording selected.");
render = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield stopRecording(panel);
yield render;
is(RecordingsView.selectedIndex, 1,
"The second recording is still selected.");
is(waterfallBtn.hidden, false, "waterfall button visible when second recording finished.");
is(jsFlameBtn.hidden, false, "js-flamegraph button visible when second recording finished.");
is(jsCallBtn.hidden, false, "js-calltree button visible when second recording finished.");
is(memFlameBtn.hidden, true, "memory-flamegraph button hidden when second recording finished.");
is(memCallBtn.hidden, true, "memory-calltree button hidden when second recording finished.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the same details view is selected after recordings are cleared
* and a new recording starts.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, PerformanceController, DetailsView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let selected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield selected;
yield rendered;
ok(DetailsView.isViewSelected(JsCallTreeView),
"The js calltree view is now selected in the details view.");
let cleared = once(PerformanceController, EVENTS.RECORDING_SELECTED, { expectedArgs: { "1": null } });
yield PerformanceController.clearRecordings();
yield cleared;
yield startRecording(panel);
yield stopRecording(panel, {
expectedViewClass: "JsCallTreeView",
expectedViewEvent: "UI_JS_CALL_TREE_RENDERED"
});
ok(DetailsView.isViewSelected(JsCallTreeView),
"The js calltree view is still selected in the details view.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,40 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the details view utility functions work as advertised.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView } = panel.panelWin;
let { PerformanceController, WaterfallView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
let selected = DetailsView.whenViewSelected(JsCallTreeView);
let notified = DetailsView.once(EVENTS.DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("js-calltree");
yield Promise.all([selected, notified]);
ok(DetailsView.isViewSelected(JsCallTreeView),
"The jscalltree view is now selected in the details view.");
yield PerformanceController.clearRecordings();
yield startRecording(panel);
let render = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield stopRecording(panel);
yield render;
ok(DetailsView.isViewSelected(JsCallTreeView),
"The jscalltree view is still selected in the details view");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,72 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that when flame chart views scroll to change selection,
* other detail views are rerendered.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
const { scrollCanvasGraph, HORIZONTAL_AXIS } = require("devtools/client/performance/test/helpers/input-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, OverviewView, DetailsView, WaterfallView, JsCallTreeView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let waterfallRendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 10, endTime: 20 });
yield waterfallRendered;
// Select the call tree to make sure it's initialized and ready to receive
// redrawing requests once reselected.
let callTreeRendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield callTreeRendered;
// Switch to the flamegraph and perform a scroll over the visualization.
// The waterfall and call tree should get rerendered when reselected.
let flamegraphRendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("js-flamegraph");
yield flamegraphRendered;
let overviewRangeSelected = once(OverviewView, EVENTS.UI_OVERVIEW_RANGE_SELECTED);
let waterfallRerendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
let callTreeRerendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED).then(() => {
ok(false, "FlameGraphView should not publicly rerender, the internal state " +
"and drawing should be handled by the underlying widget.");
});
// Reset the range to full view, trigger a "selection" event as if
// our mouse has done this
scrollCanvasGraph(JsFlameGraphView.graph, {
axis: HORIZONTAL_AXIS,
wheel: 200,
x: 10
});
yield overviewRangeSelected;
ok(true, "Overview range was changed.");
yield DetailsView.selectView("waterfall");
yield waterfallRerendered;
ok(true, "Waterfall rerendered by flame graph changing interval.");
yield DetailsView.selectView("js-calltree");
yield callTreeRerendered;
ok(true, "CallTree rerendered by flame graph changing interval.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,63 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the views with `shouldUpdateWhileMouseIsActive` works as intended.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, OverviewView, DetailsView, WaterfallView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
// Set the debounce on WaterfallView and JsFlameGraphView to 0
WaterfallView.rangeChangeDebounceTime = 0;
JsFlameGraphView.rangeChangeDebounceTime = 0;
yield DetailsView.selectView("js-flamegraph");
let duration = PerformanceController.getCurrentRecording().getDuration();
// Fake an active mouse
Object.defineProperty(OverviewView, "isMouseActive", { value: true });
// Flame Graph should update on every selection, debounced, while mouse is down
let flamegraphRendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
OverviewView.emit(EVENTS.OVERVIEW_RANGE_SELECTED, { startTime: 0, endTime: duration });
yield flamegraphRendered;
ok(true, "FlameGraph rerenders when mouse is active (1)");
flamegraphRendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
OverviewView.emit(EVENTS.OVERVIEW_RANGE_SELECTED, { startTime: 0, endTime: duration });
yield flamegraphRendered;
ok(true, "FlameGraph rerenders when mouse is active (2)");
ok(OverviewView.isMouseActive, "Fake mouse is still active");
// Fake an inactive mouse for rerender
Object.defineProperty(OverviewView, "isMouseActive", { value: false });
yield DetailsView.selectView("waterfall");
// Fake an active mouse for rerender
Object.defineProperty(OverviewView, "isMouseActive", { value: true });
let oneSecondElapsed = false;
let waterfallRendered = false;
WaterfallView.on(EVENTS.WATERFALL_RENDERED, () => waterfallRendered = true);
// Keep firing range selection events for one second
idleWait(1000).then(() => oneSecondElapsed = true);
yield waitUntil(() => {
OverviewView.emit(EVENTS.OVERVIEW_RANGE_SELECTED, { startTime: 0, endTime: duration });
return oneSecondElapsed;
});
ok(OverviewView.isMouseActive, "Fake mouse is still active");
ok(!waterfallRendered, "the waterfall view should not have been rendered while mouse is active.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,48 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that events don't bleed between detail views.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, WaterfallView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
// The waterfall should render by default, and we want to make
// sure that the render events don't bleed between detail views
// so test that's the case after both views have been created.
let callTreeRendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield callTreeRendered;
let waterfallSelected = once(DetailsView, EVENTS.UI_DETAILS_VIEW_SELECTED);
yield DetailsView.selectView("waterfall");
yield waterfallSelected;
once(JsCallTreeView, EVENTS.UI_WATERFALL_RENDERED).then(() =>
ok(false, "JsCallTreeView should not receive UI_WATERFALL_RENDERED event."));
yield startRecording(panel);
yield stopRecording(panel);
let callTreeRerendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield callTreeRerendered;
ok(true, "Test passed.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,63 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that when flame chart views scroll to change selection,
* other detail views are rerendered
*/
var HORIZONTAL_AXIS = 1;
var VERTICAL_AXIS = 2;
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, OverviewView, DetailsView, WaterfallView, JsCallTreeView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let waterfallRendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
let calltreeRendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
let flamegraphRendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
OverviewView.setTimeInterval({ startTime: 10, endTime: 20 });
DetailsView.selectView("waterfall");
yield waterfallRendered;
DetailsView.selectView("js-calltree");
yield calltreeRendered;
DetailsView.selectView("js-flamegraph");
yield flamegraphRendered;
waterfallRendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
calltreeRendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
let overviewRangeSelected = once(OverviewView, EVENTS.OVERVIEW_RANGE_SELECTED);
once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED).then(() =>
ok(false, "FlameGraphView should not rerender, but be handled via its graph widget"));
// Reset the range to full view, trigger a "selection" event as if
// our mouse has done this
scroll(JsFlameGraphView.graph, 200, HORIZONTAL_AXIS, 10);
DetailsView.selectView("waterfall");
yield waterfallRendered;
ok(true, "Waterfall rerendered by flame graph changing interval");
DetailsView.selectView("js-calltree");
yield calltreeRendered;
ok(true, "CallTree rerendered by flame graph changing interval");
yield teardown(panel);
finish();
}
// EventUtils just doesn't work!
function scroll(graph, wheel, axis, x, y = 1) {
x /= window.devicePixelRatio;
y /= window.devicePixelRatio;
graph._onMouseMove({ testX: x, testY: y });
graph._onMouseWheel({ testX: x, testY: y, axis, detail: wheel, axis,
HORIZONTAL_AXIS,
VERTICAL_AXIS
});
}

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

@ -1,49 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the call tree view renders content after recording.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, WaterfallView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
yield rendered;
ok(true, "JsCallTreeView rendered after recording is stopped.");
yield DetailsView.selectView("waterfall");
yield startRecording(panel);
yield busyWait(100);
let waterfallRenderedOnWF = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
let waterfallRenderedOnJS = once(JsCallTreeView, EVENTS.WATERFALL_RENDERED);
rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield stopRecording(panel);
// The waterfall should render by default, and we want to make
// sure that the render events don't bleed between detail views
// via bug 1173393, so test that's the case after both views have been
// created
waterfallRenderedOnJS.then(() =>
ok(false, "JsCallTreeView should not receive WATERFALL_RENDERED event"));
yield waterfallRenderedOnWF;
yield DetailsView.selectView("js-calltree");
yield rendered;
ok(true, "JsCallTreeView rendered again after recording completed a second time.");
yield teardown(panel);
finish();
}

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

@ -1,33 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the flamegraph view renders content after recording.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("js-flamegraph");
ok(DetailsView.isViewSelected(JsFlameGraphView), "The flamegraph is now selected.");
yield rendered;
ok(true, "JsFlameGraphView rendered after recording is stopped.");
yield startRecording(panel);
yield busyWait(100);
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
yield stopRecording(panel);
yield rendered;
ok(true, "JsFlameGraphView rendered again after recording completed a second time.");
yield teardown(panel);
finish();
}

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

@ -1,38 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the memory call tree view renders content after recording.
*/
function* spawnTest() {
let { panel } = yield initPerformance(ALLOCS_URL);
let { EVENTS, $$, PerformanceController, DetailsView, MemoryCallTreeView } = panel.panelWin;
// Enable memory to test.
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield waitUntil(() => PerformanceController.getCurrentRecording().getAllocations().sizes.length);
yield stopRecording(panel);
let rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
yield DetailsView.selectView("memory-calltree");
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
yield rendered;
ok(true, "MemoryCallTreeView rendered after recording is stopped.");
ok($$("#memory-calltree-view .call-tree-item").length, "there are several allocations rendered.");
yield startRecording(panel);
yield busyWait(100);
rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
yield stopRecording(panel);
yield rendered;
ok(true, "MemoryCallTreeView rendered again after recording completed a second time.");
yield teardown(panel);
finish();
}

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

@ -1,36 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the memory flamegraph view renders content after recording.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
// Enable memory to test.
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("memory-flamegraph");
ok(DetailsView.isViewSelected(MemoryFlameGraphView), "The flamegraph is now selected.");
yield rendered;
ok(true, "MemoryFlameGraphView rendered after recording is stopped.");
yield startRecording(panel);
yield busyWait(100);
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
yield stopRecording(panel);
yield rendered;
ok(true, "MemoryFlameGraphView rendered again after recording completed a second time.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,39 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the waterfall view renders content after recording.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, WaterfallView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel); // Already waits for EVENTS.UI_WATERFALL_RENDERED.
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
ok(true, "WaterfallView rendered after recording is stopped.");
yield startRecording(panel);
yield stopRecording(panel); // Already waits for EVENTS.UI_WATERFALL_RENDERED.
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is still selected in the details view.");
ok(true, "WaterfallView rendered again after recording completed a second time.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js call tree view renders content after recording.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
yield rendered;
ok(true, "JsCallTreeView rendered after recording is stopped.");
yield startRecording(panel);
yield stopRecording(panel, {
expectedViewClass: "JsCallTreeView",
expectedViewEvent: "UI_JS_CALL_TREE_RENDERED"
});
ok(true, "JsCallTreeView rendered again after recording completed a second time.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js flamegraph view renders content after recording.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
yield startRecording(panel);
yield stopRecording(panel);
let rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("js-flamegraph");
yield rendered;
ok(true, "JsFlameGraphView rendered after recording is stopped.");
yield startRecording(panel);
yield stopRecording(panel, {
expectedViewClass: "JsFlameGraphView",
expectedViewEvent: "UI_JS_FLAMEGRAPH_RENDERED"
});
ok(true, "JsFlameGraphView rendered again after recording completed a second time.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the memory call tree view renders content after recording.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, MemoryCallTreeView } = panel.panelWin;
// Enable allocations to test.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield stopRecording(panel);
let rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
yield DetailsView.selectView("memory-calltree");
yield rendered;
ok(true, "MemoryCallTreeView rendered after recording is stopped.");
yield startRecording(panel);
yield stopRecording(panel, {
expectedViewClass: "MemoryCallTreeView",
expectedViewEvent: "UI_MEMORY_CALL_TREE_RENDERED"
});
ok(true, "MemoryCallTreeView rendered again after recording completed a second time.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,44 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the memory call tree view renders content after recording.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, MemoryFlameGraphView } = panel.panelWin;
// Enable allocations to test.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
yield startRecording(panel);
yield stopRecording(panel);
let rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("memory-flamegraph");
yield rendered;
ok(true, "MemoryFlameGraphView rendered after recording is stopped.");
yield startRecording(panel);
yield stopRecording(panel, {
expectedViewClass: "MemoryFlameGraphView",
expectedViewEvent: "UI_MEMORY_FLAMEGRAPH_RENDERED"
});
ok(true, "MemoryFlameGraphView rendered again after recording completed a second time.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,33 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the waterfall view renders content after recording.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, DetailsView, WaterfallView } = panel.panelWin;
yield startRecording(panel);
yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length);
let rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield stopRecording(panel);
ok(DetailsView.isViewSelected(WaterfallView),
"The waterfall view is selected by default in the details view.");
yield rendered;
ok(true, "WaterfallView rendered after recording is stopped.");
yield startRecording(panel);
yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length);
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
yield stopRecording(panel);
yield rendered;
ok(true, "WaterfallView rendered again after recording completed a second time.");
yield teardown(panel);
finish();
}

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

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests if the sidebar is updated with "DOMContentLoaded" and "load" markers.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording, reload } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
add_task(function*() {
let { panel, target } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { PerformanceController } = panel.panelWin;
yield startRecording(panel);
yield reload(target);
yield waitUntil(() => {
// Wait until we get the necessary markers.
let markers = PerformanceController.getCurrentRecording().getMarkers();
if (!markers.some(m => m.name == "document::DOMContentLoaded") ||
!markers.some(m => m.name == "document::Load")) {
return false;
}
ok(markers.filter(m => m.name == "document::DOMContentLoaded").length == 1,
"There should only be one `DOMContentLoaded` marker.");
ok(markers.filter(m => m.name == "document::Load").length == 1,
"There should only be one `load` marker.");
return true;
});
yield stopRecording(panel);
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,88 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the call tree up/down events work for js calltree and memory calltree.
*/
const { ThreadNode } = require("devtools/client/performance/modules/logic/tree-model");
function* spawnTest() {
let focus = 0;
let focusEvent = () => focus++;
Services.prefs.setBoolPref(MEMORY_PREF, true);
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, $, DetailsView, OverviewView, JsCallTreeView, MemoryCallTreeView } = panel.panelWin;
yield DetailsView.selectView("js-calltree");
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
// Make a recording just so the performance tool is in the correct state
yield startRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
yield stopRecording(panel);
yield rendered;
// Mock the profile used so we can get a deterministic tree created
let threadNode = new ThreadNode(gProfile.threads[0], OverviewView.getTimeInterval());
JsCallTreeView._populateCallTree(threadNode);
JsCallTreeView.emit(EVENTS.JS_CALL_TREE_RENDERED);
JsCallTreeView.on("focus", focusEvent);
click(panel.panelWin, $("#js-calltree-view .call-tree-item"));
fireKey("VK_DOWN");
fireKey("VK_DOWN");
fireKey("VK_DOWN");
fireKey("VK_DOWN");
JsCallTreeView.off("focus", focusEvent);
is(focus, 4, "several focus events are fired for the js calltree.");
yield teardown(panel);
finish();
};
var gProfile = {
meta: { version: 2 },
threads: [{
samples: [{
time: 5,
frames: [
{ category: 8, location: "(root)" },
{ category: 8, location: "A (http://foo/bar/baz:12)" },
{ category: 16, location: "B (http://foo/bar/baz:34)" },
{ category: 32, location: "C (http://foo/bar/baz:56)" }
]
}, {
time: 5 + 1,
frames: [
{ category: 8, location: "(root)" },
{ category: 8, location: "A (http://foo/bar/baz:12)" },
{ category: 16, location: "B (http://foo/bar/baz:34)" },
{ category: 64, location: "D (http://foo/bar/baz:78)" }
]
}, {
time: 5 + 1 + 2,
frames: [
{ category: 8, location: "(root)" },
{ category: 8, location: "A (http://foo/bar/baz:12)" },
{ category: 16, location: "B (http://foo/bar/baz:34)" },
{ category: 64, location: "D (http://foo/bar/baz:78)" }
]
}, {
time: 5 + 1 + 2 + 7,
frames: [
{ category: 8, location: "(root)" },
{ category: 8, location: "A (http://foo/bar/baz:12)" },
{ category: 128, location: "E (http://foo/bar/baz:90)" },
{ category: 256, location: "F (http://foo/bar/baz:99)" }
]
}],
markers: []
}]
};
RecordingUtils.deflateProfile(gProfile);

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

@ -19,7 +19,7 @@ function* spawnTest() {
injectGCMarkers(PerformanceController, WaterfallView);
// Select everything
let rendered = WaterfallView.once(EVENTS.WATERFALL_RENDERED);
let rendered = WaterfallView.once(EVENTS.UI_WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
yield rendered;
@ -41,7 +41,7 @@ function* spawnTest() {
yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
ok(showAllocsButton, "GC buttons when allocations are enabled");
rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
EventUtils.sendMouseEvent({ type: "click" }, showAllocsButton);
yield rendered;
@ -49,7 +49,7 @@ function* spawnTest() {
within(OverviewView.getTimeInterval().endTime, targetMarker.start, EPSILON, "Correct end time range");
let duration = PerformanceController.getCurrentRecording().getDuration();
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: duration });
yield DetailsView.selectView("waterfall");
yield rendered;
@ -68,7 +68,7 @@ function* spawnTest() {
yield waitUntil(() => showAllocsButton = $("#waterfall-details .custom-button[type='show-allocations']"));
ok(showAllocsButton, "GC buttons when allocations are enabled");
rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
EventUtils.sendMouseEvent({ type: "click" }, showAllocsButton);
yield rendered;
@ -84,20 +84,20 @@ function* spawnTest() {
// Reselect the entire recording -- due to bug 1196945, the new recording
// won't reset the selection
duration = PerformanceController.getCurrentRecording().getDuration();
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: duration });
yield rendered;
Services.prefs.setBoolPref(ALLOCATIONS_PREF, false);
yield startRecording(panel);
rendered = once(WaterfallView, EVENTS.WATERFALL_RENDERED);
rendered = once(WaterfallView, EVENTS.UI_WATERFALL_RENDERED);
yield stopRecording(panel);
yield rendered;
injectGCMarkers(PerformanceController, WaterfallView);
// Select everything
rendered = WaterfallView.once(EVENTS.WATERFALL_RENDERED);
rendered = WaterfallView.once(EVENTS.UI_WATERFALL_RENDERED);
OverviewView.setTimeInterval({ startTime: 0, endTime: Number.MAX_VALUE });
yield rendered;

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

@ -1,46 +1,48 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the toolbox tab for performance is highlighted when recording,
* whether already loaded, or via console.profile with an unloaded performance tools.
*/
function* spawnTest() {
let { target, toolbox, console } = yield initConsole(SIMPLE_URL);
let front = toolbox.performance;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInTab, initConsoleInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { waitUntil } = require("devtools/client/performance/test/helpers/wait-utils");
add_task(function*() {
let { target, toolbox, console } = yield initConsoleInNewTab({
url: SIMPLE_URL,
win: window
});
let tab = toolbox.doc.getElementById("toolbox-tab-performance");
let profileStart = once(front, "recording-started");
console.profile("rust");
yield profileStart;
yield console.profile("rust");
yield waitUntil(() => tab.hasAttribute("highlighted"));
ok(tab.hasAttribute("highlighted"),
"performance tab is highlighted during recording from console.profile when unloaded");
"Performance tab is highlighted during recording from console.profile when unloaded.");
let profileEnd = once(front, "recording-stopped");
console.profileEnd("rust");
yield profileEnd;
yield console.profileEnd("rust");
yield waitUntil(() => !tab.hasAttribute("highlighted"));
ok(!tab.hasAttribute("highlighted"),
"performance tab is no longer highlighted when console.profile recording finishes");
"Performance tab is no longer highlighted when console.profile recording finishes.");
yield gDevTools.showToolbox(target, "performance");
let panel = yield toolbox.getCurrentPanel().open();
let { panelWin: { PerformanceController, RecordingsView }} = panel;
let { panel } = yield initPerformanceInTab({ tab: target.tab });
yield startRecording(panel);
ok(tab.hasAttribute("highlighted"),
"performance tab is highlighted during recording while in performance tool");
"Performance tab is highlighted during recording while in performance tool.");
yield stopRecording(panel);
ok(!tab.hasAttribute("highlighted"),
"performance tab is no longer highlighted when recording finishes");
"Performance tab is no longer highlighted when recording finishes.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,138 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that when setting recording features in the UI (like enabling framerate or memory),
* if the target does not support these features, then the target's support overrides
* the UI preferences when fetching configuration from a recording.
*/
const WAIT_TIME = 100;
var test = Task.async(function*() {
yield testMockMemory();
yield testMockMemoryAndTimeline();
finish();
});
// Test mock memory
function *testMockMemory () {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL, "performance", {
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
Services.prefs.setBoolPref(MEMORY_PREF, true);
Services.prefs.setBoolPref(FRAMERATE_PREF, true);
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
let { EVENTS, $, gFront, PerformanceController, PerformanceView, DetailsView, WaterfallView } = panel.panelWin;
yield startRecording(panel, { waitForOverview: false });
yield waitUntil(() => PerformanceController.getCurrentRecording().getTicks().length);
yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length);
yield stopRecording(panel, { waitForOverview: false });
ok(gFront.LEGACY_FRONT, "using legacy front");
let config = PerformanceController.getCurrentRecording().getConfiguration();
let {
markers, allocations, memory, ticks
} = PerformanceController.getCurrentRecording().getAllData();
ok(typeof config.bufferSize === "number", "sanity check, config options contains `bufferSize`.");
is(config.withMemory, false,
"Recording configuration set by target's support, not by UI prefs [No Memory Actor: withMemory]");
is(config.withAllocations, false,
"Recording configuration set by target's support, not by UI prefs [No Memory Actor: withAllocations]");
is(config.withMarkers, true,
"Recording configuration set by target's support, not by UI prefs [No Memory Actor: withMarkers]");
is(config.withTicks, true,
"Recording configuration set by target's support, not by UI prefs [No Memory Actor: withTicks]");
ok(markers.length > 0, "markers exist.");
ok(ticks.length > 0, "ticks exist.");
isEmptyArray(memory, "memory");
isEmptyArray(allocations.sites, "allocations.sites");
isEmptyArray(allocations.timestamps, "allocations.timestamps");
isEmptyArray(allocations.frames, "allocations.frames");
isEmptyArray(allocations.sizes, "allocations.sizes");
is(isVisible($("#overview-pane")), true,
"overview pane not hidden when server not supporting memory actors, yet UI prefs request them.");
is($("#select-waterfall-view").hidden, false,
"waterfall view button not hidden when memory mocked, and UI prefs enable them");
is($("#select-js-calltree-view").hidden, false,
"jscalltree view button not hidden when memory mocked, and UI prefs enable them");
is($("#select-js-flamegraph-view").hidden, false,
"jsflamegraph view button not hidden when memory mocked, and UI prefs enable them");
is($("#select-memory-calltree-view").hidden, true,
"memorycalltree view button hidden when memory mocked, and UI prefs enable them");
is($("#select-memory-flamegraph-view").hidden, true,
"memoryflamegraph view button hidden when memory mocked, and UI prefs enable them");
yield gFront.destroy();
yield teardown(panel);
}
// Test mock memory and timeline actor
function *testMockMemoryAndTimeline() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL, "performance", {
TEST_PERFORMANCE_LEGACY_FRONT: true,
TEST_MOCK_TIMELINE_ACTOR: true,
});
Services.prefs.setBoolPref(MEMORY_PREF, true);
Services.prefs.setBoolPref(FRAMERATE_PREF, true);
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
let { EVENTS, $, gFront, PerformanceController, PerformanceView, DetailsView, WaterfallView } = panel.panelWin;
yield startRecording(panel, { waitForOverview: false });
yield busyWait(WAIT_TIME);
yield stopRecording(panel, { waitForOverview: false });
let config = PerformanceController.getCurrentRecording().getConfiguration();
let {
markers, allocations, memory, ticks
} = PerformanceController.getCurrentRecording().getAllData();
ok(typeof config.bufferSize === "number", "sanity check, config options contains `bufferSize`.");
is(config.withMemory, false,
"Recording configuration set by target's support, not by UI prefs [No Memory/Timeline Actor: withMemory]");
is(config.withAllocations, false,
"Recording configuration set by target's support, not by UI prefs [No Memory/Timeline Actor: withAllocations]");
is(config.withMarkers, false,
"Recording configuration set by target's support, not by UI prefs [No Memory/Timeline Actor: withMarkers]");
is(config.withTicks, false,
"Recording configuration set by target's support, not by UI prefs [No Memory/Timeline Actor: withTicks]");
isEmptyArray(markers, "markers");
isEmptyArray(ticks, "ticks");
isEmptyArray(memory, "memory");
isEmptyArray(allocations.sites, "allocations.sites");
isEmptyArray(allocations.timestamps, "allocations.timestamps");
isEmptyArray(allocations.frames, "allocations.frames");
isEmptyArray(allocations.sizes, "allocations.sizes");
is(isVisible($("#overview-pane")), false,
"overview pane hidden when server not supporting memory/timeline actors, yet UI prefs request them.");
is($("#select-waterfall-view").hidden, true,
"waterfall view button hidden when memory/timeline mocked, and UI prefs enable them");
is($("#select-js-calltree-view").hidden, false,
"jscalltree view button not hidden when memory/timeline mocked, and UI prefs enable them");
is($("#select-js-flamegraph-view").hidden, false,
"jsflamegraph view button not hidden when memory/timeline mocked, and UI prefs enable them");
is($("#select-memory-calltree-view").hidden, true,
"memorycalltree view button hidden when memory/timeline mocked, and UI prefs enable them");
is($("#select-memory-flamegraph-view").hidden, true,
"memoryflamegraph view button hidden when memory/timeline mocked, and UI prefs enable them");
yield gFront.destroy();
yield teardown(panel);
}
function isEmptyArray (array, name) {
ok(Array.isArray(array), `${name} is an array`);
is(array.length, 0, `${name} is empty`);
}

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

@ -1,90 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that the recording model is populated correctly when using timeline
* and memory actor mocks, and the correct views are shown.
*/
const WAIT_TIME = 1000;
var test = Task.async(function*() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL, "performance", {
TEST_MOCK_TIMELINE_ACTOR: true,
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
Services.prefs.setBoolPref(MEMORY_PREF, true);
let { EVENTS, $, gFront: front, PerformanceController, PerformanceView, DetailsView, JsCallTreeView } = panel.panelWin;
ok(front.LEGACY_FRONT, true, "Using legacy front");
is(front.traits.features.withMarkers, false, "traits.features.withMarkers is false.");
is(front.traits.features.withTicks, false, "traits.features.withTicks is false.");
is(front.traits.features.withMemory, false, "traits.features.withMemory is false.");
is(front.traits.features.withAllocations, false, "traits.features.withAllocations is false.");
yield startRecording(panel, { waitForOverview: false });
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
yield stopRecording(panel, { waitForOverview: false });
let {
label, duration, markers, frames, memory, ticks, allocations, profile
} = PerformanceController.getCurrentRecording().getAllData();
is(label, "", "Empty label for mock.");
is(typeof duration, "number", "duration is a number");
ok(duration > 0, "duration is not 0");
isEmptyArray(markers, "markers");
isEmptyArray(frames, "frames");
isEmptyArray(memory, "memory");
isEmptyArray(ticks, "ticks");
isEmptyArray(allocations.sites, "allocations.sites");
isEmptyArray(allocations.timestamps, "allocations.timestamps");
isEmptyArray(allocations.frames, "allocations.frames");
isEmptyArray(allocations.sizes, "allocations.sizes");
let sampleCount = 0;
for (let thread of profile.threads) {
info("Checking thread: " + thread.name);
for (let sample of thread.samples.data) {
sampleCount++;
let stack = getInflatedStackLocations(thread, sample);
if (stack[0] != "(root)") {
ok(false, "The sample " + stack.toSource() + " doesn't have a root node.");
}
}
}
ok(sampleCount > 0,
"At least some samples have been iterated over, checking for root nodes.");
is(isVisible($("#overview-pane")), false,
"overview pane hidden when timeline mocked.");
is($("#select-waterfall-view").hidden, true,
"waterfall view button hidden when timeline mocked");
is($("#select-js-calltree-view").hidden, false,
"jscalltree view button not hidden when timeline/memory mocked");
is($("#select-js-flamegraph-view").hidden, false,
"jsflamegraph view button not hidden when timeline mocked");
is($("#select-memory-calltree-view").hidden, true,
"memorycalltree view button hidden when memory mocked");
is($("#select-memory-flamegraph-view").hidden, true,
"memoryflamegraph view button hidden when memory mocked");
ok(DetailsView.isViewSelected(JsCallTreeView),
"JS Call Tree view selected by default when timeline/memory mocked.");
yield teardown(panel);
finish();
});
function isEmptyArray (array, name) {
ok(Array.isArray(array), `${name} is an array`);
is(array.length, 0, `${name} is empty`);
}

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

@ -1,32 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that recording notices does not display any buffer
* status on servers that do not support buffer statuses.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL, void 0, {
TEST_PERFORMANCE_LEGACY_FRONT: true,
TEST_PROFILER_FILTER_STATUS: ["position", "totalSize", "generation"]
});
let { gFront: front, EVENTS, $, PerformanceController, PerformanceView } = panel.panelWin;
front.setProfilerStatusInterval(10);
yield startRecording(panel);
front.on("profiler-status", () => ok(false, "profiler-status should not be emitted when not supported"));
yield busyWait(100);
ok(!$("#details-pane-container").getAttribute("buffer-status"),
"container does not have [buffer-status] attribute when not supported");
yield busyWait(100);
ok(!$("#details-pane-container").getAttribute("buffer-status"),
"container does not have [buffer-status] attribute when not supported");
yield stopRecording(panel);
yield teardown(panel);
finish();
}

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

@ -1,85 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that the recording model is populated correctly when using timeline
* and memory actor mocks, and that the correct button/overview displays are shown.
*/
const WAIT_TIME = 1000;
var test = Task.async(function*() {
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL, "performance", {
TEST_PERFORMANCE_LEGACY_FRONT: true
});
Services.prefs.setBoolPref(MEMORY_PREF, true);
let { EVENTS, $, gFront: front, PerformanceController, PerformanceView, DetailsView, WaterfallView } = panel.panelWin;
ok(front.LEGACY_FRONT, true, "Using legacy front");
is(front.traits.features.withMarkers, true, "traits.features.withMarkers is true.");
is(front.traits.features.withTicks, true, "traits.features.withTicks is true.");
is(front.traits.features.withMemory, false, "traits.features.withMemory is false.");
is(front.traits.features.withAllocations, false, "traits.features.withAllocations is false.");
yield startRecording(panel);
yield busyWait(100);
yield waitUntil(() => PerformanceController.getCurrentRecording().getTicks().length);
yield waitUntil(() => PerformanceController.getCurrentRecording().getMarkers().length);
yield stopRecording(panel);
let {
label, duration, allocations, profile
} = PerformanceController.getCurrentRecording().getAllData();
is(label, "", "Empty label for mock.");
is(typeof duration, "number", "duration is a number");
ok(duration > 0, "duration is not 0");
isEmptyArray(allocations.sites, "allocations.sites");
isEmptyArray(allocations.timestamps, "allocations.timestamps");
isEmptyArray(allocations.frames, "allocations.frames");
isEmptyArray(allocations.sizes, "allocations.sizes");
let sampleCount = 0;
for (let thread of profile.threads) {
info("Checking thread: " + thread.name);
for (let sample of thread.samples.data) {
sampleCount++;
let stack = getInflatedStackLocations(thread, sample);
if (stack[0] != "(root)") {
ok(false, "The sample " + stack.toSource() + " doesn't have a root node.");
}
}
}
ok(sampleCount > 0,
"At least some samples have been iterated over, checking for root nodes.");
is($("#overview-pane").hidden, false,
"overview pane not hidden when only memory mocked.");
is($("#select-waterfall-view").hidden, false,
"waterfall view button not hidden when memory mocked");
is($("#select-js-calltree-view").hidden, false,
"jscalltree view button not hidden when memory mocked");
is($("#select-js-flamegraph-view").hidden, false,
"jsflamegraph view button not hidden when memory mocked");
is($("#select-memory-calltree-view").hidden, true,
"memorycalltree view button hidden when memory mocked");
is($("#select-memory-flamegraph-view").hidden, true,
"memoryflamegraph view button hidden when memory mocked");
ok(DetailsView.isViewSelected(WaterfallView),
"Waterfall view selected by default when memory mocked.");
yield teardown(panel);
finish();
});
function isEmptyArray (array, name) {
ok(Array.isArray(array), `${name} is an array`);
is(array.length, 0, `${name} is empty`);
}

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

@ -1,78 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that when using an older server (< Fx40) where the profiler actor does not
* have the `filterable` trait, the samples are filtered by time on the client, rather
* than the more performant platform code.
*/
const WAIT_TIME = 1000; // ms
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL, void 0, {
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
let { gFront: front, gTarget: target } = panel.panelWin;
// Explicitly override the profiler's trait `filterable`
front._profiler.traits.filterable = false;
// Ugly, but we need to also not send the startTime to the server
// so we don't filter it both on the server and client
let request = target.client.request;
target.client.request = (data, res) => {
// Copy so we don't destructively change the request object, as we use
// the startTime on this object for filtering in the callback
let newData = merge({}, data, { startTime: void 0 });
return request.call(target.client, newData, res);
};
// Perform the first recording...
let firstRecording = yield front.startRecording();
let firstRecordingStartTime = firstRecording._profilerStartTime;
info("Started profiling at: " + firstRecordingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample some cpu activity
yield front.stopRecording(firstRecording);
info("The first recording is " + firstRecording.getDuration() + "ms long.");
ok(firstRecording.getDuration() >= WAIT_TIME,
"The first recording duration is correct.");
// Perform the second recording...
let secondRecording = yield front.startRecording();
let secondRecordingStartTime = secondRecording._profilerStartTime;
info("Started profiling at: " + secondRecordingStartTime);
busyWait(WAIT_TIME); // allow the profiler module to sample more cpu activity
yield front.stopRecording(secondRecording);
info("The second recording is " + secondRecording.getDuration() + "ms long.");
let secondRecordingProfile = secondRecording.getProfile();
let secondRecordingSamples = secondRecordingProfile.threads[0].samples.data;
isnot(secondRecording._profilerStartTime, 0,
"The profiling start time should not be 0 on the second recording.");
ok(secondRecording.getDuration() >= WAIT_TIME,
"The second recording duration is correct.");
const TIME_SLOT = secondRecordingProfile.threads[0].samples.schema.time;
info("Second profile's first sample time: " + secondRecordingSamples[0][TIME_SLOT]);
ok(secondRecordingSamples[0][TIME_SLOT] < secondRecordingStartTime,
"The second recorded sample times were normalized.");
ok(secondRecordingSamples[0][TIME_SLOT] > 0,
"The second recorded sample times were normalized correctly.");
ok(!secondRecordingSamples.find(e => e[TIME_SLOT] + secondRecordingStartTime <= firstRecording.getDuration()),
"There should be no samples from the first recording in the second one, " +
"even though the total number of frames did not overflow.");
target.client.request = request;
yield teardown(panel);
finish();
}

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

@ -1,48 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the profiler is populated by in-progress console recordings
* when it is opened with the legacy front.
*/
var WAIT_TIME = 10;
function* spawnTest() {
let { target, toolbox, console } = yield initConsole(SIMPLE_URL, { TEST_PERFORMANCE_LEGACY_FRONT: true });
let front = toolbox.performance;
let profileStart = once(front, "recording-started");
console.profile("rust");
yield profileStart;
profileStart = once(front, "recording-started");
console.profile("rust2");
yield profileStart;
yield gDevTools.showToolbox(target, "performance");
let panel = yield toolbox.getCurrentPanel().open();
let { panelWin: { PerformanceController, RecordingsView }} = panel;
yield waitUntil(() => PerformanceController.getRecordings().length === 2);
let recordings = PerformanceController.getRecordings();
is(recordings.length, 2, "two recordings found in the performance panel.");
is(recordings[0].isConsole(), true, "recording came from console.profile (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[1].isConsole(), true, "recording came from console.profile (2).");
is(recordings[1].getLabel(), "rust2", "correct label in the recording model (2).");
is(recordings[1].isRecording(), true, "recording is still recording (2).");
is(RecordingsView.selectedItem.attachment, recordings[0],
"The first console recording should be selected.");
let profileEnd = once(front, "recording-stopped");
console.profileEnd("rust");
yield profileEnd;
profileEnd = once(front, "recording-stopped");
console.profileEnd("rust2");
yield profileEnd;
yield teardown(panel);
finish();
}

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

@ -1,84 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test basic functionality of PerformanceFront with mock memory and timeline actors.
*/
var WAIT_TIME = 100;
const { LegacyPerformanceFront } = require("devtools/client/performance/legacy/front");
function* spawnTest() {
let tab = yield getTab(SIMPLE_URL);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
merge(target, {
TEST_MOCK_TIMELINE_ACTOR: true,
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
let front = new LegacyPerformanceFront(target);
yield front.connect();
ok(front.LEGACY_FRONT, true, "Using legacy front");
front.on("timeline-data", () => ok(false, "There should not be any timeline-data events when mocked"));
let recording = yield front.startRecording({
withTicks: true,
withMarkers: true,
withMemory: true,
withAllocations: true,
});
is(recording.getConfiguration().withMarkers, false, "overrides withMarkers based off of actor support");
is(recording.getConfiguration().withTicks, false, "overrides withTicks based off of actor support");
is(recording.getConfiguration().withMemory, false, "overrides withMemory based off of actor support");
is(recording.getConfiguration().withAllocations, false, "overrides withAllocations based off of actor support");
yield busyWait(WAIT_TIME);
yield front.stopRecording(recording);
ok(typeof recording.getDuration() === "number",
"The front.stopRecording() allows recording to get a duration.");
ok(recording.getDuration() >= 0, "duration is a positive number");
isEmptyArray(recording.getMarkers(), "markers");
isEmptyArray(recording.getTicks(), "ticks");
isEmptyArray(recording.getMemory(), "memory");
isEmptyArray(recording.getAllocations().sites, "allocations.sites");
isEmptyArray(recording.getAllocations().timestamps, "allocations.timestamps");
isEmptyArray(recording.getAllocations().frames, "allocations.frames");
ok(recording.getProfile().threads[0].samples.data.length, "profile data has some samples");
checkSystemInfo(recording, "Host");
checkSystemInfo(recording, "Client");
yield front.destroy();
gBrowser.removeCurrentTab();
}
function isEmptyArray (array, name) {
ok(Array.isArray(array), `${name} is an array`);
ok(array.length === 0, `${name} is empty`);
}
function getTab (url) {
let tab = gBrowser.selectedTab = gBrowser.addTab();
let loaded = once(gBrowser.selectedBrowser, "load", true);
content.location = url;
return loaded.then(() => {
return new Promise(resolve => {
let isBlank = url == "about:blank";
waitForFocus(() => resolve(tab), content, isBlank);
});
});
}
function checkSystemInfo (recording, type) {
let data = recording[`get${type}SystemInfo`]();
for (let field of ["appid", "apptype", "vendor", "name", "version"]) {
ok(data[field], `get${type}SystemInfo() has ${field} property`);
}
}

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

@ -1,75 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test basic functionality of PerformanceFront without a mock Timeline actor.
*/
var WAIT_TIME = 100;
const { LegacyPerformanceFront } = require("devtools/client/performance/legacy/front");
function* spawnTest() {
let tab = yield getTab(SIMPLE_URL);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
merge(target, {
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
let front = new LegacyPerformanceFront(target);
yield front.connect();
ok(front.LEGACY_FRONT, true, "Using legacy front");
let recording = yield front.startRecording({
withTicks: true,
withMarkers: true,
withMemory: true,
withAllocations: true,
});
is(recording.getConfiguration().withMarkers, true, "allows withMarkers based off of actor support");
is(recording.getConfiguration().withTicks, true, "allows withTicks based off of actor support");
is(recording.getConfiguration().withMemory, false, "overrides withMemory based off of actor support");
is(recording.getConfiguration().withAllocations, false, "overrides withAllocations based off of actor support");
yield waitUntil(() => recording.getMarkers().length);
yield waitUntil(() => recording.getTicks().length);
yield front.stopRecording(recording);
ok(recording.getMarkers().length, "we have several markers");
ok(recording.getTicks().length, "we have several ticks");
ok(typeof recording.getDuration() === "number",
"The front.stopRecording() allows recording to get a duration.");
ok(recording.getDuration() >= 0, "duration is a positive number");
isEmptyArray(recording.getMemory(), "memory");
isEmptyArray(recording.getAllocations().sites, "allocations.sites");
isEmptyArray(recording.getAllocations().timestamps, "allocations.timestamps");
isEmptyArray(recording.getAllocations().frames, "allocations.frames");
ok(recording.getProfile().threads[0].samples.data.length, "profile data has some samples");
yield front.destroy();
gBrowser.removeCurrentTab();
}
function isEmptyArray (array, name) {
ok(Array.isArray(array), `${name} is an array`);
ok(array.length === 0, `${name} is empty`);
}
function getTab (url) {
let tab = gBrowser.selectedTab = gBrowser.addTab();
let loaded = once(gBrowser.selectedBrowser, "load", true);
content.location = url;
return loaded.then(() => {
return new Promise(resolve => {
let isBlank = url == "about:blank";
waitForFocus(() => resolve(tab), content, isBlank);
});
});
}

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

@ -1,48 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that when using an older server (< Fx40) where the profiler actor does not
* have the `getBufferInfo` method that nothing breaks and RecordingModels have null
* `getBufferUsage()` values.
*/
const { LegacyPerformanceFront } = require("devtools/client/performance/legacy/front");
function* spawnTest() {
let tab = yield getTab(SIMPLE_URL);
let target = TargetFactory.forTab(tab);
yield target.makeRemote();
merge(target, {
TEST_PROFILER_FILTER_STATUS: ["position", "totalSize", "generation"],
TEST_PERFORMANCE_LEGACY_FRONT: true,
});
let front = new LegacyPerformanceFront(target);
yield front.connect();
front.setProfilerStatusInterval(10);
front.on("profiler-status", () => ok(false, "profiler-status should not be called when not supported"));
let model = yield front.startRecording();
yield busyWait(100);
is(front.getBufferUsageForRecording(model), null, "buffer usage for recording should be null");
yield front.stopRecording(model);
yield front.destroy();
gBrowser.removeCurrentTab();
}
function getTab (url) {
let tab = gBrowser.selectedTab = gBrowser.addTab();
let loaded = once(gBrowser.selectedBrowser, "load", true);
content.location = url;
return loaded.then(() => {
return new Promise(resolve => {
let isBlank = url == "about:blank";
waitForFocus(() => resolve(tab), content, isBlank);
});
});
}

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

@ -1,52 +1,51 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the recordings view shows the right label while recording, after
* recording, and once the record has loaded.
*/
var test = Task.async(function*() {
// This test seems to take a long time to cleanup.
requestLongerTimeout(2);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
let { target, panel, toolbox } = yield initPerformance(SIMPLE_URL);
let { RecordingsView, PerformanceController, PerformanceView,
EVENTS, $, L10N } = panel.panelWin;
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, L10N, $, PerformanceController, RecordingsView } = panel.panelWin;
info("Start to record");
yield startRecording(panel);
let durationNode = $(".recording-item-duration",
RecordingsView.selectedItem.target);
is(durationNode.getAttribute("value"),
let durationLabel = $(".recording-item-duration", RecordingsView.selectedItem.target);
is(durationLabel.getAttribute("value"),
L10N.getStr("recordingsList.recordingLabel"),
"The duration node should show the 'recording' message while recording");
info("Stop the recording and wait for the WILL_STOP and STOPPED events");
let recordingStopping = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopping" }
});
let recordingStopped = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopped" }
});
let everythingStopped = stopRecording(panel);
let willStop = PerformanceController.once(EVENTS.RECORDING_WILL_STOP);
let hasStopped = PerformanceController.once(EVENTS.RECORDING_STOPPED);
let stoppingRecording = PerformanceController.stopRecording();
yield willStop;
is(durationNode.getAttribute("value"),
yield recordingStopping;
is(durationLabel.getAttribute("value"),
L10N.getStr("recordingsList.loadingLabel"),
"The duration node should show the 'loading' message while stopping");
yield hasStopped;
yield stoppingRecording;
ok(PerformanceController.getCurrentRecording().isCompleted(), "recording should be completed");
let duration = RecordingsView.selectedItem.attachment.getDuration().toFixed(0);
is(durationNode.getAttribute("value"),
L10N.getFormatStr("recordingsList.durationLabel", duration),
yield recordingStopped;
is(durationLabel.getAttribute("value"),
L10N.getFormatStr("recordingsList.durationLabel",
RecordingsView.selectedItem.attachment.getDuration().toFixed(0)),
"The duration node should show the duration after the record has stopped");
yield PerformanceController.clearRecordings();
yield teardown(panel);
finish();
yield everythingStopped;
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,7 +1,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
"use strict";
/**
* Tests that the details view is locked after recording has stopped and before
@ -10,68 +9,73 @@ requestLongerTimeout(2);
* stopped isn't the active one.
*/
var test = Task.async(function*() {
// This test seems to take a long time to cleanup.
requestLongerTimeout(2);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
let { panel } = yield initPerformance(SIMPLE_URL);
let { PerformanceController, PerformanceView, RecordingsView,
EVENTS, $ } = panel.panelWin;
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, $, PerformanceController, RecordingsView } = panel.panelWin;
let detailsContainer = $("#details-pane-container");
let recordingNotice = $("#recording-notice");
let loadingNotice = $("#loading-notice");
let detailsPane = $("#details-pane");
info("Start to record");
yield startRecording(panel);
is(detailsContainer.selectedPanel, recordingNotice,
"The recording-notice is shown while recording");
"The recording-notice is shown while recording.");
info("Stop the recording and wait for the WILL_STOP and STOPPED events");
let willStop = PerformanceController.once(EVENTS.RECORDING_WILL_STOP);
let hasStopped = PerformanceController.once(EVENTS.RECORDING_STOPPED);
let stoppingRecording = PerformanceController.stopRecording();
yield willStop;
let recordingStopping = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopping" }
});
let recordingStopped = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopped" }
});
let everythingStopped = stopRecording(panel);
yield recordingStopping;
is(detailsContainer.selectedPanel, loadingNotice,
"The loading-notice is shown while the record is stopping");
yield hasStopped;
yield stoppingRecording;
"The loading-notice is shown while the record is stopping.");
yield recordingStopped;
is(detailsContainer.selectedPanel, detailsPane,
"The details panel is shown after the record has stopped");
"The details panel is shown after the record has stopped.");
info("Start to record again");
yield everythingStopped;
yield startRecording(panel);
info("While the 2nd record is still going, switch to the first one");
let select = once(PerformanceController, EVENTS.RECORDING_SELECTED);
info("While the 2nd record is still going, switch to the first one.");
let recordingSelected = once(PerformanceController, EVENTS.RECORDING_SELECTED);
RecordingsView.selectedIndex = 0;
yield select;
yield recordingSelected;
info("Stop the 2nd recording and wait for the WILL_STOP and STOPPED events");
willStop = PerformanceController.once(EVENTS.RECORDING_WILL_STOP);
hasStopped = PerformanceController.once(EVENTS.RECORDING_STOPPED);
stoppingRecording = PerformanceController.stopRecording();
recordingStopping = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopping" }
});
recordingStopped = once(PerformanceController, EVENTS.RECORDING_STATE_CHANGE, {
expectedArgs: { "1": "recording-stopped" }
});
everythingStopped = stopRecording(panel);
yield willStop;
yield recordingStopping;
is(detailsContainer.selectedPanel, detailsPane,
"The details panel is still shown while the 2nd record is being stopped.");
is(RecordingsView.selectedIndex, 0,
"The first record is still selected.");
yield recordingStopped;
is(detailsContainer.selectedPanel, detailsPane,
"The details panel is still shown while the 2nd record is being stopped");
is(RecordingsView.selectedIndex, 0, "The first record is still selected");
"The details panel is still shown after the 2nd record has stopped.");
is(RecordingsView.selectedIndex, 1,
"The second record is now selected.");
yield hasStopped;
yield stoppingRecording;
is(detailsContainer.selectedPanel, detailsPane,
"The details panel is still shown after the 2nd record has stopped");
is(RecordingsView.selectedIndex, 1, "The second record is now selected");
yield PerformanceController.clearRecordings();
yield teardown(panel);
finish();
yield everythingStopped;
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,68 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests if the sidebar is updated with "DOMContentLoaded" and "load" markers.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { PerformanceController } = panel.panelWin;
loadFrameScripts();
yield startRecording(panel);
ok(true, "Recording has started.");
evalInDebuggee("document.location.reload()");
yield waitUntil(() => {
// Wait until we get the necessary markers.
let markers = PerformanceController.getCurrentRecording().getMarkers();
if (!markers.some(m => m.name == "document::DOMContentLoaded") ||
!markers.some(m => m.name == "document::Load")) {
return false;
}
ok(markers.filter(m => m.name == "document::DOMContentLoaded").length == 1,
"There should only be one `DOMContentLoaded` marker.");
ok(markers.filter(m => m.name == "document::Load").length == 1,
"There should only be one `load` marker.");
return true;
});
yield stopRecording(panel);
ok(true, "Recording has ended.");
yield teardown(panel);
finish();
}
/**
* Takes a string `script` and evaluates it directly in the content
* in potentially a different process.
*/
function evalInDebuggee (script) {
let { generateUUID } = Cc['@mozilla.org/uuid-generator;1'].getService(Ci.nsIUUIDGenerator);
let deferred = Promise.defer();
if (!mm) {
throw new Error("`loadFrameScripts()` must be called when using MessageManager.");
}
let id = generateUUID().toString();
mm.sendAsyncMessage("devtools:test:eval", { script: script, id: id });
mm.addMessageListener("devtools:test:eval:response", handler);
function handler ({ data }) {
if (id !== data.id) {
return;
}
mm.removeMessageListener("devtools:test:eval:response", handler);
deferred.resolve(data.value);
}
return deferred.promise;
}

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

@ -1,16 +1,25 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that toggling preferences before there are any recordings does not throw.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { DetailsView, JsCallTreeView } = panel.panelWin;
yield DetailsView.selectView("js-calltree");
// Manually call the _onPrefChanged function so we can catch an error
// Manually call the _onPrefChanged function so we can catch an error.
try {
JsCallTreeView._onPrefChanged(null, "invert-call-tree", true);
ok(true, "Toggling preferences before there are any recordings should not fail.");
@ -18,6 +27,5 @@ function* spawnTest() {
ok(false, "Toggling preferences before there are any recordings should not fail.");
}
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that toggling preferences during a recording does not throw.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { DetailsView, JsCallTreeView } = panel.panelWin;
yield DetailsView.selectView("js-calltree");
yield startRecording(panel);
// Manually call the _onPrefChanged function so we can catch an error.
try {
JsCallTreeView._onPrefChanged(null, "invert-call-tree", true);
ok(true, "Toggling preferences during a recording should not fail.");
} catch (e) {
ok(false, "Toggling preferences during a recording should not fail.");
}
yield stopRecording(panel, {
expectedViewClass: "JsCallTreeView",
expectedViewEvent: "UI_JS_CALL_TREE_RENDERED"
});
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,27 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that toggling preferences during a recording does not throw.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
yield DetailsView.selectView("js-calltree");
yield startRecording(panel);
// Manually call the _onPrefChanged function so we can catch an error
try {
JsCallTreeView._onPrefChanged(null, "invert-call-tree", true);
ok(true, "Toggling preferences during a recording should not fail.");
} catch (e) {
ok(false, "Toggling preferences during a recording should not fail.");
}
yield stopRecording(panel);
yield teardown(panel);
finish();
}

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

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that toggling meta option prefs change visibility of other options.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_EXPERIMENTAL_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
add_task(function*() {
Services.prefs.setBoolPref(UI_EXPERIMENTAL_PREF, false);
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $ } = panel.panelWin;
let $body = $(".theme-body");
let $menu = $("#performance-options-menupopup");
ok(!$body.classList.contains("experimental-enabled"),
"The body node does not have `experimental-enabled` on start.");
ok(!$menu.classList.contains("experimental-enabled"),
"The menu popup does not have `experimental-enabled` on start.");
Services.prefs.setBoolPref(UI_EXPERIMENTAL_PREF, true);
ok($body.classList.contains("experimental-enabled"),
"The body node has `experimental-enabled` after toggle.");
ok($menu.classList.contains("experimental-enabled"),
"The menu popup has `experimental-enabled` after toggle.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,27 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that toggling meta option prefs change visibility of other options.
*/
Services.prefs.setBoolPref(EXPERIMENTAL_PREF, false);
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { $, EVENTS, PerformanceController } = panel.panelWin;
let $body = $(".theme-body");
let $menu = $("#performance-options-menupopup");
ok(!$body.classList.contains("experimental-enabled"), "body does not have `experimental-enabled` on start");
ok(!$menu.classList.contains("experimental-enabled"), "menu does not have `experimental-enabled` on start");
Services.prefs.setBoolPref(EXPERIMENTAL_PREF, true);
ok($body.classList.contains("experimental-enabled"), "body has `experimental-enabled` after toggle");
ok($menu.classList.contains("experimental-enabled"), "menu has `experimental-enabled` after toggle");
yield teardown(panel);
finish();
}

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

@ -1,33 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that setting the `devtools.performance.memory.` prefs propagate to the memory actor.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, $, gFront } = panel.panelWin;
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
let originalProbability = Services.prefs.getCharPref(MEMORY_SAMPLE_PROB_PREF);
let originalLogLength = Services.prefs.getIntPref(MEMORY_MAX_LOG_LEN_PREF);
Services.prefs.setCharPref(MEMORY_SAMPLE_PROB_PREF, "0.213");
Services.prefs.setIntPref(MEMORY_MAX_LOG_LEN_PREF, 777777);
yield startRecording(panel);
let { probability, maxLogLength } = yield gFront.getConfiguration();
yield stopRecording(panel);
is(probability, 0.213, "allocations probability option is set on memory actor");
is(maxLogLength, 777777, "allocations max log length option is set on memory actor");
Services.prefs.setBoolPref(ALLOCATIONS_PREF, false);
Services.prefs.setCharPref(MEMORY_SAMPLE_PROB_PREF, originalProbability);
Services.prefs.setIntPref(MEMORY_MAX_LOG_LEN_PREF, originalLogLength);
yield teardown(panel);
finish();
}

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

@ -0,0 +1,52 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that `enable-framerate` toggles the visibility of the fps graph,
* as well as enabling ticks data on the PerformanceFront.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_FRAMERATE_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { isVisible } = require("devtools/client/performance/test/helpers/dom-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $, PerformanceController } = panel.panelWin;
// Disable framerate to test.
Services.prefs.setBoolPref(UI_ENABLE_FRAMERATE_PREF, false);
yield startRecording(panel);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, false,
"PerformanceFront started without ticks recording.");
ok(!isVisible($("#time-framerate")),
"The fps graph is hidden when ticks disabled.");
// Re-enable framerate.
Services.prefs.setBoolPref(UI_ENABLE_FRAMERATE_PREF, true);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, false,
"PerformanceFront still marked without ticks recording.");
ok(!isVisible($("#time-framerate")),
"The fps graph is still hidden if recording does not contain ticks.");
yield startRecording(panel);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, true,
"PerformanceFront started with ticks recording.");
ok(isVisible($("#time-framerate")),
"The fps graph is not hidden when ticks enabled before recording.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that toggling `enable-memory` during a recording doesn't change that
* recording's state and does not break.
*/
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_FRAMERATE_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $, PerformanceController } = panel.panelWin;
// Test starting without framerate, and stopping with it.
Services.prefs.setBoolPref(UI_ENABLE_FRAMERATE_PREF, false);
yield startRecording(panel);
Services.prefs.setBoolPref(UI_ENABLE_FRAMERATE_PREF, true);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, false,
"The recording finished without tracking framerate.");
// Test starting with framerate, and stopping without it.
yield startRecording(panel);
Services.prefs.setBoolPref(UI_ENABLE_FRAMERATE_PREF, false);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, true,
"The recording finished with tracking framerate.");
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,34 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
requestLongerTimeout(2);
/**
* Tests that `enable-framerate` toggles the visibility of the fps graph,
* as well as enabling ticks data on the PerformanceFront.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, $ } = panel.panelWin;
Services.prefs.setBoolPref(FRAMERATE_PREF, false);
yield startRecording(panel);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, false,
"PerformanceFront started without ticks recording.");
ok(!isVisible($("#time-framerate")), "fps graph is hidden when ticks disabled");
Services.prefs.setBoolPref(FRAMERATE_PREF, true);
ok(!isVisible($("#time-framerate")), "fps graph is still hidden if recording does not contain ticks.");
yield startRecording(panel);
yield stopRecording(panel);
ok(isVisible($("#time-framerate")), "fps graph is not hidden when ticks enabled before recording");
is(PerformanceController.getCurrentRecording().getConfiguration().withTicks, true,
"PerformanceFront started with ticks recording.");
yield teardown(panel);
finish();
}

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

@ -1,15 +1,28 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that `enable-memory` toggles the visibility of the memory graph,
* as well as enabling memory data on the PerformanceFront.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, $ } = panel.panelWin;
Services.prefs.setBoolPref(MEMORY_PREF, false);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_MEMORY_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { isVisible } = require("devtools/client/performance/test/helpers/dom-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $, PerformanceController } = panel.panelWin;
// Disable memory to test.
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, false);
yield startRecording(panel);
yield stopRecording(panel);
@ -18,21 +31,28 @@ function* spawnTest() {
"PerformanceFront started without memory recording.");
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
"PerformanceFront started without allocations recording.");
ok(!isVisible($("#memory-overview")), "memory graph is hidden when memory disabled");
ok(!isVisible($("#memory-overview")),
"The memory graph is hidden when memory disabled.");
Services.prefs.setBoolPref(MEMORY_PREF, true);
// Re-enable memory.
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true);
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, false,
"PerformanceFront still marked without memory recording.");
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
"PerformanceFront still marked without allocations recording.");
ok(!isVisible($("#memory-overview")),
"memory graph is still hidden after enabling if recording did not start recording memory");
yield startRecording(panel);
yield stopRecording(panel);
ok(isVisible($("#memory-overview")), "memory graph is not hidden when memory enabled before recording");
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, true,
"PerformanceFront started with memory recording.");
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
"PerformanceFront did not record with allocations.");
ok(isVisible($("#memory-overview")),
"The memory graph is not hidden when memory enabled before recording.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,19 +1,30 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that toggling `enable-memory` during a recording doesn't change that
* recording's state and does not break.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
let { EVENTS, PerformanceController, $ } = panel.panelWin;
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_MEMORY_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { $, PerformanceController } = panel.panelWin;
// Test starting without memory, and stopping with it.
Services.prefs.setBoolPref(MEMORY_PREF, false);
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, false);
yield startRecording(panel);
Services.prefs.setBoolPref(MEMORY_PREF, true);
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, true);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, false,
@ -23,7 +34,8 @@ function* spawnTest() {
// Test starting with memory, and stopping without it.
yield startRecording(panel);
Services.prefs.setBoolPref(MEMORY_PREF, false);
Services.prefs.setBoolPref(UI_ENABLE_MEMORY_PREF, false);
yield stopRecording(panel);
is(PerformanceController.getCurrentRecording().getConfiguration().withMemory, true,
@ -31,6 +43,5 @@ function* spawnTest() {
is(PerformanceController.getCurrentRecording().getConfiguration().withAllocations, false,
"The recording still is not recording allocations.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,20 +1,31 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js flamegraphs get rerendered when toggling `flatten-tree-recursion`
* Tests that the js flamegraphs get rerendered when toggling `flatten-tree-recursion`.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_FLATTEN_RECURSION_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, PerformanceController, DetailsView, JsFlameGraphView, FlameGraphUtils } = panel.panelWin;
Services.prefs.setBoolPref(FLATTEN_PREF, true);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, true);
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
let rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("js-flamegraph");
yield rendered;
@ -26,10 +37,9 @@ function* spawnTest() {
ok(rendering1,
"The rendering data was cached.");
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(FLATTEN_PREF, false);
rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, false);
yield rendered;
ok(true, "JsFlameGraphView rerendered when toggling flatten-tree-recursion.");
let thread2 = PerformanceController.getCurrentRecording().getProfile().threads[0];
@ -40,10 +50,9 @@ function* spawnTest() {
isnot(rendering1, rendering2,
"The rendering data should be different because other options were used (1).");
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(FLATTEN_PREF, true);
rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, true);
yield rendered;
ok(true, "JsFlameGraphView rerendered when toggling back flatten-tree-recursion.");
let thread3 = PerformanceController.getCurrentRecording().getProfile().threads[0];
@ -54,6 +63,5 @@ function* spawnTest() {
isnot(rendering2, rendering3,
"The rendering data should be different because other options were used (2).");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,22 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the memory flamegraphs get rerendered when toggling `flatten-tree-recursion`
* Tests that the memory flamegraphs get rerendered when toggling `flatten-tree-recursion`.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_FLATTEN_RECURSION_PREF, UI_ENABLE_ALLOCATIONS_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, PerformanceController, DetailsView, MemoryFlameGraphView, RecordingUtils, FlameGraphUtils } = panel.panelWin;
// Enable memory to test
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
Services.prefs.setBoolPref(FLATTEN_PREF, true);
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, true);
yield startRecording(panel);
yield busyWait(100);
let rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
yield stopRecording(panel);
let rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("memory-flamegraph");
yield rendered;
@ -31,10 +42,9 @@ function* spawnTest() {
ok(rendering1,
"The rendering data was cached.");
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(FLATTEN_PREF, false);
rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, false);
yield rendered;
ok(true, "MemoryFlameGraphView rerendered when toggling flatten-tree-recursion.");
let allocations2 = PerformanceController.getCurrentRecording().getAllocations();
@ -48,10 +58,9 @@ function* spawnTest() {
isnot(rendering1, rendering2,
"The rendering data should be different because other options were used (1).");
rendered = once(MemoryFlameGraphView, EVENTS.MEMORY_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(FLATTEN_PREF, true);
rendered = once(MemoryFlameGraphView, EVENTS.UI_MEMORY_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_FLATTEN_RECURSION_PREF, true);
yield rendered;
ok(true, "MemoryFlameGraphView rerendered when toggling back flatten-tree-recursion.");
let allocations3 = PerformanceController.getCurrentRecording().getAllocations();
@ -65,6 +74,5 @@ function* spawnTest() {
isnot(rendering2, rendering3,
"The rendering data should be different because other options were used (2).");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,36 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js call tree views get rerendered when toggling `invert-call-tree`
* Tests that the js call tree views get rerendered when toggling `invert-call-tree`.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_INVERT_CALL_TREE_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, JsCallTreeView } = panel.panelWin;
Services.prefs.setBoolPref(INVERT_PREF, true);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, true);
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
let rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
yield DetailsView.selectView("js-calltree");
ok(DetailsView.isViewSelected(JsCallTreeView), "The call tree is now selected.");
yield rendered;
rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(INVERT_PREF, false);
rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, false);
yield rendered;
ok(true, "JsCallTreeView rerendered when toggling invert-call-tree.");
rendered = once(JsCallTreeView, EVENTS.JS_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(INVERT_PREF, true);
rendered = once(JsCallTreeView, EVENTS.UI_JS_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, true);
yield rendered;
ok(true, "JsCallTreeView rerendered when toggling back invert-call-tree.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,38 +1,45 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the memory call tree views get rerendered when toggling `invert-call-tree`
* Tests that the memory call tree views get rerendered when toggling `invert-call-tree`.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_ENABLE_ALLOCATIONS_PREF, UI_INVERT_CALL_TREE_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, MemoryCallTreeView } = panel.panelWin;
// Enable memory to test
Services.prefs.setBoolPref(ALLOCATIONS_PREF, true);
Services.prefs.setBoolPref(INVERT_PREF, true);
// Enable allocations to test.
Services.prefs.setBoolPref(UI_ENABLE_ALLOCATIONS_PREF, true);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, true);
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
let rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
yield DetailsView.selectView("memory-calltree");
ok(DetailsView.isViewSelected(MemoryCallTreeView), "The call tree is now selected.");
yield rendered;
rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(INVERT_PREF, false);
rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, false);
yield rendered;
ok(true, "MemoryCallTreeView rerendered when toggling invert-call-tree.");
rendered = once(MemoryCallTreeView, EVENTS.MEMORY_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(INVERT_PREF, true);
rendered = once(MemoryCallTreeView, EVENTS.UI_MEMORY_CALL_TREE_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_CALL_TREE_PREF, true);
yield rendered;
ok(true, "MemoryCallTreeView rerendered when toggling back invert-call-tree.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

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

@ -1,35 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/**
* Tests that the js Flamegraphs gets rerendered when toggling `invert-flame-graph`
* Tests that the js flamegraphs views get rerendered when toggling `invert-flame-graph`.
*/
function* spawnTest() {
let { panel } = yield initPerformance(SIMPLE_URL);
const { SIMPLE_URL } = require("devtools/client/performance/test/helpers/urls");
const { UI_INVERT_FLAME_PREF } = require("devtools/client/performance/test/helpers/prefs");
const { initPerformanceInNewTab, teardownToolboxAndRemoveTab } = require("devtools/client/performance/test/helpers/panel-utils");
const { startRecording, stopRecording } = require("devtools/client/performance/test/helpers/actions");
const { once } = require("devtools/client/performance/test/helpers/event-utils");
add_task(function*() {
let { panel } = yield initPerformanceInNewTab({
url: SIMPLE_URL,
win: window
});
let { EVENTS, DetailsView, JsFlameGraphView } = panel.panelWin;
Services.prefs.setBoolPref(INVERT_FLAME_PREF, true);
Services.prefs.setBoolPref(UI_INVERT_FLAME_PREF, true);
yield startRecording(panel);
yield busyWait(100);
yield stopRecording(panel);
let rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
let rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
yield DetailsView.selectView("js-flamegraph");
yield rendered;
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(INVERT_FLAME_PREF, false);
rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_FLAME_PREF, false);
yield rendered;
ok(true, "JsFlameGraphView rerendered when toggling invert-call-tree.");
ok(true, "JsFlameGraphView rerendered when toggling invert-flame-graph.");
rendered = once(JsFlameGraphView, EVENTS.JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(INVERT_FLAME_PREF, true);
rendered = once(JsFlameGraphView, EVENTS.UI_JS_FLAMEGRAPH_RENDERED);
Services.prefs.setBoolPref(UI_INVERT_FLAME_PREF, true);
yield rendered;
ok(true, "JsFlameGraphView rerendered when toggling back invert-call-tree.");
ok(true, "JsFlameGraphView rerendered when toggling back invert-flame-graph.");
yield teardown(panel);
finish();
}
yield teardownToolboxAndRemoveTab(panel);
});

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше