michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: "use strict"; michael@0: michael@0: const {classes: Cc, interfaces: Ci, utils: Cu} = Components; michael@0: michael@0: const XHTML_NS = "http://www.w3.org/1999/xhtml"; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; michael@0: let WebConsoleUtils = devtools.require("devtools/toolkit/webconsole/utils").Utils; michael@0: michael@0: let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"] michael@0: .getService(Ci.nsIConsoleAPIStorage); michael@0: michael@0: let {ConsoleServiceListener, ConsoleAPIListener} = michael@0: devtools.require("devtools/toolkit/webconsole/utils"); michael@0: michael@0: function initCommon() michael@0: { michael@0: //Services.prefs.setBoolPref("devtools.debugger.log", true); michael@0: michael@0: Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); michael@0: Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); michael@0: } michael@0: michael@0: function initDebuggerServer() michael@0: { michael@0: if (!DebuggerServer.initialized) { michael@0: DebuggerServer.init(); michael@0: DebuggerServer.addBrowserActors(); michael@0: } michael@0: } michael@0: michael@0: function connectToDebugger(aCallback) michael@0: { michael@0: initCommon(); michael@0: initDebuggerServer(); michael@0: michael@0: let transport = DebuggerServer.connectPipe(); michael@0: let client = new DebuggerClient(transport); michael@0: michael@0: let dbgState = { dbgClient: client }; michael@0: client.connect(aCallback.bind(null, dbgState)); michael@0: } michael@0: michael@0: function attachConsole(aListeners, aCallback, aAttachToTab) michael@0: { michael@0: function _onAttachConsole(aState, aResponse, aWebConsoleClient) michael@0: { michael@0: if (aResponse.error) { michael@0: Cu.reportError("attachConsole failed: " + aResponse.error + " " + michael@0: aResponse.message); michael@0: } michael@0: michael@0: aState.client = aWebConsoleClient; michael@0: michael@0: aCallback(aState, aResponse); michael@0: } michael@0: michael@0: connectToDebugger(function _onConnect(aState, aResponse) { michael@0: if (aResponse.error) { michael@0: Cu.reportError("client.connect() failed: " + aResponse.error + " " + michael@0: aResponse.message); michael@0: aCallback(aState, aResponse); michael@0: return; michael@0: } michael@0: michael@0: aState.dbgClient.listTabs(function _onListTabs(aResponse) { michael@0: if (aResponse.error) { michael@0: Cu.reportError("listTabs failed: " + aResponse.error + " " + michael@0: aResponse.message); michael@0: aCallback(aState, aResponse); michael@0: return; michael@0: } michael@0: let consoleActor = aAttachToTab ? michael@0: aResponse.tabs[aResponse.selected].consoleActor : michael@0: aResponse.consoleActor; michael@0: aState.actor = consoleActor; michael@0: aState.dbgClient.attachConsole(consoleActor, aListeners, michael@0: _onAttachConsole.bind(null, aState)); michael@0: }); michael@0: }); michael@0: } michael@0: michael@0: function closeDebugger(aState, aCallback) michael@0: { michael@0: aState.dbgClient.close(aCallback); michael@0: aState.dbgClient = null; michael@0: aState.client = null; michael@0: } michael@0: michael@0: function checkConsoleAPICall(aCall, aExpected) michael@0: { michael@0: if (aExpected.level != "trace" && aExpected.arguments) { michael@0: is(aCall.arguments.length, aExpected.arguments.length, michael@0: "number of arguments"); michael@0: } michael@0: michael@0: checkObject(aCall, aExpected); michael@0: } michael@0: michael@0: function checkObject(aObject, aExpected) michael@0: { michael@0: for (let name of Object.keys(aExpected)) michael@0: { michael@0: let expected = aExpected[name]; michael@0: let value = aObject[name]; michael@0: checkValue(name, value, expected); michael@0: } michael@0: } michael@0: michael@0: function checkValue(aName, aValue, aExpected) michael@0: { michael@0: if (aExpected === null) { michael@0: ok(!aValue, "'" + aName + "' is null"); michael@0: } michael@0: else if (aValue === undefined) { michael@0: ok(false, "'" + aName + "' is undefined"); michael@0: } michael@0: else if (typeof aExpected == "string" || typeof aExpected == "number" || michael@0: typeof aExpected == "boolean") { michael@0: is(aValue, aExpected, "property '" + aName + "'"); michael@0: } michael@0: else if (aExpected instanceof RegExp) { michael@0: ok(aExpected.test(aValue), aName + ": " + aExpected + " matched " + aValue); michael@0: } michael@0: else if (Array.isArray(aExpected)) { michael@0: info("checking array for property '" + aName + "'"); michael@0: checkObject(aValue, aExpected); michael@0: } michael@0: else if (typeof aExpected == "object") { michael@0: info("checking object for property '" + aName + "'"); michael@0: checkObject(aValue, aExpected); michael@0: } michael@0: } michael@0: michael@0: function checkHeadersOrCookies(aArray, aExpected) michael@0: { michael@0: let foundHeaders = {}; michael@0: michael@0: for (let elem of aArray) { michael@0: if (!(elem.name in aExpected)) { michael@0: continue; michael@0: } michael@0: foundHeaders[elem.name] = true; michael@0: info("checking value of header " + elem.name); michael@0: checkValue(elem.name, elem.value, aExpected[elem.name]); michael@0: } michael@0: michael@0: for (let header in aExpected) { michael@0: if (!(header in foundHeaders)) { michael@0: ok(false, header + " was not found"); michael@0: } michael@0: } michael@0: } michael@0: michael@0: var gTestState = {}; michael@0: michael@0: function runTests(aTests, aEndCallback) michael@0: { michael@0: function driver() michael@0: { michael@0: let lastResult, sendToNext; michael@0: for (let i = 0; i < aTests.length; i++) { michael@0: gTestState.index = i; michael@0: let fn = aTests[i]; michael@0: info("will run test #" + i + ": " + fn.name); michael@0: lastResult = fn(sendToNext, lastResult); michael@0: sendToNext = yield lastResult; michael@0: } michael@0: yield aEndCallback(sendToNext, lastResult); michael@0: } michael@0: gTestState.driver = driver(); michael@0: return gTestState.driver.next(); michael@0: } michael@0: michael@0: function nextTest(aMessage) michael@0: { michael@0: return gTestState.driver.send(aMessage); michael@0: }