diff options
Diffstat (limited to 'toolkit/devtools/timeline/test/head.js')
-rw-r--r-- | toolkit/devtools/timeline/test/head.js | 148 |
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; +} |