summaryrefslogtreecommitdiff
path: root/browser/devtools/profiler/test
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2014-05-21 11:38:25 +0200
committerwolfbeast <mcwerewolf@gmail.com>2014-05-21 11:38:25 +0200
commitd25ba7d760b017b038e5aa6c0a605b4a330eb68d (patch)
tree16ec27edc7d5f83986f16236d3a36a2682a0f37e /browser/devtools/profiler/test
parenta942906574671868daf122284a9c4689e6924f74 (diff)
downloadpalemoon-gre-d25ba7d760b017b038e5aa6c0a605b4a330eb68d.tar.gz
Recommit working copy to repo with proper line endings.
Diffstat (limited to 'browser/devtools/profiler/test')
-rw-r--r--browser/devtools/profiler/test/Makefile.in39
-rw-r--r--browser/devtools/profiler/test/browser_profiler_bug_830664_multiple_profiles.js63
-rw-r--r--browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js38
-rw-r--r--browser/devtools/profiler/test/browser_profiler_bug_855244_multiple_tabs.js103
-rw-r--r--browser/devtools/profiler/test/browser_profiler_cmd.js154
-rw-r--r--browser/devtools/profiler/test/browser_profiler_console_api.js64
-rw-r--r--browser/devtools/profiler/test/browser_profiler_console_api_content.js56
-rw-r--r--browser/devtools/profiler/test/browser_profiler_console_api_mixed.js36
-rw-r--r--browser/devtools/profiler/test/browser_profiler_console_api_named.js66
-rw-r--r--browser/devtools/profiler/test/browser_profiler_controller.js64
-rw-r--r--browser/devtools/profiler/test/browser_profiler_profiles.js69
-rw-r--r--browser/devtools/profiler/test/browser_profiler_remote.js55
-rw-r--r--browser/devtools/profiler/test/browser_profiler_run.js66
-rw-r--r--browser/devtools/profiler/test/head.js119
-rw-r--r--browser/devtools/profiler/test/mock_console_api.html21
-rw-r--r--browser/devtools/profiler/test/mock_profiler_bug_834878_page.html14
-rw-r--r--browser/devtools/profiler/test/mock_profiler_bug_834878_script.js7
-rw-r--r--browser/devtools/profiler/test/moz.build6
18 files changed, 1040 insertions, 0 deletions
diff --git a/browser/devtools/profiler/test/Makefile.in b/browser/devtools/profiler/test/Makefile.in
new file mode 100644
index 000000000..398afe09a
--- /dev/null
+++ b/browser/devtools/profiler/test/Makefile.in
@@ -0,0 +1,39 @@
+# 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/.
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+# Disabled for intermittent failures.
+# browser_profiler_run.js \
+# browser_profiler_bug_855244_multiple_tabs.js \
+# browser_profiler_controller.js \
+# browser_profiler_bug_830664_multiple_profiles.js \
+# browser_profiler_console_api.js \
+# browser_profiler_console_api_named.js \
+# browser_profiler_console_api_mixed.js \
+# browser_profiler_console_api_content.js \
+
+MOCHITEST_BROWSER_TESTS = \
+ browser_profiler_profiles.js \
+ browser_profiler_remote.js \
+ browser_profiler_bug_834878_source_buttons.js \
+ browser_profiler_cmd.js \
+ head.js \
+ $(NULL)
+
+MOCHITEST_BROWSER_PAGES = \
+ mock_profiler_bug_834878_page.html \
+ mock_profiler_bug_834878_script.js \
+ mock_console_api.html \
+ $(NULL)
+
+MOCHITEST_BROWSER_FILES_PARTS = MOCHITEST_BROWSER_TESTS MOCHITEST_BROWSER_PAGES
+
+include $(topsrcdir)/config/rules.mk
diff --git a/browser/devtools/profiler/test/browser_profiler_bug_830664_multiple_profiles.js b/browser/devtools/profiler/test/browser_profiler_bug_830664_multiple_profiles.js
new file mode 100644
index 000000000..1acafd5c8
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_bug_830664_multiple_profiles.js
@@ -0,0 +1,63 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel, gUid;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, function onSetUp(tab, browser, panel) {
+ gTab = tab;
+ gPanel = panel;
+
+ gPanel.once("profileCreated", function (_, uid) {
+ gUid = uid;
+ let profile = gPanel.profiles.get(uid);
+
+ if (profile.isReady) {
+ startProfiling();
+ } else {
+ profile.once("ready", startProfiling);
+ }
+ });
+ gPanel.createProfile();
+ });
+}
+
+function startProfiling() {
+ gPanel.profiles.get(gPanel.activeProfile.uid).once("started", function () {
+ setTimeout(function () {
+ sendFromProfile(2, "start");
+ gPanel.profiles.get(2).once("started", function () setTimeout(stopProfiling, 50));
+ }, 50);
+ });
+
+ sendFromProfile(gPanel.activeProfile.uid, "start");
+}
+
+function stopProfiling() {
+ is(getSidebarItem(1).attachment.state, PROFILE_RUNNING);
+ is(getSidebarItem(2).attachment.state, PROFILE_RUNNING);
+
+ gPanel.profiles.get(gPanel.activeProfile.uid).once("stopped", function () {
+ is(getSidebarItem(1).attachment.state, PROFILE_COMPLETED);
+
+ sendFromProfile(2, "stop");
+ gPanel.profiles.get(2).once("stopped", confirmAndFinish);
+ });
+
+ sendFromProfile(gPanel.activeProfile.uid, "stop");
+}
+
+function confirmAndFinish(ev, data) {
+ is(getSidebarItem(1).attachment.state, PROFILE_COMPLETED);
+ is(getSidebarItem(2).attachment.state, PROFILE_COMPLETED);
+
+ tearDown(gTab, function onTearDown() {
+ gPanel = null;
+ gTab = null;
+ gUid = null;
+ });
+}
diff --git a/browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js b/browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js
new file mode 100644
index 000000000..3fdc40e95
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js
@@ -0,0 +1,38 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const BASE = "http://example.com/browser/browser/devtools/profiler/test/";
+const URL = BASE + "mock_profiler_bug_834878_page.html";
+const SCRIPT = BASE + "mock_profiler_bug_834878_script.js";
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, function onSetUp(tab, browser, panel) {
+ panel.once("profileCreated", function () {
+ let data = { uri: SCRIPT, line: 5, isChrome: false };
+
+ panel.displaySource(data, function onOpen() {
+ let target = TargetFactory.forTab(tab);
+ let dbg = gDevTools.getToolbox(target).getPanel("jsdebugger");
+ let view = dbg.panelWin.DebuggerView;
+
+ is(view.Sources.selectedValue, data.uri, "URI is different");
+ is(view.editor.getCaretPosition().line, data.line - 1,
+ "Line is different");
+
+ // Test the case where script is already loaded.
+ view.editor.setCaretPosition(1);
+ gDevTools.showToolbox(target, "jsprofiler").then(function () {
+ panel.displaySource(data, function onOpenAgain() {
+ is(view.editor.getCaretPosition().line, data.line - 1,
+ "Line is different");
+ tearDown(tab);
+ });
+ });
+ });
+ });
+
+ panel.createProfile();
+ });
+}
diff --git a/browser/devtools/profiler/test/browser_profiler_bug_855244_multiple_tabs.js b/browser/devtools/profiler/test/browser_profiler_bug_855244_multiple_tabs.js
new file mode 100644
index 000000000..74a831d0e
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_bug_855244_multiple_tabs.js
@@ -0,0 +1,103 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab1, gPanel1;
+let gTab2, gPanel2;
+
+// Tests that you can run the profiler in multiple tabs at the same
+// time and that closing the debugger panel in one tab doesn't lock
+// profilers in other tabs.
+
+registerCleanupFunction(function () {
+ gTab1 = gTab2 = gPanel1 = gPanel2 = null;
+});
+
+function test() {
+ waitForExplicitFinish();
+
+ openTwoTabs()
+ .then(startTwoProfiles)
+ .then(stopFirstProfile)
+ .then(stopSecondProfile)
+ .then(closeTabs)
+ .then(openTwoTabs)
+ .then(startTwoProfiles)
+ .then(closeFirstPanel)
+ .then(stopSecondProfile)
+ .then(closeTabs)
+ .then(finish);
+}
+
+function openTwoTabs() {
+ let deferred = Promise.defer();
+
+ setUp(URL, (tab, browser, panel) => {
+ gTab1 = tab;
+ gPanel1 = panel;
+
+ loadTab(URL, (tab, browser) => {
+ gTab2 = tab;
+ openProfiler(tab, () => {
+ let target = TargetFactory.forTab(tab);
+ gPanel2 = gDevTools.getToolbox(target).getPanel("jsprofiler");
+ deferred.resolve();
+ });
+ });
+ });
+
+ return deferred.promise;
+}
+
+function startTwoProfiles() {
+ let deferred = Promise.defer();
+ gPanel1.controller.start("Profile 1", (err) => {
+ ok(!err, "Profile in tab 1 started without errors");
+ gPanel2.controller.start("Profile 1", (err) => {
+ ok(!err, "Profile in tab 2 started without errors");
+ gPanel1.controller.isActive((err, isActive) => {
+ ok(isActive, "Profiler is active");
+ deferred.resolve();
+ });
+ });
+ });
+
+ return deferred.promise;
+}
+
+function stopFirstProfile() {
+ let deferred = Promise.defer();
+
+ gPanel1.controller.stop("Profile 1", (err, data) => {
+ ok(!err, "Profile in tab 1 stopped without errors");
+ ok(data, "Profile in tab 1 returned some data");
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+}
+
+function stopSecondProfile() {
+ let deferred = Promise.defer();
+
+ gPanel2.controller.stop("Profile 1", (err, data) => {
+ ok(!err, "Profile in tab 2 stopped without errors");
+ ok(data, "Profile in tab 2 returned some data");
+ deferred.resolve();
+ });
+
+ return deferred.promise;
+}
+
+function closeTabs() {
+ while (gBrowser.tabs.length > 1) {
+ gBrowser.removeCurrentTab();
+ }
+}
+
+function closeFirstPanel() {
+ let target = TargetFactory.forTab(gTab1);
+ let toolbox = gDevTools.getToolbox(target);
+ return toolbox.destroy;
+}
diff --git a/browser/devtools/profiler/test/browser_profiler_cmd.js b/browser/devtools/profiler/test/browser_profiler_cmd.js
new file mode 100644
index 000000000..321b01b48
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_cmd.js
@@ -0,0 +1,154 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gcli = Cu.import("resource://gre/modules/devtools/gcli.jsm", {}).gcli;
+let gTarget, gPanel, gOptions;
+
+function cmd(typed, expected="") {
+ helpers.audit(gOptions, [{
+ setup: typed,
+ exec: { output: expected }
+ }]);
+}
+
+function test() {
+ waitForExplicitFinish();
+
+ helpers.addTabWithToolbar(URL, function (options) {
+ gOptions = options;
+ gTarget = options.target;
+
+ return gDevTools.showToolbox(options.target, "jsprofiler")
+ .then(setupGlobals)
+ .then(testProfilerStart)
+ .then(testProfilerList)
+ .then(testProfilerStop)
+ .then(testProfilerClose)
+ .then(testProfilerCloseWhenClosed)
+ }).then(finishUp);
+}
+
+function setupGlobals() {
+ let deferred = Promise.defer();
+ gPanel = gDevTools.getToolbox(gTarget).getPanel("jsprofiler");
+ deferred.resolve();
+ return deferred.promise;
+}
+
+function testProfilerStart() {
+ let deferred = Promise.defer();
+
+ gPanel.once("started", function () {
+ is(gPanel.profiles.size, 2, "There are two profiles");
+ ok(!gPanel.getProfileByName("Profile 1").isStarted, "Profile 1 wasn't started");
+ ok(gPanel.getProfileByName("Profile 2").isStarted, "Profile 2 was started");
+ cmd('profiler start "Profile 2"', "This profile has already been started");
+ deferred.resolve();
+ });
+
+ cmd("profiler start", gcli.lookup("profilerStarting2"));
+ return deferred.promise;
+}
+
+function testProfilerList() {
+ let deferred = Promise.defer();
+
+ cmd("profiler list", /^.*Profile\s1.*Profile\s2\s\*.*$/);
+ deferred.resolve();
+
+ return deferred.promise;
+}
+
+function testProfilerStop() {
+ let deferred = Promise.defer();
+
+ gPanel.once("stopped", function () {
+ ok(!gPanel.getProfileByName("Profile 2").isStarted, "Profile 2 was stopped");
+ ok(gPanel.getProfileByName("Profile 2").isFinished, "Profile 2 was stopped");
+ cmd('profiler stop "Profile 2"', "This profile has already been completed. " +
+ "Use 'profile show' command to see its results");
+ cmd('profiler stop "Profile 1"', "This profile has not been started yet. " +
+ "Use 'profile start' to start profiling");
+ cmd('profiler stop "invalid"', "Profile not found")
+ deferred.resolve();
+ });
+
+ cmd('profiler stop "Profile 2"', gcli.lookup("profilerStopping2"));
+ return deferred.promise;
+}
+
+function testProfilerShow() {
+ let deferred = Promise.defer();
+
+ is(gPanel.getProfileByName("Profile 2").uid, gPanel.activeProfile.uid,
+ "Profile 2 is active");
+
+ gPanel.once("profileSwitched", function () {
+ is(gPanel.getProfileByName("Profile 1").uid, gPanel.activeProfile.uid,
+ "Profile 1 is active");
+ cmd('profile show "invalid"', "Profile not found");
+ deferred.resolve();
+ });
+
+ cmd('profile show "Profile 1"');
+ return deferred.promise;
+}
+
+function testProfilerClose() {
+ let deferred = Promise.defer();
+
+ helpers.audit(gOptions, [{
+ setup: "profiler close",
+ completed: false,
+ exec: { output: "" }
+ }]);
+
+ let toolbox = gDevTools.getToolbox(gOptions.target);
+ if (!toolbox) {
+ ok(true, "Profiler was closed.");
+ deferred.resolve();
+ } else {
+ toolbox.on("destroyed", function () {
+ ok(true, "Profiler was closed.");
+ deferred.resolve();
+ });
+ }
+
+ return deferred.promise;
+}
+
+function testProfilerCloseWhenClosed() {
+ // We need to call this test to make sure there are no
+ // errors when executing 'profiler close' on a closed
+ // toolbox. See bug 863636 for more info.
+
+ let deferred = Promise.defer();
+
+ helpers.audit(gOptions, [{
+ setup: "profiler close",
+ completed: false,
+ exec: { output: "" }
+ }]);
+
+ let toolbox = gDevTools.getToolbox(gOptions.target);
+ if (!toolbox) {
+ ok(true, "Profiler was closed.");
+ deferred.resolve();
+ } else {
+ toolbox.on("destroyed", function () {
+ ok(true, "Profiler was closed.");
+ deferred.resolve();
+ });
+ }
+
+ return deferred.promise;
+}
+
+function finishUp() {
+ gTarget = null;
+ gPanel = null;
+ gOptions = null;
+ finish();
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_console_api.js b/browser/devtools/profiler/test/browser_profiler_console_api.js
new file mode 100644
index 000000000..0b25c0142
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_console_api.js
@@ -0,0 +1,64 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, (tab, browser, panel) => {
+ gTab = tab;
+ gPanel = panel;
+
+ openConsole(tab, testConsoleProfile);
+ });
+}
+
+function testConsoleProfile(hud) {
+ hud.jsterm.clearOutput(true);
+
+ // Here we start two named profiles and then end one of them.
+ // profileEnd, when name is not provided, simply pops the latest
+ // profile.
+
+ let profilesStarted = 0;
+
+ function profileEnd(_, uid) {
+ let profile = gPanel.profiles.get(uid);
+
+ profile.once("started", () => {
+ if (++profilesStarted < 2)
+ return;
+
+ gPanel.off("profileCreated", profileEnd);
+ gPanel.profiles.get(3).once("stopped", () => {
+ openProfiler(gTab, checkProfiles);
+ });
+
+ hud.jsterm.execute("console.profileEnd()");
+ });
+ }
+
+ gPanel.on("profileCreated", profileEnd);
+ hud.jsterm.execute("console.profile()");
+ hud.jsterm.execute("console.profile()");
+}
+
+function checkProfiles(toolbox) {
+ let panel = toolbox.getPanel("jsprofiler");
+
+ is(getSidebarItem(1, panel).attachment.state, PROFILE_IDLE);
+ is(getSidebarItem(2, panel).attachment.state, PROFILE_RUNNING);
+ is(getSidebarItem(3, panel).attachment.state, PROFILE_COMPLETED);
+
+ // Make sure we can still stop profiles via the UI.
+
+ gPanel.profiles.get(2).once("stopped", () => {
+ is(getSidebarItem(2, panel).attachment.state, PROFILE_COMPLETED);
+ tearDown(gTab, () => gTab = gPanel = null);
+ });
+
+ sendFromProfile(2, "stop");
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_console_api_content.js b/browser/devtools/profiler/test/browser_profiler_console_api_content.js
new file mode 100644
index 000000000..67e0b1084
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_console_api_content.js
@@ -0,0 +1,56 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+const BASE = "http://example.com/browser/browser/devtools/profiler/test/";
+const PAGE = BASE + "mock_console_api.html";
+
+let gTab, gPanel, gToolbox;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, (tab, browser, panel) => {
+ gTab = tab;
+ gPanel = panel;
+
+ openProfiler(tab, (toolbox) => {
+ gToolbox = toolbox;
+ loadUrl(PAGE, tab, () => {
+ gPanel.sidebar.on("stateChanged", (_, item) => {
+ if (item.attachment.state !== PROFILE_COMPLETED)
+ return;
+
+ runTests();
+ });
+ });
+ });
+ });
+}
+
+function runTests() {
+ is(getSidebarItem(1).attachment.state, PROFILE_IDLE);
+ is(getSidebarItem(2).attachment.state, PROFILE_COMPLETED);
+
+ gPanel.once("parsed", () => {
+ function assertSampleAndFinish() {
+ let [win,doc] = getProfileInternals();
+ let sample = doc.getElementsByClassName("samplePercentage");
+
+ if (sample.length <= 0)
+ return void setTimeout(assertSampleAndFinish, 100);
+
+ ok(sample.length > 0, "We have Cleopatra UI displayed");
+ tearDown(gTab, () => {
+ gTab = null;
+ gPanel = null;
+ gToolbox = null;
+ });
+ }
+
+ assertSampleAndFinish();
+ });
+
+ let profile = gPanel.profiles.get(2);
+ gPanel.sidebar.selectedItem = gPanel.sidebar.getItemByProfile(profile);
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_console_api_mixed.js b/browser/devtools/profiler/test/browser_profiler_console_api_mixed.js
new file mode 100644
index 000000000..548050e88
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_console_api_mixed.js
@@ -0,0 +1,36 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, (tab, browser, panel) => {
+ gTab = tab;
+ gPanel = panel;
+
+ openProfiler(tab, runTests);
+ });
+}
+
+function runTests(toolbox) {
+ let panel = toolbox.getPanel("jsprofiler");
+
+ panel.profiles.get(1).once("started", () => {
+ is(getSidebarItem(1, panel).attachment.state, PROFILE_RUNNING);
+
+ openConsole(gTab, (hud) => {
+ panel.profiles.get(1).once("stopped", () => {
+ is(getSidebarItem(1, panel).attachment.state, PROFILE_COMPLETED);
+ tearDown(gTab, () => gTab = gPanel = null);
+ });
+
+ hud.jsterm.execute("console.profileEnd()");
+ });
+ });
+
+ sendFromProfile(1, "start");
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_console_api_named.js b/browser/devtools/profiler/test/browser_profiler_console_api_named.js
new file mode 100644
index 000000000..460676aa7
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_console_api_named.js
@@ -0,0 +1,66 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, (tab, browser, panel) => {
+ gTab = tab;
+ gPanel = panel;
+
+ openConsole(tab, testConsoleProfile);
+ });
+}
+
+function testConsoleProfile(hud) {
+ hud.jsterm.clearOutput(true);
+
+ // Here we start two named profiles and then end one of them.
+
+ let profilesStarted = 0;
+
+ function profileEnd(_, uid) {
+ let profile = gPanel.profiles.get(uid);
+
+ profile.once("started", () => {
+ if (++profilesStarted < 2)
+ return;
+
+ gPanel.off("profileCreated", profileEnd);
+ gPanel.profiles.get(2).once("stopped", () => {
+ openProfiler(gTab, checkProfiles);
+ });
+
+ hud.jsterm.execute("console.profileEnd('Second')");
+ });
+ }
+
+ gPanel.on("profileCreated", profileEnd);
+ hud.jsterm.execute("console.profile('Second')");
+ hud.jsterm.execute("console.profile('Third')");
+}
+
+function checkProfiles(toolbox) {
+ let panel = toolbox.getPanel("jsprofiler");
+
+ is(getSidebarItem(1, panel).attachment.state, PROFILE_IDLE);
+ is(getSidebarItem(2, panel).attachment.name, "Second");
+ is(getSidebarItem(2, panel).attachment.state, PROFILE_COMPLETED);
+ is(getSidebarItem(3, panel).attachment.name, "Third");
+ is(getSidebarItem(3, panel).attachment.state, PROFILE_RUNNING);
+
+ // Make sure we can still stop profiles via the queue pop.
+
+ gPanel.profiles.get(3).once("stopped", () => {
+ openProfiler(gTab, () => {
+ is(getSidebarItem(3, panel).attachment.state, PROFILE_COMPLETED);
+ tearDown(gTab, () => gTab = gPanel = null);
+ });
+ });
+
+ openConsole(gTab, (hud) => hud.jsterm.execute("console.profileEnd()"));
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_controller.js b/browser/devtools/profiler/test/browser_profiler_controller.js
new file mode 100644
index 000000000..8881f01bd
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_controller.js
@@ -0,0 +1,64 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, function onSetUp(tab, browser, panel) {
+ gTab = tab;
+ gPanel = panel;
+
+ testInactive(startFirstProfile);
+ });
+}
+
+function testInactive(next=function(){}) {
+ gPanel.controller.isActive(function (err, isActive) {
+ ok(!err, "isActive didn't return any errors");
+ ok(!isActive, "Profiler is not active");
+ next();
+ });
+}
+
+function testActive(next=function(){}) {
+ gPanel.controller.isActive(function (err, isActive) {
+ ok(!err, "isActive didn't return any errors");
+ ok(isActive, "Profiler is active");
+ next();
+ });
+}
+
+function startFirstProfile() {
+ gPanel.controller.start("Profile 1", function (err) {
+ ok(!err, "Profile 1 started without errors");
+ testActive(startSecondProfile);
+ });
+}
+
+function startSecondProfile() {
+ gPanel.controller.start("Profile 2", function (err) {
+ ok(!err, "Profile 2 started without errors");
+ testActive(stopFirstProfile);
+ });
+}
+
+function stopFirstProfile() {
+ gPanel.controller.stop("Profile 1", function (err, data) {
+ ok(!err, "Profile 1 stopped without errors");
+ ok(data, "Profiler returned some data");
+
+ testActive(stopSecondProfile);
+ });
+}
+
+function stopSecondProfile() {
+ gPanel.controller.stop("Profile 2", function (err, data) {
+ ok(!err, "Profile 2 stopped without errors");
+ ok(data, "Profiler returned some data");
+ testInactive(tearDown.call(null, gTab, function () gTab = gPanel = null));
+ });
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_profiles.js b/browser/devtools/profiler/test/browser_profiler_profiles.js
new file mode 100644
index 000000000..10f7b4bcb
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_profiles.js
@@ -0,0 +1,69 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, function onSetUp(tab, browser, panel) {
+ gTab = tab;
+ gPanel = panel;
+
+ panel.once("profileCreated", onProfileCreated);
+ panel.once("profileSwitched", onProfileSwitched);
+
+ testNewProfile();
+ });
+}
+
+function testNewProfile() {
+ is(gPanel.profiles.size, 1, "There is only one profile");
+
+ let btn = gPanel.document.getElementById("profiler-create");
+ ok(!btn.getAttribute("disabled"), "Create Profile button is not disabled");
+ btn.click();
+}
+
+function onProfileCreated(name, uid) {
+ is(gPanel.profiles.size, 2, "There are two profiles now");
+ ok(gPanel.activeProfile.uid !== uid, "New profile is not yet active");
+
+ let btn = gPanel.document.getElementById("profile-" + uid);
+ ok(btn, "Profile item has been added to the sidebar");
+ btn.click();
+}
+
+function onProfileSwitched(name, uid) {
+ gPanel.once("profileCreated", onNamedProfileCreated);
+ gPanel.once("profileSwitched", onNamedProfileSwitched);
+
+ ok(gPanel.activeProfile.uid === uid, "Switched to a new profile");
+ gPanel.createProfile("Custom Profile");
+}
+
+function onNamedProfileCreated(name, uid) {
+ is(gPanel.profiles.size, 3, "There are three profiles now");
+ is(gPanel.getProfileByUID(uid).name, "Custom Profile", "Name is correct");
+
+ let profile = gPanel.profiles.get(uid);
+ let data = gPanel.sidebar.getItemByProfile(profile).attachment;
+
+ is(data.uid, uid, "UID is correct");
+ is(data.name, "Custom Profile", "Name is correct on the label");
+
+ let btn = gPanel.document.getElementById("profile-" + uid);
+ ok(btn, "Profile item has been added to the sidebar");
+ btn.click();
+}
+
+function onNamedProfileSwitched(name, uid) {
+ ok(gPanel.activeProfile.uid === uid, "Switched to a new profile");
+
+ tearDown(gTab, function onTearDown() {
+ gPanel = null;
+ gTab = null;
+ });
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_remote.js b/browser/devtools/profiler/test/browser_profiler_remote.js
new file mode 100644
index 000000000..450f9d290
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_remote.js
@@ -0,0 +1,55 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let temp = {};
+
+Cu.import("resource://gre/modules/devtools/dbg-server.jsm", temp);
+let DebuggerServer = temp.DebuggerServer;
+
+Cu.import("resource://gre/modules/devtools/dbg-client.jsm", temp);
+let DebuggerClient = temp.DebuggerClient;
+let debuggerSocketConnect = temp.debuggerSocketConnect;
+
+Cu.import("resource:///modules/devtools/ProfilerController.jsm", temp);
+let ProfilerController = temp.ProfilerController;
+
+function test() {
+ waitForExplicitFinish();
+ Services.prefs.setBoolPref(REMOTE_ENABLED, true);
+
+ loadTab(URL, function onTabLoad(tab, browser) {
+ DebuggerServer.init(function () true);
+ DebuggerServer.addBrowserActors();
+ is(DebuggerServer._socketConnections, 0);
+
+ DebuggerServer.openListener(2929);
+ is(DebuggerServer._socketConnections, 1);
+
+ let transport = debuggerSocketConnect("127.0.0.1", 2929);
+ let client = new DebuggerClient(transport);
+ client.connect(function onClientConnect() {
+ let target = { isRemote: true, client: client };
+ let controller = new ProfilerController(target);
+
+ controller.connect(function onControllerConnect() {
+ // If this callback is called, this means listTabs call worked.
+ // Which means that the transport worked. Time to finish up this
+ // test.
+
+ function onShutdown() {
+ window.removeEventListener("Debugger:Shutdown", onShutdown, true);
+ transport = client = null;
+ finish();
+ }
+
+ window.addEventListener("Debugger:Shutdown", onShutdown, true);
+
+ client.close(function () {
+ gBrowser.removeTab(tab);
+ });
+ });
+ });
+ });
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/browser_profiler_run.js b/browser/devtools/profiler/test/browser_profiler_run.js
new file mode 100644
index 000000000..80e162ffb
--- /dev/null
+++ b/browser/devtools/profiler/test/browser_profiler_run.js
@@ -0,0 +1,66 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const URL = "data:text/html;charset=utf8,<p>JavaScript Profiler test</p>";
+
+let gTab, gPanel, gAttempts = 0;
+
+function test() {
+ waitForExplicitFinish();
+
+ setUp(URL, function onSetUp(tab, browser, panel) {
+ gTab = tab;
+ gPanel = panel;
+
+ panel.once("started", onStart);
+ panel.once("parsed", onParsed);
+
+ testUI();
+ });
+}
+
+function testUI() {
+ ok(gPanel, "Profiler panel exists");
+ ok(gPanel.activeProfile, "Active profile exists");
+
+ let [win, doc] = getProfileInternals();
+ let startButton = doc.querySelector(".controlPane #startWrapper button");
+ let stopButton = doc.querySelector(".controlPane #stopWrapper button");
+
+ ok(startButton, "Start button exists");
+ ok(stopButton, "Stop button exists");
+
+ startButton.click();
+}
+
+function onStart() {
+ gPanel.controller.isActive(function (err, isActive) {
+ ok(isActive, "Profiler is running");
+
+ let [win, doc] = getProfileInternals();
+ let stopButton = doc.querySelector(".controlPane #stopWrapper button");
+
+ setTimeout(function () stopButton.click(), 100);
+ });
+}
+
+function onParsed() {
+ function assertSample() {
+ let [win,doc] = getProfileInternals();
+ let sample = doc.getElementsByClassName("samplePercentage");
+
+ if (sample.length <= 0) {
+ return void setTimeout(assertSample, 100);
+ }
+
+ ok(sample.length > 0, "We have some items displayed");
+ is(sample[0].innerHTML, "100.0%", "First percentage is 100%");
+
+ tearDown(gTab, function onTearDown() {
+ gPanel = null;
+ gTab = null;
+ });
+ }
+
+ assertSample();
+}
diff --git a/browser/devtools/profiler/test/head.js b/browser/devtools/profiler/test/head.js
new file mode 100644
index 000000000..8833f57cf
--- /dev/null
+++ b/browser/devtools/profiler/test/head.js
@@ -0,0 +1,119 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+let temp = {};
+
+const PROFILER_ENABLED = "devtools.profiler.enabled";
+const REMOTE_ENABLED = "devtools.debugger.remote-enabled";
+const PROFILE_IDLE = 0;
+const PROFILE_RUNNING = 1;
+const PROFILE_COMPLETED = 2;
+
+Cu.import("resource:///modules/devtools/gDevTools.jsm", temp);
+let gDevTools = temp.gDevTools;
+
+Cu.import("resource://gre/modules/devtools/Loader.jsm", temp);
+let TargetFactory = temp.devtools.TargetFactory;
+
+Cu.import("resource://gre/modules/devtools/dbg-server.jsm", temp);
+let DebuggerServer = temp.DebuggerServer;
+
+Cu.import("resource:///modules/HUDService.jsm", temp);
+let HUDService = temp.HUDService;
+
+// Import the GCLI test helper
+let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
+Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
+
+registerCleanupFunction(function () {
+ helpers = null;
+ Services.prefs.clearUserPref(PROFILER_ENABLED);
+ Services.prefs.clearUserPref(REMOTE_ENABLED);
+ DebuggerServer.destroy();
+});
+
+function getProfileInternals(uid) {
+ let profile = (uid != null) ? gPanel.profiles.get(uid) : gPanel.activeProfile;
+ let win = profile.iframe.contentWindow;
+ let doc = win.document;
+
+ return [win, doc];
+}
+
+function getSidebarItem(uid, panel=gPanel) {
+ let profile = panel.profiles.get(uid);
+ return panel.sidebar.getItemByProfile(profile);
+}
+
+function sendFromProfile(uid, msg) {
+ let [win, doc] = getProfileInternals(uid);
+ win.parent.postMessage({ uid: uid, status: msg }, "*");
+}
+
+function loadTab(url, callback) {
+ let tab = gBrowser.addTab();
+ gBrowser.selectedTab = tab;
+ loadUrl(url, tab, callback);
+}
+
+function loadUrl(url, tab, callback) {
+ content.location.assign(url);
+ let browser = gBrowser.getBrowserForTab(tab);
+ if (browser.contentDocument.readyState === "complete") {
+ callback(tab, browser);
+ return;
+ }
+
+ let onLoad = function onLoad() {
+ browser.removeEventListener("load", onLoad, true);
+ callback(tab, browser);
+ };
+
+ browser.addEventListener("load", onLoad, true);
+}
+
+function openProfiler(tab, callback) {
+ let target = TargetFactory.forTab(tab);
+ gDevTools.showToolbox(target, "jsprofiler").then(callback);
+}
+
+function openConsole(tab, cb=function(){}) {
+ // This function was borrowed from webconsole/test/head.js
+ let target = TargetFactory.forTab(tab);
+
+ gDevTools.showToolbox(target, "webconsole").then(function (toolbox) {
+ let hud = toolbox.getCurrentPanel().hud;
+ hud.jsterm._lazyVariablesView = false;
+ cb(hud);
+ });
+}
+
+function closeProfiler(tab, callback) {
+ let target = TargetFactory.forTab(tab);
+ let toolbox = gDevTools.getToolbox(target);
+ toolbox.destroy().then(callback);
+}
+
+function setUp(url, callback=function(){}) {
+ Services.prefs.setBoolPref(PROFILER_ENABLED, true);
+
+ loadTab(url, function onTabLoad(tab, browser) {
+ openProfiler(tab, function onProfilerOpen() {
+ let target = TargetFactory.forTab(tab);
+ let panel = gDevTools.getToolbox(target).getPanel("jsprofiler");
+ callback(tab, browser, panel);
+ });
+ });
+}
+
+function tearDown(tab, callback=function(){}) {
+ closeProfiler(tab, function onProfilerClose() {
+ callback();
+
+ while (gBrowser.tabs.length > 1) {
+ gBrowser.removeCurrentTab();
+ }
+
+ finish();
+ });
+}
diff --git a/browser/devtools/profiler/test/mock_console_api.html b/browser/devtools/profiler/test/mock_console_api.html
new file mode 100644
index 000000000..2a626c9aa
--- /dev/null
+++ b/browser/devtools/profiler/test/mock_console_api.html
@@ -0,0 +1,21 @@
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset='utf-8'/>
+ <title>console.profile from content</title>
+ </head>
+
+ <body>
+ <script>
+ console.profile();
+ var a = new Array(500);
+ while (a.length) {
+ a.shift();
+ }
+ console.profileEnd();
+ </script>
+ </body>
+</html> \ No newline at end of file
diff --git a/browser/devtools/profiler/test/mock_profiler_bug_834878_page.html b/browser/devtools/profiler/test/mock_profiler_bug_834878_page.html
new file mode 100644
index 000000000..ad150b98a
--- /dev/null
+++ b/browser/devtools/profiler/test/mock_profiler_bug_834878_page.html
@@ -0,0 +1,14 @@
+<!-- Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset='utf-8'/>
+ <title>Profiler Script Linking Test</title>
+ <script type="text/javascript" src="mock_profiler_bug_834878_script.js">
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/browser/devtools/profiler/test/mock_profiler_bug_834878_script.js b/browser/devtools/profiler/test/mock_profiler_bug_834878_script.js
new file mode 100644
index 000000000..0ef5f3772
--- /dev/null
+++ b/browser/devtools/profiler/test/mock_profiler_bug_834878_script.js
@@ -0,0 +1,7 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function main() {
+ console.log("Hello, World!");
+ return 0;
+} \ No newline at end of file
diff --git a/browser/devtools/profiler/test/moz.build b/browser/devtools/profiler/test/moz.build
new file mode 100644
index 000000000..895d11993
--- /dev/null
+++ b/browser/devtools/profiler/test/moz.build
@@ -0,0 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+