Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

/* Any copyright is dedicated to the Public Domain.
"use strict";
const TEST_FILE = "test-network-request.html";
const TEST_PATH =
const TEST_URI = TEST_PATH + TEST_FILE;
const XHR_URL = TEST_PATH + "sjs_slow-response-test-server.sjs";
requestLongerTimeout(2);
registerCleanupFunction(async function () {
await new Promise(resolve => {
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () =>
resolve()
);
});
});
pushPref("devtools.webconsole.filter.net", false);
pushPref("devtools.webconsole.filter.netxhr", true);
/**
* Main test for checking HTTP logs in the Console panel.
*/
add_task(async function task() {
const hud = await openNewTabAndConsole(TEST_URI);
const messageNode = await doXhrAndExpand(hud);
await testNetworkMessage(hud.toolbox, messageNode);
await closeToolbox();
});
add_task(async function task() {
info(
"Verify that devtools.netmonitor.saveRequestAndResponseBodies=false disable response content collection"
);
await pushPref("devtools.netmonitor.saveRequestAndResponseBodies", false);
const hud = await openNewTabAndConsole(TEST_URI);
const messageNode = await doXhrAndExpand(hud);
const responseTab = messageNode.querySelector("#response-tab");
ok(responseTab, "Response tab is available");
const {
TEST_EVENTS,
const onResponseContent = hud.ui.once(TEST_EVENTS.RECEIVED_RESPONSE_CONTENT);
// Select Response tab and check the content.
responseTab.click();
// Even if response content aren't collected by NetworkObserver,
// we do try to fetch the content via an RDP request, which
// we try to wait for here.
info("Wait for the async getResponseContent request");
await onResponseContent;
const responsePanel = messageNode.querySelector("#response-panel");
// This is updated only after we tried to fetch the response content
// and fired the getResponseContent request
info("Wait for the empty response content");
ok(
responsePanel.querySelector("div.empty-notice"),
"An empty notice is displayed instead of the response content"
);
const responseContent = messageNode.querySelector(
"#response-panel .editor-row-container .CodeMirror"
);
ok(!responseContent, "Response content is really not displayed");
await waitForLazyRequests(hud.toolbox);
await closeToolbox();
});
async function doXhrAndExpand(hud) {
// Execute XHR and expand it after all network
// update events are received. Consequently,
// check out content of all (HTTP details) tabs.
const onMessage = waitForMessageByType(hud, XHR_URL, ".network");
const onRequestUpdates = waitForRequestUpdates(hud);
const onPayloadReady = waitForPayloadReady(hud);
// Fire an XHR POST request.
SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () {
content.wrappedJSObject.testXhrPostSlowResponse();
});
const { node: messageNode } = await onMessage;
ok(messageNode, "Network message found.");
await onRequestUpdates;
// Expand network log
await expandXhrMessage(messageNode);
const toggleButtonNode = messageNode.querySelector(".sidebar-toggle");
ok(!toggleButtonNode, "Sidebar toggle button shouldn't be shown");
await onPayloadReady;
return messageNode;
}
// Panel testing helpers
async function testNetworkMessage(toolbox, messageNode) {
await testStatusInfo(messageNode);
await testHeaders(messageNode);
await testCookies(messageNode);
await testRequest(messageNode);
await testResponse(messageNode);
await testTimings(messageNode);
await testStackTrace(messageNode);
await testSecurity(messageNode);
await waitForLazyRequests(toolbox);
}
// Status Info
function testStatusInfo(messageNode) {
const statusInfo = messageNode.querySelector(".status-info");
ok(statusInfo, "Status info is not empty");
}
// Headers
async function testHeaders(messageNode) {
const headersTab = messageNode.querySelector("#headers-tab");
ok(headersTab, "Headers tab is available");
// Select Headers tab and check the content.
headersTab.click();
await waitFor(
() => messageNode.querySelector("#headers-panel .headers-overview"),
"Wait for .header-overview to be rendered"
);
}
// Cookies
async function testCookies(messageNode) {
const cookiesTab = messageNode.querySelector("#cookies-tab");
ok(cookiesTab, "Cookies tab is available");
// Select tab and check the content.
cookiesTab.click();
await waitFor(
() => messageNode.querySelector("#cookies-panel .treeValueCell"),
"Wait for .treeValueCell to be rendered"
);
}
// Request
async function testRequest(messageNode) {
const requestTab = messageNode.querySelector("#request-tab");
ok(requestTab, "Request tab is available");
// Select Request tab and check the content. CodeMirror initialization
// is delayed to prevent UI freeze, so wait for a little while.
requestTab.click();
const requestPanel = messageNode.querySelector("#request-panel");
await waitForSourceEditor(requestPanel);
const requestContent = requestPanel.querySelector(
".panel-container .CodeMirror"
);
ok(requestContent, "Request content is available");
ok(
requestContent.textContent.includes("Hello world!"),
"Request POST body is correct"
);
}
// Response
async function testResponse(messageNode) {
const responseTab = messageNode.querySelector("#response-tab");
ok(responseTab, "Response tab is available");
// Select Response tab and check the content. CodeMirror initialization
// is delayed, so again wait for a little while.
responseTab.click();
const responsePanel = messageNode.querySelector("#response-panel");
await waitForSourceEditor(responsePanel);
const responseContent = messageNode.querySelector(
"#response-panel .editor-row-container .CodeMirror"
);
ok(responseContent, "Response content is available");
ok(responseContent.textContent, "Response text is available");
}
// Timings
async function testTimings(messageNode) {
const timingsTab = messageNode.querySelector("#timings-tab");
ok(timingsTab, "Timings tab is available");
// Select Timings tab and check the content.
timingsTab.click();
const timingsContent = await waitFor(() =>
messageNode.querySelector(
"#timings-panel .timings-container .timings-label",
"Wait for .timings-label to be rendered"
)
);
ok(timingsContent, "Timings content is available");
ok(timingsContent.textContent, "Timings text is available");
}
// Stack Trace
async function testStackTrace(messageNode) {
const stackTraceTab = messageNode.querySelector("#stack-trace-tab");
ok(stackTraceTab, "StackTrace tab is available");
// Select Stack Trace tab and check the content.
stackTraceTab.click();
await waitFor(
() => messageNode.querySelector("#stack-trace-panel .frame-link"),
"Wait for .frame-link to be rendered"
);
}
// Security
async function testSecurity(messageNode) {
const securityTab = messageNode.querySelector("#security-tab");
ok(securityTab, "Security tab is available");
// Select Security tab and check the content.
securityTab.click();
await waitFor(
() => messageNode.querySelector("#security-panel .treeTable .treeRow"),
"Wait for #security-panel .treeTable .treeRow to be rendered"
);
}
// Waiting helpers
async function waitForPayloadReady(hud) {
return hud.ui.once("network-request-payload-ready");
}
async function waitForSourceEditor(panel) {
return waitUntil(() => {
return !!panel.querySelector(".CodeMirror");
});
}
async function waitForRequestUpdates(hud) {
return hud.ui.once("network-messages-updated");
}
function expandXhrMessage(node) {
info(
"Click on XHR message and wait for the network detail panel to be displayed"
);
node.querySelector(".url").click();
return waitFor(
() => node.querySelector(".network-info"),
"Wait for .network-info to be rendered"
);
}