summaryrefslogtreecommitdiffstats
path: root/devtools/shared/webconsole/test/browser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/shared/webconsole/test/browser
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.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/.eslintrc.js6
-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.js269
-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.js70
-rw-r--r--devtools/shared/webconsole/test/browser/network_requests_iframe.html66
8 files changed, 629 insertions, 0 deletions
diff --git a/devtools/shared/webconsole/test/browser/.eslintrc.js b/devtools/shared/webconsole/test/browser/.eslintrc.js
new file mode 100644
index 0000000000..2eba290f7d
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/.eslintrc.js
@@ -0,0 +1,6 @@
+"use strict";
+
+module.exports = {
+ // Extend from the shared list of defined globals for mochitests.
+ extends: "../../../../.eslintrc.mochitests.js",
+};
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..c8d410f8d7
--- /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 target = await getTargetForTab(tab);
+
+ const webConsoleFront = await target.getFront("console");
+
+ // Fetch WebConsoleCommands so that it is available for next Content Tasks
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ const { require } = ChromeUtils.import(
+ "resource://devtools/shared/Loader.jsm"
+ );
+ const {
+ WebConsoleCommands,
+ } = require("devtools/server/actors/webconsole/utils");
+
+ // Bind the symbol on this in order to make it available for next tasks
+ this.WebConsoleCommands = WebConsoleCommands;
+ });
+
+ await registerNewCommand(webConsoleFront);
+ await wrapCommand(webConsoleFront);
+ await unregisterCommand(webConsoleFront);
+ await registerAccessor(webConsoleFront);
+ await unregisterAfterOverridingTwice(webConsoleFront);
+});
+
+async function evaluateJSAndCheckResult(webConsoleFront, input, expected) {
+ const response = await webConsoleFront.evaluateJSAsync(input);
+ checkObject(response, expected);
+}
+
+async function registerNewCommand(webConsoleFront) {
+ 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(webConsoleFront, 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(webConsoleFront) {
+ 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(webConsoleFront, "keys('>o_/')", {
+ result: "bang!",
+ });
+
+ await evaluateJSAndCheckResult(webConsoleFront, "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(webConsoleFront) {
+ await ContentTask.spawn(gBrowser.selectedBrowser, null, function() {
+ this.WebConsoleCommands.unregister("setFoo");
+ });
+
+ await evaluateJSAndCheckResult(webConsoleFront, "setFoo", {
+ input: "setFoo",
+ result: {
+ type: "undefined",
+ },
+ exceptionMessage: /setFoo is not defined/,
+ });
+}
+
+async function registerAccessor(webConsoleFront) {
+ 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(webConsoleFront, 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(webConsoleFront) {
+ 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(webConsoleFront, "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(webConsoleFront, "keys({});", {
+ result: "command 1",
+ });
+ await evaluateJSAndCheckResult(webConsoleFront, "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(webConsoleFront, "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..84eb9e07e1
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/browser_network_longstring.js
@@ -0,0 +1,269 @@
+/* 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("devtools/server/devtools-server");
+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 target = await getTargetForTab(tab);
+ const { client } = target;
+ const webConsoleFront = await target.getFront("console");
+
+ await webConsoleFront.startListeners(["NetworkActivity"]);
+
+ // 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 onNetworkEvent = webConsoleFront.once("serverNetworkEvent");
+ const updates = [];
+ let netActor = null;
+ const onAllNetworkEventUpdateReceived = new Promise(resolve => {
+ const onNetworkEventUpdate = packet => {
+ updates.push(packet.updateType);
+ assertNetworkEventUpdate(netActor, packet);
+
+ if (
+ updates.includes("responseContent") &&
+ updates.includes("eventTimings")
+ ) {
+ client.off("networkEventUpdate", onNetworkEventUpdate);
+ resolve();
+ }
+ };
+ client.on("networkEventUpdate", onNetworkEventUpdate);
+ });
+
+ await SpecialPowers.spawn(gBrowser.selectedBrowser, [], async function() {
+ content.wrappedJSObject.testXhrPost();
+ });
+
+ info("Waiting for networkEvent");
+ const netEvent = await onNetworkEvent;
+ netActor = assertNetworkEvent(client, webConsoleFront, netEvent);
+
+ info("Waiting for all networkEventUpdate");
+ await onAllNetworkEventUpdateReceived;
+ 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 target.destroy();
+
+ DevToolsServer.LONG_STRING_LENGTH = ORIGINAL_LONG_STRING_LENGTH;
+ DevToolsServer.LONG_STRING_INITIAL_LENGTH = ORIGINAL_LONG_STRING_INITIAL_LENGTH;
+});
+
+function assertNetworkEvent(client, webConsoleFront, packet) {
+ info("checking the network event packet");
+
+ const netActor = packet.eventActor;
+
+ checkObject(netActor, {
+ actor: /[a-z]/,
+ startedDateTime: /^\d+\-\d+\-\d+T.+$/,
+ url: /data\.json/,
+ method: "POST",
+ });
+
+ return netActor.actor;
+}
+
+function assertNetworkEventUpdate(netActor, packet) {
+ info("received networkEventUpdate " + packet.updateType);
+ is(packet.from, netActor, "networkEventUpdate actor");
+
+ let expectedPacket = null;
+
+ switch (packet.updateType) {
+ case "requestHeaders":
+ case "responseHeaders":
+ ok(packet.headers > 0, "headers > 0");
+ ok(packet.headersSize > 0, "headersSize > 0");
+ break;
+ case "requestCookies":
+ expectedPacket = {
+ cookies: 3,
+ };
+ break;
+ case "requestPostData":
+ ok(packet.dataSize > 0, "dataSize > 0");
+ break;
+ case "responseStart":
+ expectedPacket = {
+ response: {
+ httpVersion: /^HTTP\/\d\.\d$/,
+ status: "200",
+ statusText: "OK",
+ headersSize: /^\d+$/,
+ },
+ };
+ break;
+ case "securityInfo":
+ expectedPacket = {
+ state: "insecure",
+ };
+ break;
+ case "responseCookies":
+ expectedPacket = {
+ cookies: 0,
+ };
+ break;
+ case "responseContent":
+ expectedPacket = {
+ mimeType: "application/json",
+ contentSize: /^\d+$/,
+ };
+ break;
+ case "eventTimings":
+ expectedPacket = {
+ totalTime: /^\d+$/,
+ };
+ break;
+ default:
+ ok(false, "unknown network event update type: " + packet.updateType);
+ return;
+ }
+
+ if (expectedPacket) {
+ info("checking the packet content");
+ checkObject(packet, expectedPacket);
+ }
+}
+
+function assertRequestHeaders(response) {
+ info("checking request headers");
+
+ ok(response.headers.length > 0, "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 > 0, "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..2ce4d01998
--- /dev/null
+++ b/devtools/shared/webconsole/test/browser/head.js
@@ -0,0 +1,70 @@
+/* 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
+);
+
+async function getTargetForTab(tab) {
+ const target = await TargetFactory.forTab(tab);
+ info("Attaching to the active tab.");
+ await target.attach();
+ return target;
+}
+
+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>