summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/browser/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/server/tests/browser/head.js')
-rw-r--r--devtools/server/tests/browser/head.js203
1 files changed, 203 insertions, 0 deletions
diff --git a/devtools/server/tests/browser/head.js b/devtools/server/tests/browser/head.js
new file mode 100644
index 000000000..1e7f09d95
--- /dev/null
+++ b/devtools/server/tests/browser/head.js
@@ -0,0 +1,203 @@
+/* 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/. */
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
+const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
+const {DebuggerClient} = require("devtools/shared/client/main");
+const {DebuggerServer} = require("devtools/server/main");
+const {defer} = require("promise");
+const DevToolsUtils = require("devtools/shared/DevToolsUtils");
+const Services = require("Services");
+
+const PATH = "browser/devtools/server/tests/browser/";
+const MAIN_DOMAIN = "http://test1.example.org/" + PATH;
+const ALT_DOMAIN = "http://sectest1.example.org/" + PATH;
+const ALT_DOMAIN_SECURED = "https://sectest1.example.org:443/" + PATH;
+
+// All tests are asynchronous.
+waitForExplicitFinish();
+
+/**
+ * Add a new test tab in the browser and load the given url.
+ * @param {String} url The url to be loaded in the new tab
+ * @return a promise that resolves to the new browser that the document
+ * is loaded in. Note that we cannot return the document
+ * directly, since this would be a CPOW in the e10s case,
+ * and Promises cannot be resolved with CPOWs (see bug 1233497).
+ */
+var addTab = Task.async(function* (url) {
+ info(`Adding a new tab with URL: ${url}`);
+ let tab = gBrowser.selectedTab = gBrowser.addTab(url);
+ yield BrowserTestUtils.browserLoaded(tab.linkedBrowser);
+
+ info(`Tab added and URL ${url} loaded`);
+
+ return tab.linkedBrowser;
+});
+
+function* initAnimationsFrontForUrl(url) {
+ const {AnimationsFront} = require("devtools/shared/fronts/animation");
+ const {InspectorFront} = require("devtools/shared/fronts/inspector");
+
+ yield addTab(url);
+
+ initDebuggerServer();
+ let client = new DebuggerClient(DebuggerServer.connectPipe());
+ let form = yield connectDebuggerClient(client);
+ let inspector = InspectorFront(client, form);
+ let walker = yield inspector.getWalker();
+ let animations = AnimationsFront(client, form);
+
+ return {inspector, walker, animations, client};
+}
+
+function initDebuggerServer() {
+ try {
+ // Sometimes debugger server does not get destroyed correctly by previous
+ // tests.
+ DebuggerServer.destroy();
+ } catch (e) {
+ info(`DebuggerServer destroy error: ${e}\n${e.stack}`);
+ }
+ DebuggerServer.init();
+ DebuggerServer.addBrowserActors();
+}
+
+/**
+ * Connect a debugger client.
+ * @param {DebuggerClient}
+ * @return {Promise} Resolves to the selected tabActor form when the client is
+ * connected.
+ */
+function connectDebuggerClient(client) {
+ return client.connect()
+ .then(() => client.listTabs())
+ .then(tabs => {
+ return tabs.tabs[tabs.selected];
+ });
+}
+
+/**
+ * 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 + ".");
+
+ return new Promise(resolve => {
+
+ 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);
+ resolve(...aArgs);
+ }, useCapture);
+ break;
+ }
+ }
+ });
+}
+
+/**
+ * Forces GC, CC and Shrinking GC to get rid of disconnected docshells and
+ * windows.
+ */
+function forceCollections() {
+ Cu.forceGC();
+ Cu.forceCC();
+ Cu.forceShrinkingGC();
+}
+
+/**
+ * Get a mock tabActor from a given window.
+ * This is sometimes useful to test actors or classes that use the tabActor in
+ * isolation.
+ * @param {DOMWindow} win
+ * @return {Object}
+ */
+function getMockTabActor(win) {
+ return {
+ window: win,
+ isRootActor: true
+ };
+}
+
+registerCleanupFunction(function tearDown() {
+ while (gBrowser.tabs.length > 1) {
+ gBrowser.removeCurrentTab();
+ }
+});
+
+function idleWait(time) {
+ return DevToolsUtils.waitForTime(time);
+}
+
+function busyWait(time) {
+ let start = Date.now();
+ let stack;
+ while (Date.now() - start < time) { stack = Components.stack; }
+}
+
+/**
+ * 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);
+ }
+ return new Promise(resolve => {
+ setTimeout(function () {
+ waitUntil(predicate).then(() => resolve(true));
+ }, interval);
+ });
+}
+
+function waitForMarkerType(front, types, predicate,
+ unpackFun = (name, data) => data.markers,
+ eventName = "timeline-data")
+{
+ types = [].concat(types);
+ predicate = predicate || function () { return true; };
+ let filteredMarkers = [];
+ let { promise, resolve } = defer();
+
+ info("Waiting for markers of type: " + types);
+
+ function handler(name, data) {
+ if (typeof name === "string" && name !== "markers") {
+ return;
+ }
+
+ let markers = unpackFun(name, data);
+ info("Got markers: " + JSON.stringify(markers, null, 2));
+
+ filteredMarkers = filteredMarkers.concat(markers.filter(m => types.indexOf(m.name) !== -1));
+
+ if (types.every(t => filteredMarkers.some(m => m.name === t)) && predicate(filteredMarkers)) {
+ front.off(eventName, handler);
+ resolve(filteredMarkers);
+ }
+ }
+ front.on(eventName, handler);
+
+ return promise;
+}