Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test gets skipped with pattern: http3 OR http2
- Manifest: devtools/client/netmonitor/test/browser.toml
/* Any copyright is dedicated to the Public Domain.
"use strict";
/**
* Tests if the POST requests display the correct information in the UI,
* for raw payloads with content-type headers attached to the upload stream.
*/
add_task(async function () {
const {
L10N,
} = require("resource://devtools/client/netmonitor/src/utils/l10n.js");
const { tab, monitor } = await initNetMonitor(POST_RAW_WITH_HEADERS_URL, {
requestCount: 1,
});
info("Starting test... ");
const { document, store, windowRequire } = monitor.panelWin;
const Actions = windowRequire("devtools/client/netmonitor/src/actions/index");
store.dispatch(Actions.batchEnable(false));
// Execute requests.
await performRequests(monitor, tab, 3);
const expectedRequestsContent = [
{
headersFromUploadSectionTitle:
"Request headers from upload stream (47 B)",
uploadSectionHeaders: [
{ label: "content-type", value: "application/x-www-form-urlencoded" },
],
uploadSectionRawText: "content-type: application/x-www-form-urlencoded",
requestPanelFormData: [
{ label: "foo", value: '"bar"' },
{ label: "baz", value: '"123"' },
],
requestPanelPayload: [
"content-type: application/x-www-form-urlencoded",
"foo=bar&baz=123",
],
},
{
headersFromUploadSectionTitle:
"Request headers from upload stream (47 B)",
uploadSectionHeaders: [
{ label: "content-type", value: "application/x-www-form-urlencoded" },
],
uploadSectionRawText: "content-type: application/x-www-form-urlencoded",
requestPanelPayload: ["content-type: application/x-www-form-urlencoded"],
},
{
headersFromUploadSectionTitle:
"Request headers from upload stream (74 B)",
uploadSectionHeaders: [
{ label: "content-type", value: "application/x-www-form-urlencoded" },
{ label: "custom-header", value: "hello world!" },
],
uploadSectionRawText:
"content-type: application/x-www-form-urlencoded\r\ncustom-header: hello world!",
requestPanelFormData: [
{ label: "foo", value: '"bar"' },
{ label: "baz", value: '"123"' },
],
requestPanelPayload: [
"content-type: application/x-www-form-urlencoded",
"custom-header: hello world!",
"foo=bar&baz=123",
],
},
];
const requests = document.querySelectorAll(".request-list-item");
store.dispatch(Actions.toggleNetworkDetails());
for (let i = 0; i < expectedRequestsContent.length; i++) {
EventUtils.sendMouseEvent({ type: "mousedown" }, requests[i]);
await assertRequestContentInHeaderAndRequestSidePanels(
expectedRequestsContent[i]
);
}
async function assertRequestContentInHeaderAndRequestSidePanels(expected) {
// Wait for all 3 headers sections to load (Response Headers, Request Headers, Request headers from upload stream)
let wait = waitForDOM(document, "#headers-panel .accordion-item", 3);
clickOnSidebarTab(document, "headers");
await wait;
let tabpanel = document.querySelector("#headers-panel");
is(
tabpanel.querySelectorAll(".accordion-item").length,
3,
"There should be 3 header sections displayed in this tabpanel."
);
info("Check that the Headers in the upload stream section are correct.");
is(
tabpanel.querySelectorAll(".accordion-item .accordion-header-label")[2]
.textContent,
expected.headersFromUploadSectionTitle,
"The request headers from upload section doesn't have the correct title."
);
let labels = tabpanel.querySelectorAll(
".accordion-item:last-child .accordion-content tr .treeLabelCell .treeLabel"
);
let values = tabpanel.querySelectorAll(
".accordion-item:last-child .accordion-content tr .treeValueCell .objectBox"
);
for (let i = 0; i < labels.length; i++) {
is(
labels[i].textContent,
expected.uploadSectionHeaders[i].label,
"The request header name was incorrect."
);
is(
values[i].textContent,
expected.uploadSectionHeaders[i].value,
"The request header value was incorrect."
);
}
info(
"Toggle to open the raw view for the request headers from upload stream"
);
wait = waitForDOM(
tabpanel,
".accordion-item:last-child .accordion-content .raw-headers-container"
);
tabpanel.querySelector("#raw-upload-checkbox").click();
await wait;
const rawTextArea = tabpanel.querySelector(
".accordion-item:last-child .accordion-content .raw-headers"
);
is(
rawTextArea.textContent,
expected.uploadSectionRawText,
"The raw text for the request headers from upload section is correct"
);
info("Switch to the Request panel");
wait = waitForDOM(document, "#request-panel .panel-container");
clickOnSidebarTab(document, "request");
await wait;
tabpanel = document.querySelector("#request-panel");
if (expected.requestPanelFormData) {
await waitUntil(
() =>
tabpanel.querySelector(".data-label").textContent ==
L10N.getStr("paramsFormData")
);
labels = tabpanel.querySelectorAll("tr .treeLabelCell .treeLabel");
values = tabpanel.querySelectorAll("tr .treeValueCell .objectBox");
for (let i = 0; i < labels.length; i++) {
is(
labels[i].textContent,
expected.requestPanelFormData[i].label,
"The form data param name was incorrect."
);
is(
values[i].textContent,
expected.requestPanelFormData[i].value,
"The form data param value was incorrect."
);
}
info("Toggle open the the request payload raw view");
tabpanel.querySelector("#raw-request-checkbox").click();
}
await waitUntil(
() =>
tabpanel.querySelector(".data-label").textContent ==
L10N.getStr("paramsPostPayload") &&
tabpanel.querySelector(
".panel-container .editor-row-container .CodeMirror-code"
)
);
// Check that the expected header lines are included in the codemirror
// text.
const actualText = tabpanel.querySelector(
".panel-container .editor-row-container .CodeMirror-code"
).textContent;
const requestPayloadIsCorrect = expected.requestPanelPayload.every(
content => actualText.includes(content)
);
is(requestPayloadIsCorrect, true, "The request payload is not correct");
}
return teardown(monitor);
});