☠☠ backed out by 3d2e44c2fd29 ☠ ☠ | |
author | Mihai Sucan <mihai.sucan@gmail.com> |
Wed, 26 Sep 2012 17:27:38 +0100 | |
changeset 108591 | 89ab8685729df08d361ffa99000fd13f74cbbc40 |
parent 108590 | 9c70da27ec28f740cc2ae2f60394b17141ab452e |
child 108592 | 3eb02ef25ea5a92bb3a85abdc6befc7d3f2d745f |
push id | 15595 |
push user | philringnalda@gmail.com |
push date | Sat, 29 Sep 2012 07:05:36 +0000 |
treeherder | mozilla-inbound@b56f7cb51b1f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | robcee |
bugs | 768096 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/devtools/webconsole/Makefile.in +++ b/toolkit/devtools/webconsole/Makefile.in @@ -4,14 +4,14 @@ DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -#TEST_DIRS += tests +TEST_DIRS += test include $(topsrcdir)/config/rules.mk libs:: $(INSTALL) $(IFLAGS1) $(srcdir)/*.jsm $(FINAL_TARGET)/modules/devtools
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/Makefile.in @@ -0,0 +1,28 @@ +# 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 + +# Mochitest tests +MOCHITEST_FILES = \ + test_basics.html \ + test_cached_messages.html \ + test_page_errors.html \ + test_consoleapi.html \ + test_jsterm.html \ + test_object_actor.html \ + test_network_get.html \ + test_network_post.html \ + network_requests_iframe.html \ + data.json \ + common.js \ + $(NULL) + +include $(topsrcdir)/config/rules.mk
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/common.js @@ -0,0 +1,128 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); + +const {classes: Cc, interfaces: Ci, utils: Cu} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); +Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); +Cu.import("resource://gre/modules/devtools/WebConsoleUtils.jsm"); + +function initCommon() +{ + // Always log packets when running tests. + Services.prefs.setBoolPref("devtools.debugger.log", true); +} + +function initDebuggerServer() +{ + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } +} + +function connectToDebugger(aCallback) +{ + initCommon(); + initDebuggerServer(); + + let transport = DebuggerServer.connectPipe(); + let client = new DebuggerClient(transport); + + let dbgState = { dbgClient: client }; + client.connect(aCallback.bind(null, dbgState)); +} + +function attachConsole(aListeners, aCallback) +{ + function _onAttachConsole(aState, aResponse, aWebConsoleClient) + { + if (aResponse.error) { + Cu.reportError("attachConsole failed: " + aResponse.error + " " + + aResponse.message); + } + + aState.client = aWebConsoleClient; + + aCallback(aState, aResponse); + } + + connectToDebugger(function _onConnect(aState) { + aState.dbgClient.listTabs(function _onListTabs(aResponse) { + if (aResponse.error) { + Cu.reportError("listTabs failed: " + aResponse.error + " " + + aResponse.message); + aCallback(aState, aResponse); + return; + } + let tab = aResponse.tabs[aResponse.selected]; + aState.actor = tab.consoleActor; + aState.dbgClient.attachConsole(tab.consoleActor, aListeners, + _onAttachConsole.bind(null, aState)); + }); + }); +} + +function closeDebugger(aState, aCallback) +{ + aState.dbgClient.close(aCallback); + aState.dbgClient = null; + aState.client = null; +} + +function checkConsoleAPICall(aCall, aExpected) +{ + if (aExpected.level != "trace" && aExpected.arguments) { + is(aCall.arguments.length, aExpected.arguments.length, + "number of arguments"); + } + + checkObject(aCall, aExpected); +} + +function checkObject(aObject, aExpected) +{ + for (let name of Object.keys(aExpected)) + { + let expected = aExpected[name]; + let value = aObject[name]; + if (value === undefined) { + ok(false, "'" + name + "' is undefined"); + } + else if (typeof expected == "string" || + typeof expected == "number" || + typeof expected == "boolean") { + is(value, expected, "property '" + name + "'"); + } + else if (expected instanceof RegExp) { + ok(expected.test(value), name + ": " + expected); + } + else if (Array.isArray(expected)) { + info("checking array for property '" + name + "'"); + checkObject(value, expected); + } + else if (typeof expected == "object") { + info("checking object for property '" + name + "'"); + checkObject(value, expected); + } + } +} + +function checkHeadersOrCookies(aArray, aExpected) +{ + for (let elem of aArray) { + if (!(elem.name in aExpected)) { + continue; + } + let expected = aExpected[elem.name]; + if (expected instanceof RegExp) { + ok(expected.test(elem.value), elem.name + ": " + expected); + } + else { + is(elem.value, expected, elem.name); + } + } +}
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/data.json @@ -0,0 +1,1 @@ +{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] } \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/network_requests_iframe.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> + <head> + <meta charset="utf-8"> + <title>Console HTTP test page</title> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> + <script type="text/javascript"><!-- + function makeXhr(aMethod, aUrl, aRequestBody, aCallback) { + var xmlhttp = new XMLHttpRequest(); + xmlhttp.open(aMethod, aUrl, true); + if (aCallback) { + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState == 4) { + aCallback(); + } + }; + } + xmlhttp.send(aRequestBody); + } + + function testXhrGet(aCallback) { + makeXhr('get', 'data.json', null, aCallback); + } + + function testXhrPost(aCallback) { + makeXhr('post', 'data.json', "Hello world!", aCallback); + } + + document.cookie = "foobar=fooval"; + document.cookie = "omgfoo=bug768096"; + // --></script> + </head> + <body> + <h1>Web Console HTTP Logging Testpage</h1> + <h2>This page is used to test the HTTP logging.</h2> + + <form action="?" method="post"> + <input name="name" type="text" value="foo bar"><br> + <input name="age" type="text" value="144"><br> + </form> + </body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_basics.html @@ -0,0 +1,69 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Basic Web Console Actor tests</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Basic Web Console Actor tests</p> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["PageError"], onStartPageError); +} + +function onStartPageError(aState, aResponse) +{ + is(aResponse.startedListeners.length, 1, "startedListeners.length"); + is(aResponse.startedListeners[0], "PageError", "startedListeners: PageError"); + ok(aResponse.nativeConsoleAPI, "nativeConsoleAPI"); + + closeDebugger(aState, function() { + top.console_ = top.console; + top.console = { lolz: "foo" }; + attachConsole(["PageError", "ConsoleAPI", "foo"], + onStartPageErrorAndConsoleAPI); + }); +} + +function onStartPageErrorAndConsoleAPI(aState, aResponse) +{ + let startedListeners = aResponse.startedListeners; + is(startedListeners.length, 2, "startedListeners.length"); + isnot(startedListeners.indexOf("PageError"), -1, "startedListeners: PageError"); + isnot(startedListeners.indexOf("ConsoleAPI"), -1, + "startedListeners: ConsoleAPI"); + is(startedListeners.indexOf("foo"), -1, "startedListeners: no foo"); + ok(!aResponse.nativeConsoleAPI, "!nativeConsoleAPI"); + + top.console = top.console_; + delete top.console_; + + aState.client.stopListeners(["ConsoleAPI", "foo"], + onStopConsoleAPI.bind(null, aState)); +} + +function onStopConsoleAPI(aState, aResponse) +{ + is(aResponse.stoppedListeners.length, 1, "stoppedListeners.length"); + is(aResponse.stoppedListeners[0], "ConsoleAPI", "stoppedListeners: ConsoleAPI"); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_cached_messages.html @@ -0,0 +1,179 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for cached messages</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for cached messages</p> + +<script type="application/javascript;version=1.8"> +let expectedConsoleCalls = []; +let expectedPageErrors = []; + +(function() { + Services.console.reset(); + + expectedPageErrors = [ + { + _type: "PageError", + errorMessage: /fooColor/, + sourceName: /.+/, + category: "CSS Parser", + timeStamp: /^\d+$/, + error: false, + warning: true, + exception: false, + strict: false, + }, + { + _type: "PageError", + errorMessage: /doTheImpossible/, + sourceName: /.+/, + category: "content javascript", + timeStamp: /^\d+$/, + error: false, + warning: false, + exception: true, + strict: false, + }, + ]; + + let container = top.document.createElement("script"); + top.document.body.appendChild(container); + container.textContent = "document.body.style.color = 'fooColor';"; + top.document.body.removeChild(container); + + container = top.document.createElement("script"); + top.document.body.appendChild(container); + container.textContent = "document.doTheImpossible();"; + top.document.body.removeChild(container); +})(); + +function doConsoleCalls() +{ + top.console.log("foobarBaz-log", undefined); + top.console.info("foobarBaz-info", null); + top.console.warn("foobarBaz-warn", document.body); + + expectedConsoleCalls = [ + { + _type: "ConsoleAPI", + level: "log", + filename: /test_cached_messages/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-log", { type: "undefined" }], + }, + { + _type: "ConsoleAPI", + level: "info", + filename: /test_cached_messages/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-info", { type: "null" }], + }, + { + _type: "ConsoleAPI", + level: "warn", + filename: /test_cached_messages/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-warn", { type: "object", actor: /[a-z]/ }], + }, + ]; +} +</script> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +let consoleAPIListener; + +let consoleAPICalls = 0; + +let handlers = { + onConsoleAPICall: function onConsoleAPICall() + { + consoleAPICalls++; + if (consoleAPICalls == expectedConsoleCalls.length) { + checkConsoleAPICache(); + } + }, +}; + +function startTest() +{ + removeEventListener("load", startTest); + + consoleAPIListener = new ConsoleAPIListener(top, handlers); + consoleAPIListener.init(); + + doConsoleCalls(); +} + +function checkConsoleAPICache() +{ + consoleAPIListener.destroy(); + consoleAPIListener = null; + attachConsole(["ConsoleAPI"], onAttach1); +} + +function onAttach1(aState, aResponse) +{ + aState.client.getCachedMessages(["ConsoleAPI"], + onCachedConsoleAPI.bind(null, aState)); +} + +function onCachedConsoleAPI(aState, aResponse) +{ + let msgs = aResponse.messages; + + is(msgs.length, expectedConsoleCalls.length, + "number of cached console messages"); + + expectedConsoleCalls.forEach(function(aMessage, aIndex) { + info("checking received cached message #" + aIndex); + checkConsoleAPICall(msgs[aIndex], expectedConsoleCalls[aIndex]); + }); + + closeDebugger(aState, testPageErrors); +} + +function testPageErrors() +{ + attachConsole(["PageError"], onAttach2); +} + +function onAttach2(aState, aResponse) +{ + aState.client.getCachedMessages(["PageError"], + onCachedPageErrors.bind(null, aState)); +} + +function onCachedPageErrors(aState, aResponse) +{ + let msgs = aResponse.messages; + + is(msgs.length, expectedPageErrors.length, + "number of cached page errors"); + + expectedPageErrors.forEach(function(aMessage, aIndex) { + info("checking received cached message #" + aIndex); + checkObject(msgs[aIndex], expectedPageErrors[aIndex]); + }); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_consoleapi.html @@ -0,0 +1,148 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for the Console API</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for the Console API</p> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +let expectedConsoleCalls = []; + +function doConsoleCalls(aState) +{ + console.log("foobarBaz-log", undefined); + console.info("foobarBaz-info", null); + console.warn("foobarBaz-warn", document.body); + console.debug(null); + console.trace(); + console.dir(document, window); + + expectedConsoleCalls = [ + { + level: "log", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-log", { type: "undefined" }], + }, + { + level: "info", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-info", { type: "null" }], + }, + { + level: "warn", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: ["foobarBaz-warn", { type: "object", actor: /[a-z]/ }], + }, + { + level: "debug", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: [{ type: "null" }], + }, + { + level: "trace", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: [ + { + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + }, + { + filename: /test_consoleapi/, + functionName: "onAttach", + }, + ], + }, + { + level: "dir", + filename: /test_consoleapi/, + functionName: "doConsoleCalls", + timeStamp: /^\d+$/, + arguments: [ + { + type: "object", + actor: /[a-z]/, + className: "HTMLDocument", + }, + { + type: "object", + actor: /[a-z]/, + className: "Window", + } + ], + objectProperties: [ + { + name: "ATTRIBUTE_NODE", + value: 2, + }, + { + name: "CDATA_SECTION_NODE", + value: 4, + }, // ... + ], + }, + ]; +} + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["ConsoleAPI"], onAttach); +} + +function onAttach(aState, aResponse) +{ + onConsoleAPICall = onConsoleAPICall.bind(null, aState); + aState.dbgClient.addListener("consoleAPICall", onConsoleAPICall); + doConsoleCalls(aState.actor); +} + +let consoleCalls = []; + +function onConsoleAPICall(aState, aType, aPacket) +{ + is(aPacket.from, aState.actor, "console API call actor"); + + consoleCalls.push(aPacket.message); + if (consoleCalls.length != expectedConsoleCalls.length) { + return; + } + + aState.dbgClient.removeListener("consoleAPICall", onConsoleAPICall); + + expectedConsoleCalls.forEach(function(aMessage, aIndex) { + info("checking received console call #" + aIndex); + checkConsoleAPICall(consoleCalls[aIndex], expectedConsoleCalls[aIndex]); + }); + + + consoleCalls = []; + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_jsterm.html @@ -0,0 +1,146 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for JavaScript terminal functionality</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for JavaScript terminal functionality</p> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["PageError"], onAttach); +} + +function onAttach(aState, aResponse) +{ + top.foobarObject = Object.create(null); + top.foobarObject.foo = 1; + top.foobarObject.foobar = 2; + top.foobarObject.foobaz = 3; + top.foobarObject.omg = 4; + top.foobarObject.omgfoo = 5; + + info("test autocomplete for 'window.foo'"); + onAutocomplete1 = onAutocomplete1.bind(null, aState); + aState.client.autocomplete("window.foo", 0, onAutocomplete1); +} + +function onAutocomplete1(aState, aResponse) +{ + let matches = aResponse.matches; + + is(aResponse.matchProp, "foo", "matchProp"); + is(matches.length, 1, "matches.length"); + is(matches[0], "foobarObject", "matches[0]"); + + info("test autocomplete for 'window.foobarObject.'"); + + onAutocomplete2 = onAutocomplete2.bind(null, aState); + aState.client.autocomplete("window.foobarObject.", 0, onAutocomplete2); +} + +function onAutocomplete2(aState, aResponse) +{ + let matches = aResponse.matches; + + ok(!aResponse.matchProp, "matchProp"); + is(matches.length, 5, "matches.length"); + checkObject(matches, ["foo", "foobar", "foobaz", "omg", "omgfoo"]); + + info("test eval '2+2'"); + + onEval1 = onEval1.bind(null, aState); + aState.client.evaluateJS("2+2", onEval1); +} + +function onEval1(aState, aResponse) +{ + checkObject(aResponse, { + from: aState.actor, + input: "2+2", + result: 4, + }); + + ok(!aResponse.error, "no js error"); + ok(!aResponse.helperResult, "no helper result"); + + info("test eval 'window'"); + onEval2 = onEval2.bind(null, aState); + aState.client.evaluateJS("window", onEval2); +} + +function onEval2(aState, aResponse) +{ + checkObject(aResponse, { + from: aState.actor, + input: "window", + result: { + type: "object", + className: "Window", + actor: /[a-z]/, + }, + }); + + ok(!aResponse.error, "no js error"); + ok(!aResponse.helperResult, "no helper result"); + + info("test eval with exception"); + + onEvalWithException = onEvalWithException.bind(null, aState); + aState.client.evaluateJS("window.doTheImpossible()", + onEvalWithException); +} + +function onEvalWithException(aState, aResponse) +{ + checkObject(aResponse, { + from: aState.actor, + input: "window.doTheImpossible()", + result: { + type: "undefined", + }, + errorMessage: /doTheImpossible/, + }); + + ok(aResponse.error, "js error object"); + ok(!aResponse.helperResult, "no helper result"); + + info("test eval with helper"); + + onEvalWithHelper = onEvalWithHelper.bind(null, aState); + aState.client.evaluateJS("clear()", onEvalWithHelper); +} + +function onEvalWithHelper(aState, aResponse) +{ + checkObject(aResponse, { + from: aState.actor, + input: "clear()", + result: { + type: "undefined", + }, + helperResult: { type: "clearOutput" }, + }); + + ok(!aResponse.error, "no js error"); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_network_get.html @@ -0,0 +1,243 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for the network actor (GET request)</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for the network actor (GET request)</p> + +<iframe src="/tests/toolkit/devtools/webconsole/test/network_requests_iframe.html"></iframe> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +function startTest() +{ + removeEventListener("load", startTest); + attachConsole(["NetworkActivity"], onAttach); +} + +function onAttach(aState, aResponse) +{ + info("test network GET request"); + + onNetworkEvent = onNetworkEvent.bind(null, aState); + aState.dbgClient.addListener("networkEvent", onNetworkEvent); + onNetworkEventUpdate = onNetworkEventUpdate.bind(null, aState); + aState.dbgClient.addListener("networkEventUpdate", onNetworkEventUpdate); + + let iframe = document.querySelector("iframe").contentWindow; + iframe.testXhrGet(); +} + +function onNetworkEvent(aState, aType, aPacket) +{ + is(aPacket.from, aState.actor, "network event actor"); + + info("checking the network event packet"); + + let netActor = aPacket.eventActor; + + checkObject(netActor, { + actor: /[a-z]/, + startedDateTime: /^\d+\-\d+\-\d+T.+$/, + url: /data\.json/, + method: "GET", + }); + + aState.netActor = netActor.actor; + + aState.dbgClient.removeListener("networkEvent", onNetworkEvent); +} + +let updates = []; + +function onNetworkEventUpdate(aState, aType, aPacket) +{ + info("received networkEventUpdate " + aPacket.updateType); + is(aPacket.from, aState.netActor, "networkEventUpdate actor"); + + updates.push(aPacket.updateType); + + let expectedPacket = null; + + switch (aPacket.updateType) { + case "requestHeaders": + case "responseHeaders": + ok(aPacket.headers > 0, "headers > 0"); + ok(aPacket.headersSize > 0, "headersSize > 0"); + break; + case "requestCookies": + expectedPacket = { + cookies: 2, + }; + break; + case "requestPostData": + ok(false, "got unexpected requestPostData"); + break; + case "responseStart": + expectedPacket = { + response: { + httpVersion: /^HTTP\/\d\.\d$/, + status: 200, + statusText: "OK", + headersSize: /^\d+$/, + discardResponseBody: true, + }, + }; + break; + case "responseCookies": + expectedPacket = { + cookies: 0, + }; + break; + case "responseContent": + expectedPacket = { + mimeType: /^application\/(json|octet-stream)$/, + contentSize: 0, + discardResponseBody: true, + }; + break; + case "eventTimings": + expectedPacket = { + totalTime: /^\d+$/, + }; + break; + default: + ok(false, "unknown network event update type: " + + aPacket.updateType); + return; + } + + if (expectedPacket) { + info("checking the packet content"); + checkObject(aPacket, expectedPacket); + } + + if (updates.indexOf("responseContent") > -1 && + updates.indexOf("eventTimings") > -1) { + aState.dbgClient.removeListener("networkEventUpdate", + onNetworkEvent); + + onRequestHeaders = onRequestHeaders.bind(null, aState); + aState.client.getRequestHeaders(aState.netActor, + onRequestHeaders); + } +} + +function onRequestHeaders(aState, aResponse) +{ + info("checking request headers"); + + ok(aResponse.headers.length > 0, "request headers > 0"); + ok(aResponse.headersSize > 0, "request headersSize > 0"); + + checkHeadersOrCookies(aResponse.headers, { + Referer: /network_requests_iframe\.html/, + Cookie: /bug768096/, + }); + + onRequestCookies = onRequestCookies.bind(null, aState); + aState.client.getRequestCookies(aState.netActor, + onRequestCookies); +} + +function onRequestCookies(aState, aResponse) +{ + info("checking request cookies"); + + is(aResponse.cookies.length, 2, "request cookies length"); + + checkHeadersOrCookies(aResponse.cookies, { + foobar: "fooval", + omgfoo: "bug768096", + }); + + onRequestPostData = onRequestPostData.bind(null, aState); + aState.client.getRequestPostData(aState.netActor, + onRequestPostData); +} + +function onRequestPostData(aState, aResponse) +{ + info("checking request POST data"); + + ok(!aResponse.postData.text, "no request POST data"); + ok(aResponse.postDataDiscarded, "request POST data was discarded"); + + onResponseHeaders = onResponseHeaders.bind(null, aState); + aState.client.getResponseHeaders(aState.netActor, + onResponseHeaders); +} + +function onResponseHeaders(aState, aResponse) +{ + info("checking response headers"); + + ok(aResponse.headers.length > 0, "response headers > 0"); + ok(aResponse.headersSize > 0, "response headersSize > 0"); + + checkHeadersOrCookies(aResponse.headers, { + "Content-Type": /^application\/(json|octet-stream)$/, + "Content-Length": /^\d+$/, + }); + + onResponseCookies = onResponseCookies.bind(null, aState); + aState.client.getResponseCookies(aState.netActor, + onResponseCookies); +} + +function onResponseCookies(aState, aResponse) +{ + info("checking response cookies"); + + is(aResponse.cookies.length, 0, "response cookies length"); + + onResponseContent = onResponseContent.bind(null, aState); + aState.client.getResponseContent(aState.netActor, + onResponseContent); +} + +function onResponseContent(aState, aResponse) +{ + info("checking response content"); + + ok(!aResponse.content.text, "no response content"); + ok(aResponse.contentDiscarded, "response content was discarded"); + + onEventTimings = onEventTimings.bind(null, aState); + aState.client.getEventTimings(aState.netActor, + onEventTimings); +} + +function onEventTimings(aState, aResponse) +{ + info("checking event timings"); + + checkObject(aResponse, { + timings: { + blocked: /^-1|\d+$/, + dns: /^-1|\d+$/, + connect: /^-1|\d+$/, + send: /^-1|\d+$/, + wait: /^-1|\d+$/, + receive: /^-1|\d+$/, + }, + totalTime: /^\d+$/, + }); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_network_post.html @@ -0,0 +1,267 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for the network actor (POST request)</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for the network actor (POST request)</p> + +<iframe src="/tests/toolkit/devtools/webconsole/test/network_requests_iframe.html"></iframe> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["NetworkActivity"], onAttach); +} + +function onAttach(aState, aResponse) +{ + info("enable network request and response body logging"); + + onSetPreferences = onSetPreferences.bind(null, aState); + aState.client.setPreferences({ + "NetworkMonitor.saveRequestAndResponseBodies": true, + }, onSetPreferences); +} + +function onSetPreferences(aState, aResponse) +{ + is(aResponse.updated.length, 1, "updated prefs length"); + is(aResponse.updated[0], "NetworkMonitor.saveRequestAndResponseBodies", + "updated prefs length"); + + info("test network POST request"); + + onNetworkEvent = onNetworkEvent.bind(null, aState); + aState.dbgClient.addListener("networkEvent", onNetworkEvent); + onNetworkEventUpdate = onNetworkEventUpdate.bind(null, aState); + aState.dbgClient.addListener("networkEventUpdate", onNetworkEventUpdate); + + let iframe = document.querySelector("iframe").contentWindow; + iframe.testXhrPost(); +} + +function onNetworkEvent(aState, aType, aPacket) +{ + is(aPacket.from, aState.actor, "network event actor"); + + info("checking the network event packet"); + + let netActor = aPacket.eventActor; + + checkObject(netActor, { + actor: /[a-z]/, + startedDateTime: /^\d+\-\d+\-\d+T.+$/, + url: /data\.json/, + method: "POST", + }); + + aState.netActor = netActor.actor; + + aState.dbgClient.removeListener("networkEvent", onNetworkEvent); +} + +let updates = []; + +function onNetworkEventUpdate(aState, aType, aPacket) +{ + info("received networkEventUpdate " + aPacket.updateType); + is(aPacket.from, aState.netActor, "networkEventUpdate actor"); + + updates.push(aPacket.updateType); + + let expectedPacket = null; + + switch (aPacket.updateType) { + case "requestHeaders": + case "responseHeaders": + ok(aPacket.headers > 0, "headers > 0"); + ok(aPacket.headersSize > 0, "headersSize > 0"); + break; + case "requestCookies": + expectedPacket = { + cookies: 2, + }; + break; + case "requestPostData": + ok(aPacket.dataSize > 0, "dataSize > 0"); + ok(!aPacket.discardRequestBody, "discardRequestBody"); + break; + case "responseStart": + expectedPacket = { + response: { + httpVersion: /^HTTP\/\d\.\d$/, + status: 200, + statusText: "OK", + headersSize: /^\d+$/, + discardResponseBody: false, + }, + }; + break; + case "responseCookies": + expectedPacket = { + cookies: 0, + }; + break; + case "responseContent": + expectedPacket = { + mimeType: /^application\/(json|octet-stream)$/, + contentSize: /^\d+$/, + discardResponseBody: false, + }; + break; + case "eventTimings": + expectedPacket = { + totalTime: /^\d+$/, + }; + break; + default: + ok(false, "unknown network event update type: " + + aPacket.updateType); + return; + } + + if (expectedPacket) { + info("checking the packet content"); + checkObject(aPacket, expectedPacket); + } + + if (updates.indexOf("responseContent") > -1 && + updates.indexOf("eventTimings") > -1) { + aState.dbgClient.removeListener("networkEventUpdate", + onNetworkEvent); + + onRequestHeaders = onRequestHeaders.bind(null, aState); + aState.client.getRequestHeaders(aState.netActor, + onRequestHeaders); + } +} + +function onRequestHeaders(aState, aResponse) +{ + info("checking request headers"); + + ok(aResponse.headers.length > 0, "request headers > 0"); + ok(aResponse.headersSize > 0, "request headersSize > 0"); + + checkHeadersOrCookies(aResponse.headers, { + Referer: /network_requests_iframe\.html/, + Cookie: /bug768096/, + }); + + onRequestCookies = onRequestCookies.bind(null, aState); + aState.client.getRequestCookies(aState.netActor, + onRequestCookies); +} + +function onRequestCookies(aState, aResponse) +{ + info("checking request cookies"); + + is(aResponse.cookies.length, 2, "request cookies length"); + + checkHeadersOrCookies(aResponse.cookies, { + foobar: "fooval", + omgfoo: "bug768096", + }); + + onRequestPostData = onRequestPostData.bind(null, aState); + aState.client.getRequestPostData(aState.netActor, + onRequestPostData); +} + +function onRequestPostData(aState, aResponse) +{ + info("checking request POST data"); + + checkObject(aResponse, { + postData: { + text: "Hello world!", + }, + postDataDiscarded: false, + }); + + onResponseHeaders = onResponseHeaders.bind(null, aState); + aState.client.getResponseHeaders(aState.netActor, + onResponseHeaders); +} + +function onResponseHeaders(aState, aResponse) +{ + info("checking response headers"); + + ok(aResponse.headers.length > 0, "response headers > 0"); + ok(aResponse.headersSize > 0, "response headersSize > 0"); + + checkHeadersOrCookies(aResponse.headers, { + "Content-Type": /^application\/(json|octet-stream)$/, + "Content-Length": /^\d+$/, + }); + + onResponseCookies = onResponseCookies.bind(null, aState); + aState.client.getResponseCookies(aState.netActor, + onResponseCookies); +} + +function onResponseCookies(aState, aResponse) +{ + info("checking response cookies"); + + is(aResponse.cookies.length, 0, "response cookies length"); + + onResponseContent = onResponseContent.bind(null, aState); + aState.client.getResponseContent(aState.netActor, + onResponseContent); +} + +function onResponseContent(aState, aResponse) +{ + info("checking response content"); + + checkObject(aResponse, { + content: { + text: /"test JSON data"/, + }, + contentDiscarded: false, + }); + + onEventTimings = onEventTimings.bind(null, aState); + aState.client.getEventTimings(aState.netActor, + onEventTimings); +} + +function onEventTimings(aState, aResponse) +{ + info("checking event timings"); + + checkObject(aResponse, { + timings: { + blocked: /^-1|\d+$/, + dns: /^-1|\d+$/, + connect: /^-1|\d+$/, + send: /^-1|\d+$/, + wait: /^-1|\d+$/, + receive: /^-1|\d+$/, + }, + totalTime: /^\d+$/, + }); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_object_actor.html @@ -0,0 +1,172 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for the object actor</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for the object actor</p> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +let expectedProps = []; + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["ConsoleAPI"], onAttach); +} + +function onAttach(aState, aResponse) +{ + onConsoleCall = onConsoleCall.bind(null, aState); + aState.dbgClient.addListener("consoleAPICall", onConsoleCall); + + window.foobarObject = Object.create(null); + foobarObject.foo = 1; + foobarObject.foobar = "hello"; + foobarObject.foobaz = document; + foobarObject.omg = null; + foobarObject.testfoo = false; + foobarObject.notInspectable = {}; + foobarObject.omgfn = function _omgfn() { + return "myResult"; + }; + foobarObject.abArray = ["a", "b"]; + + Object.defineProperty(foobarObject, "getterAndSetter", { + enumerable: true, + get: function fooGet() { return "foo"; }, + set: function fooSet() { 1+2 }, + }); + + console.log("hello", foobarObject); + + expectedProps = [ + { + name: "abArray", + value: { + type: "object", + className: "Array", + actor: /[a-z]/, + inspectable: true, + }, + }, + { + name: "foo", + configurable: true, + enumerable: true, + writable: true, + value: 1, + }, + { + name: "foobar", + value: "hello", + }, + { + name: "foobaz", + value: { + type: "object", + className: "HTMLDocument", + displayString: /\[object HTMLDocument/, + inspectable: true, + actor: /[a-z]/, + }, + }, + { + name: "getterAndSetter", + get: { + type: "function", + className: "function", + displayString: /function fooGet/, + actor: /[a-z]/, + inspectable: false, + }, + set: { + type: "function", + className: "function", + displayString: /function fooSet/, + actor: /[a-z]/, + inspectable: false, + }, + }, + { + name: "notInspectable", + value: { + type: "object", + className: "Object", + actor: /[a-z]/, + inspectable: false, + }, + }, + { + name: "omg", + value: { type: "null" }, + }, + { + name: "omgfn", + value: { + type: "function", + className: "function", + displayString: /function _omgfn/, + actor: /[a-z]/, + inspectable: false, + }, + }, + { + name: "testfoo", + value: false, + }, + ]; +} + +function onConsoleCall(aState, aType, aPacket) +{ + is(aPacket.from, aState.actor, "console API call actor"); + + info("checking the console API call packet"); + + checkConsoleAPICall(aPacket.message, { + level: "log", + filename: /test_object_actor/, + functionName: "onAttach", + arguments: ["hello", { + type: "object", + actor: /[a-z]/, + inspectable: true, + }], + }); + + aState.dbgClient.removeListener("consoleAPICall", onConsoleCall); + + info("inspecting object properties"); + let args = aPacket.message.arguments; + onProperties = onProperties.bind(null, aState); + aState.client.inspectObjectProperties(args[1].actor, onProperties); +} + +function onProperties(aState, aResponse) +{ + let props = aResponse.properties; + is(props.length, expectedProps.length, + "number of enumerable properties"); + checkObject(props, expectedProps); + + expectedProps = []; + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>
new file mode 100644 --- /dev/null +++ b/toolkit/devtools/webconsole/test/test_page_errors.html @@ -0,0 +1,98 @@ +<!DOCTYPE HTML> +<html lang="en"> +<head> + <meta charset="utf8"> + <title>Test for page errors</title> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript;version=1.8" src="common.js"></script> + <!-- Any copyright is dedicated to the Public Domain. + - http://creativecommons.org/publicdomain/zero/1.0/ --> +</head> +<body> +<p>Test for page errors</p> + +<script type="text/javascript;version=1.8"> +netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); +SimpleTest.waitForExplicitFinish(); + +let expectedPageErrors = []; + +function doPageErrors() +{ + expectedPageErrors = [ + { + errorMessage: /fooColor/, + sourceName: /test_page_errors/, + category: "CSS Parser", + timeStamp: /^\d+$/, + error: false, + warning: true, + exception: false, + strict: false, + }, + { + errorMessage: /doTheImpossible/, + sourceName: /test_page_errors/, + category: "content javascript", + timeStamp: /^\d+$/, + error: false, + warning: false, + exception: true, + strict: false, + }, + ]; + + let container = document.createElement("script"); + document.body.appendChild(container); + container.textContent = "document.body.style.color = 'fooColor';"; + document.body.removeChild(container); + + SimpleTest.expectUncaughtException(); + + container = document.createElement("script"); + document.body.appendChild(container); + container.textContent = "document.doTheImpossible();"; + document.body.removeChild(container); +} + +function startTest() +{ + removeEventListener("load", startTest); + + attachConsole(["PageError"], onAttach); +} + +function onAttach(aState, aResponse) +{ + onPageError = onPageError.bind(null, aState); + aState.dbgClient.addListener("pageError", onPageError); + doPageErrors(); +} + +let pageErrors = []; + +function onPageError(aState, aType, aPacket) +{ + is(aPacket.from, aState.actor, "page error actor"); + + pageErrors.push(aPacket.pageError); + if (pageErrors.length != expectedPageErrors.length) { + return; + } + + aState.dbgClient.removeListener("pageError", onPageError); + + expectedPageErrors.forEach(function(aMessage, aIndex) { + info("checking received page error #" + aIndex); + checkObject(pageErrors[aIndex], expectedPageErrors[aIndex]); + }); + + closeDebugger(aState, function() { + SimpleTest.finish(); + }); +} + +addEventListener("load", startTest); +</script> +</body> +</html>