summaryrefslogtreecommitdiffstats
path: root/devtools/shared/webconsole/test/browser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /devtools/shared/webconsole/test/browser
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/shared/webconsole/test/browser')
-rw-r--r--devtools/shared/webconsole/test/browser/browser.ini13
-rw-r--r--devtools/shared/webconsole/test/browser/browser_commands_registration.js199
-rw-r--r--devtools/shared/webconsole/test/browser/browser_network_longstring.js182
-rw-r--r--devtools/shared/webconsole/test/browser/data.json3
-rw-r--r--devtools/shared/webconsole/test/browser/data.json^headers^3
-rw-r--r--devtools/shared/webconsole/test/browser/head.js63
-rw-r--r--devtools/shared/webconsole/test/browser/network_requests_iframe.html66
7 files changed, 529 insertions, 0 deletions
diff --git a/devtools/shared/webconsole/test/browser/browser.ini b/devtools/shared/webconsole/test/browser/browser.ini
new file mode 100644
index 0000000000..1b66699410
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/browser.ini
@@ -0,0 +1,13 @@
+[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..aa166e5d89
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/browser_commands_registration.js
@@ -0,0 +1,199 @@
+/* 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 WebConsoleCommands 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 {
+ WebConsoleCommands,
+ } = require("resource://devtools/server/actors/webconsole/utils.js");
+
+ // Bind the symbol on this in order to make it available for next tasks
+ this.WebConsoleCommands = WebConsoleCommands;
+ });
+
+ await registerNewCommand(commands);
+ await wrapCommand(commands);
+ await unregisterCommand(commands);
+ await registerAccessor(commands);
+ await unregisterAfterOverridingTwice(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.WebConsoleCommands.register("setFoo", (owner, value) => {
+ owner.window.foo = value;
+ return "ok";
+ });
+
+ ok(
+ this.WebConsoleCommands.hasCommand("setFoo"),
+ "The command should be registered"
+ );
+ });
+
+ 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 wrapCommand(commands) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ const origKeys = this.WebConsoleCommands.getCommand("keys");
+
+ const newKeys = (...args) => {
+ const [, arg0] = args;
+ if (arg0 === ">o_/") {
+ return "bang!";
+ }
+ return origKeys(...args);
+ };
+
+ this.WebConsoleCommands.register("keys", newKeys);
+ is(
+ this.WebConsoleCommands.getCommand("keys"),
+ newKeys,
+ "the keys() command should have been replaced"
+ );
+
+ this.origKeys = origKeys;
+ });
+
+ await evaluateJSAndCheckResult(commands, "keys('>o_/')", {
+ result: "bang!",
+ });
+
+ await evaluateJSAndCheckResult(commands, "keys({foo: 'bar'})", {
+ result: {
+ _grip: {
+ class: "Array",
+ preview: {
+ items: ["foo"],
+ },
+ },
+ },
+ });
+
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.register("keys", this.origKeys);
+ is(
+ this.WebConsoleCommands.getCommand("keys"),
+ this.origKeys,
+ "the keys() command should be restored"
+ );
+ delete this.origKeys;
+ });
+}
+
+async function unregisterCommand(commands) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.unregister("setFoo");
+ });
+
+ await evaluateJSAndCheckResult(commands, "setFoo", {
+ input: "setFoo",
+ result: {
+ type: "undefined",
+ },
+ exceptionMessage: /setFoo is not defined/,
+ });
+}
+
+async function registerAccessor(commands) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.register("$foo", {
+ 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_/"'
+ );
+ this.WebConsoleCommands.unregister("$foo");
+ ok(
+ !this.WebConsoleCommands.hasCommand("$foo"),
+ "$foo should be unregistered"
+ );
+ });
+}
+
+async function unregisterAfterOverridingTwice(commands) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.register("keys", (owner, obj) => "command 1");
+ });
+
+ info("checking the value of the first override");
+ await evaluateJSAndCheckResult(commands, "keys('foo');", {
+ result: "command 1",
+ });
+
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ const orig = this.WebConsoleCommands.getCommand("keys");
+ this.WebConsoleCommands.register("keys", (owner, obj) => {
+ if (obj === "quack") {
+ return "bang!";
+ }
+ return orig(owner, obj);
+ });
+ });
+
+ info("checking the values after the second override");
+ await evaluateJSAndCheckResult(commands, "keys({});", {
+ result: "command 1",
+ });
+ await evaluateJSAndCheckResult(commands, "keys('quack');", {
+ result: "bang!",
+ });
+
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.unregister("keys");
+ });
+
+ info(
+ "checking the value after unregistration (should restore " +
+ "the original command)"
+ );
+ await evaluateJSAndCheckResult(commands, "keys({});", {
+ result: {
+ _grip: {
+ class: "Array",
+ preview: { items: [] },
+ },
+ },
+ });
+}
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..d3f85f3dc8
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/browser_network_longstring.js
@@ -0,0 +1,182 @@
+/* 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();
+ const target = commands.targetCommand.targetFront;
+
+ // 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 webConsoleFront = await target.getFront("console");
+ const requestHeaders = await webConsoleFront.getRequestHeaders(netActor);
+ assertRequestHeaders(requestHeaders);
+ const requestCookies = await webConsoleFront.getRequestCookies(netActor);
+ assertRequestCookies(requestCookies);
+ const requestPostData = await webConsoleFront.getRequestPostData(netActor);
+ assertRequestPostData(requestPostData);
+ const responseHeaders = await webConsoleFront.getResponseHeaders(netActor);
+ assertResponseHeaders(responseHeaders);
+ const responseCookies = await webConsoleFront.getResponseCookies(netActor);
+ assertResponseCookies(responseCookies);
+ const responseContent = await webConsoleFront.getResponseContent(netActor);
+ assertResponseContent(responseContent);
+ const eventTimings = await webConsoleFront.getEventTimings(netActor);
+ 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");
+ ok(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");
+ ok(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..65189c1aef
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/head.js
@@ -0,0 +1,63 @@
+/* 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";
+
+/* import-globals-from ../../../../client/shared/test/shared-head.js */
+
+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>