summaryrefslogtreecommitdiff
path: root/toolkit/devtools/timeline/test/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/devtools/timeline/test/head.js')
-rw-r--r--toolkit/devtools/timeline/test/head.js148
1 files changed, 148 insertions, 0 deletions
diff --git a/toolkit/devtools/timeline/test/head.js b/toolkit/devtools/timeline/test/head.js
new file mode 100644
index 000000000..74b185aa3
--- /dev/null
+++ b/toolkit/devtools/timeline/test/head.js
@@ -0,0 +1,148 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
+
+let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
+
+// Disable logging for all the tests. Both the debugger server and frontend will
+// be affected by this pref.
+let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
+Services.prefs.setBoolPref("devtools.debugger.log", false);
+
+// Enable the tool while testing.
+let gToolEnabled = Services.prefs.getBoolPref("devtools.timeline.enabled");
+Services.prefs.setBoolPref("devtools.timeline.enabled", true);
+
+let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
+let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
+let { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
+let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
+let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
+
+let TargetFactory = devtools.TargetFactory;
+let Toolbox = devtools.Toolbox;
+
+const EXAMPLE_URL = "http://example.com/browser/browser/devtools/timeline/test/";
+const SIMPLE_URL = EXAMPLE_URL + "doc_simple-test.html";
+
+// All tests are asynchronous.
+waitForExplicitFinish();
+
+registerCleanupFunction(() => {
+ info("finish() was called, cleaning up...");
+ Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
+ Services.prefs.setBoolPref("devtools.timeline.enabled", gToolEnabled);
+});
+
+// Close the toolbox and all opened tabs automatically.
+registerCleanupFunction(function*() {
+ let target = TargetFactory.forTab(gBrowser.selectedTab);
+ yield gDevTools.closeToolbox(target);
+
+ while (gBrowser.tabs.length > 1) {
+ gBrowser.removeCurrentTab();
+ }
+});
+
+function addTab(url) {
+ info("Adding tab: " + url);
+
+ let deferred = promise.defer();
+ let tab = gBrowser.selectedTab = gBrowser.addTab(url);
+ let linkedBrowser = tab.linkedBrowser;
+
+ linkedBrowser.addEventListener("load", function onLoad() {
+ linkedBrowser.removeEventListener("load", onLoad, true);
+ info("Tab added and finished loading: " + url);
+ deferred.resolve(tab);
+ }, true);
+
+ return deferred.promise;
+}
+
+/**
+ * Spawns a new tab and starts up a toolbox with the timeline panel
+ * automatically selected.
+ *
+ * Must be used within a task.
+ *
+ * @param string url
+ * The location of the new tab to spawn.
+ * @return object
+ * A promise resolved once the timeline is initialized, with the
+ * {target, panel} instances.
+ */
+function* initTimelinePanel(url) {
+ info("Initializing a timeline pane.");
+
+ let tab = yield addTab(url);
+ let target = TargetFactory.forTab(tab);
+
+ yield target.makeRemote();
+
+ let toolbox = yield gDevTools.showToolbox(target, "timeline");
+ let panel = toolbox.getCurrentPanel();
+ return { target, panel };
+}
+
+/**
+ * Waits until a predicate returns true.
+ *
+ * @param function predicate
+ * Invoked once in a while until it returns true.
+ * @param number interval [optional]
+ * How often the predicate is invoked, in milliseconds.
+ */
+function waitUntil(predicate, interval = 10) {
+ if (predicate()) {
+ return promise.resolve(true);
+ }
+ let deferred = promise.defer();
+ setTimeout(function() {
+ waitUntil(predicate).then(() => deferred.resolve(true));
+ }, interval);
+ return deferred.promise;
+
+}
+
+/**
+ * Wait until next tick.
+ */
+function nextTick() {
+ let def = promise.defer();
+ executeSoon(() => def.resolve())
+ return def.promise;
+}
+
+/**
+ * Wait for eventName on target.
+ * @param {Object} target An observable object that either supports on/off or
+ * addEventListener/removeEventListener
+ * @param {String} eventName
+ * @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
+ * @return A promise that resolves when the event has been handled
+ */
+function once(target, eventName, useCapture=false) {
+ info("Waiting for event: '" + eventName + "' on " + target + ".");
+
+ let deferred = promise.defer();
+
+ for (let [add, remove] of [
+ ["addEventListener", "removeEventListener"],
+ ["addListener", "removeListener"],
+ ["on", "off"]
+ ]) {
+ if ((add in target) && (remove in target)) {
+ target[add](eventName, function onEvent(...aArgs) {
+ info("Got event: '" + eventName + "' on " + target + ".");
+ target[remove](eventName, onEvent, useCapture);
+ deferred.resolve.apply(deferred, aArgs);
+ }, useCapture);
+ break;
+ }
+ }
+
+ return deferred.promise;
+}