diff options
Diffstat (limited to 'devtools/shared/webconsole/test/browser')
7 files changed, 437 insertions, 0 deletions
diff --git a/devtools/shared/webconsole/test/browser/browser.toml b/devtools/shared/webconsole/test/browser/browser.toml new file mode 100644 index 0000000000..31c82d6307 --- /dev/null +++ b/devtools/shared/webconsole/test/browser/browser.toml @@ -0,0 +1,15 @@ +[DEFAULT] +tags = "devtools" +subsuite = "devtools" +support-files = [ + "head.js", + "data.json", + "data.json^headers^", + "network_requests_iframe.html", + "!/devtools/client/shared/test/shared-head.js", + "!/devtools/client/shared/test/telemetry-test-helpers.js", +] + +["browser_commands_registration.js"] + +["browser_network_longstring.js"] diff --git a/devtools/shared/webconsole/test/browser/browser_commands_registration.js b/devtools/shared/webconsole/test/browser/browser_commands_registration.js new file mode 100644 index 0000000000..e2c128df57 --- /dev/null +++ b/devtools/shared/webconsole/test/browser/browser_commands_registration.js @@ -0,0 +1,86 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test for Web Console commands registration. + +add_task(async function () { + const tab = await addTab("data:text/html,<div id=quack></div>"); + + const commands = await CommandsFactory.forTab(tab); + await commands.targetCommand.startListening(); + + // Fetch WebConsoleCommandsManager so that it is available for next Content Tasks + await ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + const { require } = ChromeUtils.importESModule( + "resource://devtools/shared/loader/Loader.sys.mjs" + ); + const { + WebConsoleCommandsManager, + } = require("resource://devtools/server/actors/webconsole/commands/manager.js"); + + // Bind the symbol on this in order to make it available for next tasks + this.WebConsoleCommandsManager = WebConsoleCommandsManager; + }); + + await registerNewCommand(commands); + await registerAccessor(commands); +}); + +async function evaluateJSAndCheckResult(commands, input, expected) { + const response = await commands.scriptCommand.execute(input); + checkObject(response, expected); +} + +async function registerNewCommand(commands) { + await ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + this.WebConsoleCommandsManager.register({ + name: "setFoo", + isSideEffectFree: false, + command(owner, value) { + owner.window.foo = value; + return "ok"; + }, + }); + }); + + const command = "setFoo('bar')"; + await evaluateJSAndCheckResult(commands, command, { + input: command, + result: "ok", + }); + + await ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + is(content.top.foo, "bar", "top.foo should equal to 'bar'"); + }); +} + +async function registerAccessor(commands) { + await ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + this.WebConsoleCommandsManager.register({ + name: "$foo", + isSideEffectFree: true, + command: { + get(owner) { + const foo = owner.window.document.getElementById("quack"); + return owner.makeDebuggeeValue(foo); + }, + }, + }); + }); + + const command = "$foo.textContent = '>o_/'"; + await evaluateJSAndCheckResult(commands, command, { + input: command, + result: ">o_/", + }); + + await ContentTask.spawn(gBrowser.selectedBrowser, null, function () { + is( + content.document.getElementById("quack").textContent, + ">o_/", + '#foo textContent should equal to ">o_/"' + ); + }); +} diff --git a/devtools/shared/webconsole/test/browser/browser_network_longstring.js b/devtools/shared/webconsole/test/browser/browser_network_longstring.js new file mode 100644 index 0000000000..6cb1850848 --- /dev/null +++ b/devtools/shared/webconsole/test/browser/browser_network_longstring.js @@ -0,0 +1,203 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that the network actor uses the LongStringActor + +const { + DevToolsServer, +} = require("resource://devtools/server/devtools-server.js"); +const LONG_STRING_LENGTH = 400; +const LONG_STRING_INITIAL_LENGTH = 400; +let ORIGINAL_LONG_STRING_LENGTH, ORIGINAL_LONG_STRING_INITIAL_LENGTH; + +add_task(async function () { + const tab = await addTab(URL_ROOT + "network_requests_iframe.html"); + + const commands = await CommandsFactory.forTab(tab); + await commands.targetCommand.startListening(); + + // Override the default long string settings to lower values. + // This is done from the parent process's DevToolsServer as the LongString + // actor is being created from the parent process as network requests are + // watched from the parent process. + ORIGINAL_LONG_STRING_LENGTH = DevToolsServer.LONG_STRING_LENGTH; + ORIGINAL_LONG_STRING_INITIAL_LENGTH = + DevToolsServer.LONG_STRING_INITIAL_LENGTH; + + DevToolsServer.LONG_STRING_LENGTH = LONG_STRING_LENGTH; + DevToolsServer.LONG_STRING_INITIAL_LENGTH = LONG_STRING_INITIAL_LENGTH; + + info("test network POST request"); + const networkResource = await new Promise(resolve => { + commands.resourceCommand + .watchResources([commands.resourceCommand.TYPES.NETWORK_EVENT], { + onAvailable: () => {}, + onUpdated: resourceUpdate => { + resolve(resourceUpdate[0].resource); + }, + }) + .then(() => { + // Spawn the network request after we started watching + SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function () { + content.wrappedJSObject.testXhrPost(); + }); + }); + }); + + const netActor = networkResource.actor; + ok(netActor, "We have a netActor:" + netActor); + + const { client } = commands; + const requestHeaders = await client.request({ + to: netActor, + type: "getRequestHeaders", + }); + assertRequestHeaders(requestHeaders); + const requestCookies = await client.request({ + to: netActor, + type: "getRequestCookies", + }); + assertRequestCookies(requestCookies); + const requestPostData = await client.request({ + to: netActor, + type: "getRequestPostData", + }); + assertRequestPostData(requestPostData); + const responseHeaders = await client.request({ + to: netActor, + type: "getResponseHeaders", + }); + assertResponseHeaders(responseHeaders); + const responseCookies = await client.request({ + to: netActor, + type: "getResponseCookies", + }); + assertResponseCookies(responseCookies); + const responseContent = await client.request({ + to: netActor, + type: "getResponseContent", + }); + assertResponseContent(responseContent); + const eventTimings = await client.request({ + to: netActor, + type: "getEventTimings", + }); + assertEventTimings(eventTimings); + + await commands.destroy(); + + DevToolsServer.LONG_STRING_LENGTH = ORIGINAL_LONG_STRING_LENGTH; + DevToolsServer.LONG_STRING_INITIAL_LENGTH = + ORIGINAL_LONG_STRING_INITIAL_LENGTH; +}); + +function assertRequestHeaders(response) { + info("checking request headers"); + + ok(!!response.headers.length, "request headers > 0"); + Assert.greater(response.headersSize, 0, "request headersSize > 0"); + + checkHeadersOrCookies(response.headers, { + Referer: /network_requests_iframe\.html/, + Cookie: /bug768096/, + }); +} + +function assertRequestCookies(response) { + info("checking request cookies"); + + is(response.cookies.length, 3, "request cookies length"); + + checkHeadersOrCookies(response.cookies, { + foobar: "fooval", + omgfoo: "bug768096", + badcookie: "bug826798=st3fan", + }); +} + +function assertRequestPostData(response) { + info("checking request POST data"); + + checkObject(response, { + postData: { + text: { + type: "longString", + initial: /^Hello world! foobaz barr.+foobaz barrfo$/, + length: 563, + actor: /[a-z]/, + }, + }, + postDataDiscarded: false, + }); + + is( + response.postData.text.initial.length, + LONG_STRING_INITIAL_LENGTH, + "postData text initial length" + ); +} + +function assertResponseHeaders(response) { + info("checking response headers"); + + ok(!!response.headers.length, "response headers > 0"); + Assert.greater(response.headersSize, 0, "response headersSize > 0"); + + checkHeadersOrCookies(response.headers, { + "content-type": /^application\/(json|octet-stream)$/, + "content-length": /^\d+$/, + "x-very-short": "hello world", + "x-very-long": { + type: "longString", + length: 521, + initial: /^Lorem ipsum.+\. Donec vitae d$/, + actor: /[a-z]/, + }, + }); +} + +function assertResponseCookies(response) { + info("checking response cookies"); + + is(response.cookies.length, 0, "response cookies length"); +} + +function assertResponseContent(response) { + info("checking response content"); + + checkObject(response, { + content: { + text: { + type: "longString", + initial: /^\{ id: "test JSON data"(.|\r|\n)+ barfoo ba$/g, + length: 1070, + actor: /[a-z]/, + }, + }, + contentDiscarded: false, + }); + + is( + response.content.text.initial.length, + LONG_STRING_INITIAL_LENGTH, + "content initial length" + ); +} + +function assertEventTimings(response) { + info("checking event timings"); + + checkObject(response, { + timings: { + blocked: /^-1|\d+$/, + dns: /^-1|\d+$/, + connect: /^-1|\d+$/, + send: /^-1|\d+$/, + wait: /^-1|\d+$/, + receive: /^-1|\d+$/, + }, + totalTime: /^\d+$/, + }); +} diff --git a/devtools/shared/webconsole/test/browser/data.json b/devtools/shared/webconsole/test/browser/data.json new file mode 100644 index 0000000000..d46085c124 --- /dev/null +++ b/devtools/shared/webconsole/test/browser/data.json @@ -0,0 +1,3 @@ +{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ], + veryLong: "foo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo barfoo bar" +} diff --git a/devtools/shared/webconsole/test/browser/data.json^headers^ b/devtools/shared/webconsole/test/browser/data.json^headers^ new file mode 100644 index 0000000000..bb6b45500f --- /dev/null +++ b/devtools/shared/webconsole/test/browser/data.json^headers^ @@ -0,0 +1,3 @@ +Content-Type: application/json +x-very-long: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a ipsum massa. Phasellus at elit dictum libero laoreet sagittis. Phasellus condimentum ultricies imperdiet. Nam eu ligula justo, ut tincidunt quam. Etiam sollicitudin, tortor sed egestas blandit, sapien sem tincidunt nulla, eu luctus libero odio quis leo. Nam elit massa, mattis quis blandit ac, facilisis vitae arcu. Donec vitae dictum neque. Proin ornare nisl at lectus commodo iaculis eget eget est. Quisque scelerisque vestibulum quam sed interdum. +x-very-short: hello world diff --git a/devtools/shared/webconsole/test/browser/head.js b/devtools/shared/webconsole/test/browser/head.js new file mode 100644 index 0000000000..cdfc7ab59a --- /dev/null +++ b/devtools/shared/webconsole/test/browser/head.js @@ -0,0 +1,61 @@ +/* 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/. */ + +"use strict"; + +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js", + this +); + +function checkObject(object, expected) { + for (const name of Object.keys(expected)) { + const expectedValue = expected[name]; + const value = object[name]; + checkValue(name, value, expectedValue); + } +} + +function checkValue(name, value, expected) { + if (expected === null) { + is(value, null, "'" + name + "' is null"); + } else if (value === null) { + ok(false, "'" + name + "' is null"); + } else 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 + " matched " + value); + } 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(array, expected) { + const foundHeaders = {}; + + for (const elem of array) { + if (!(elem.name in expected)) { + continue; + } + foundHeaders[elem.name] = true; + info("checking value of header " + elem.name); + checkValue(elem.name, elem.value, expected[elem.name]); + } + + for (const header in expected) { + if (!(header in foundHeaders)) { + ok(false, header + " was not found"); + } + } +} diff --git a/devtools/shared/webconsole/test/browser/network_requests_iframe.html b/devtools/shared/webconsole/test/browser/network_requests_iframe.html new file mode 100644 index 0000000000..4e96364b06 --- /dev/null +++ b/devtools/shared/webconsole/test/browser/network_requests_iframe.html @@ -0,0 +1,66 @@ +<!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"><!-- + "use strict"; + let setAllowAllCookies = false; + + function makeXhr(method, url, requestBody, callback) { + // On the first call, allow all cookies and set cookies, then resume the actual test + if (!setAllowAllCookies) { + SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, + function() { + setAllowAllCookies = true; + setCookies(); + makeXhrCallback(method, url, requestBody, callback); + }); + } else { + makeXhrCallback(method, url, requestBody, callback); + } + } + + function makeXhrCallback(method, url, requestBody, callback) { + const xmlhttp = new XMLHttpRequest(); + xmlhttp.open(method, url, true); + if (callback) { + xmlhttp.onreadystatechange = function() { + if (xmlhttp.readyState == 4) { + callback(); + } + }; + } + xmlhttp.send(requestBody); + } + + /* exported testXhrGet */ + function testXhrGet(callback) { + makeXhr("get", "data.json", null, callback); + } + + /* exported testXhrPost */ + function testXhrPost(callback) { + const body = "Hello world! " + "foobaz barr".repeat(50); + makeXhr("post", "data.json", body, callback); + } + + function setCookies() { + document.cookie = "foobar=fooval"; + document.cookie = "omgfoo=bug768096"; + document.cookie = "badcookie=bug826798=st3fan"; + } + </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> |