diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /devtools/client/netmonitor/test/browser_net_resend.js | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/netmonitor/test/browser_net_resend.js')
-rw-r--r-- | devtools/client/netmonitor/test/browser_net_resend.js | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/devtools/client/netmonitor/test/browser_net_resend.js b/devtools/client/netmonitor/test/browser_net_resend.js new file mode 100644 index 0000000000..01940195f7 --- /dev/null +++ b/devtools/client/netmonitor/test/browser_net_resend.js @@ -0,0 +1,385 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Tests if resending a request works. + */ + +add_task(async function () { + if ( + Services.prefs.getBoolPref( + "devtools.netmonitor.features.newEditAndResend", + true + ) + ) { + await testResendRequest(); + } else { + await testOldEditAndResendPanel(); + } +}); + +// This tests resending a request without editing using +// the resend context menu item. This particularly covering +// the new resend functionality. +async function testResendRequest() { + const { tab, monitor } = await initNetMonitor(POST_DATA_URL, { + requestCount: 1, + }); + info("Starting test... "); + + const { document, store, windowRequire } = monitor.panelWin; + + // Action should be processed synchronously in tests. + const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); + store.dispatch(Actions.batchEnable(false)); + + await performRequests(monitor, tab, 2); + + is( + document.querySelectorAll(".request-list-item").length, + 2, + "There are currently two requests" + ); + + const firstResend = await resendRequestAndWaitForNewRequest( + monitor, + document.querySelectorAll(".request-list-item")[0] + ); + + ok( + firstResend.originalResource.resourceId !== + firstResend.newResource.resourceId, + "The resent request is different resource from the first request" + ); + + is( + firstResend.originalResource.url, + firstResend.newResource.url, + "The resent request has the same url and query parameters and the first request" + ); + + is( + firstResend.originalResource.requestHeaders.headers.length, + firstResend.newResource.requestHeaders.headers.length, + "The no of headers are the same" + ); + + firstResend.originalResource.requestHeaders.headers.forEach( + ({ name, value }) => { + const foundHeader = firstResend.newResource.requestHeaders.headers.find( + header => header.name == name + ); + is( + value, + foundHeader.value, + `The '${name}' header for the request and the resent request match` + ); + } + ); + + info("Check that the custom headers and form data are resent correctly"); + const secondResend = await resendRequestAndWaitForNewRequest( + monitor, + document.querySelectorAll(".request-list-item")[1] + ); + + ok( + secondResend.originalResource.resourceId !== + secondResend.newResource.resourceId, + "The resent request is different resource from the second request" + ); + + const customHeader = + secondResend.originalResource.requestHeaders.headers.find( + header => header.name == "custom-header-xxx" + ); + + const customHeaderInResentRequest = + secondResend.newResource.requestHeaders.headers.find( + header => header.name == "custom-header-xxx" + ); + + is( + customHeader.value, + customHeaderInResentRequest.value, + "The custom header in the resent request is the same as the second request" + ); + + is( + customHeaderInResentRequest.value, + "custom-value-xxx", + "The custom header in the resent request is correct" + ); + + is( + secondResend.originalResource.requestPostData.postData.text, + secondResend.newResource.requestPostData.postData.text, + "The form data in the resent is the same as the second request" + ); +} + +async function resendRequestAndWaitForNewRequest(monitor, originalRequestItem) { + const { document, store, windowRequire, connector } = monitor.panelWin; + const { getSelectedRequest, getDisplayedRequests } = windowRequire( + "devtools/client/netmonitor/src/selectors/index" + ); + + info("Select the request to resend"); + const expectedNoOfRequestsAfterResend = + getDisplayedRequests(store.getState()).length + 1; + + const waitForHeaders = waitUntil(() => + document.querySelector(".headers-overview") + ); + EventUtils.sendMouseEvent({ type: "mousedown" }, originalRequestItem); + await waitForHeaders; + + const originalResourceId = getSelectedRequest(store.getState()).id; + + const waitForNewRequest = waitUntil( + () => + getDisplayedRequests(store.getState()).length == + expectedNoOfRequestsAfterResend && + getSelectedRequest(store.getState()).id !== originalResourceId + ); + + info("Open the context menu and select the resend for the request"); + EventUtils.sendMouseEvent({ type: "contextmenu" }, originalRequestItem); + await selectContextMenuItem(monitor, "request-list-context-resend-only"); + await waitForNewRequest; + + const newResourceId = getSelectedRequest(store.getState()).id; + + // Make sure we fetch the request headers and post data for the + // new request so we can assert them. + await connector.requestData(newResourceId, "requestHeaders"); + await connector.requestData(newResourceId, "requestPostData"); + + return { + originalResource: getRequestById(store.getState(), originalResourceId), + newResource: getRequestById(store.getState(), newResourceId), + }; +} + +// This is a basic test for the old edit and resend panel +// This should be removed soon in Bug 1745416 when we remove +// the old panel functionality. +async function testOldEditAndResendPanel() { + const ADD_QUERY = "t1=t2"; + const ADD_HEADER = "Test-header: true"; + const ADD_UA_HEADER = "User-Agent: Custom-Agent"; + const ADD_POSTDATA = "&t3=t4"; + + const { tab, monitor } = await initNetMonitor(POST_DATA_URL, { + requestCount: 1, + }); + info("Starting test... "); + + const { document, store, windowRequire } = monitor.panelWin; + const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); + const { getSelectedRequest, getSortedRequests } = windowRequire( + "devtools/client/netmonitor/src/selectors/index" + ); + + store.dispatch(Actions.batchEnable(false)); + + // Execute requests. + await performRequests(monitor, tab, 2); + + const origItemId = getSortedRequests(store.getState())[0].id; + + store.dispatch(Actions.selectRequest(origItemId)); + await waitForRequestData( + store, + ["requestHeaders", "requestPostData"], + origItemId + ); + + let origItem = getSortedRequests(store.getState())[0]; + + // add a new custom request cloned from selected request + + store.dispatch(Actions.cloneSelectedRequest()); + await testCustomForm(origItem); + + let customItem = getSelectedRequest(store.getState()); + testCustomItem(customItem, origItem); + + // edit the custom request + await editCustomForm(); + + // FIXME: reread the customItem, it's been replaced by a new object (immutable!) + customItem = getSelectedRequest(store.getState()); + testCustomItemChanged(customItem, origItem); + + // send the new request + const wait = waitForNetworkEvents(monitor, 1); + store.dispatch(Actions.sendCustomRequest()); + await wait; + + let sentItem; + // Testing sent request will require updated requestHeaders and requestPostData, + // we must wait for both properties get updated before starting test. + await waitUntil(() => { + sentItem = getSelectedRequest(store.getState()); + origItem = getSortedRequests(store.getState())[0]; + return ( + sentItem && + sentItem.requestHeaders && + sentItem.requestPostData && + origItem && + origItem.requestHeaders && + origItem.requestPostData + ); + }); + + await testSentRequest(sentItem, origItem); + + // Ensure the UI shows the new request, selected, and that the detail panel was closed. + is( + getSortedRequests(store.getState()).length, + 3, + "There are 3 requests shown" + ); + is( + document + .querySelector(".request-list-item.selected") + .getAttribute("data-id"), + sentItem.id, + "The sent request is selected" + ); + is( + document.querySelector(".network-details-bar"), + null, + "The detail panel is hidden" + ); + + await teardown(monitor); + + function testCustomItem(item, orig) { + is( + item.method, + orig.method, + "item is showing the same method as original request" + ); + is(item.url, orig.url, "item is showing the same URL as original request"); + } + + function testCustomItemChanged(item, orig) { + const { url } = item; + const expectedUrl = orig.url + "&" + ADD_QUERY; + + is(url, expectedUrl, "menu item is updated to reflect url entered in form"); + } + + /* + * Test that the New Request form was populated correctly + */ + async function testCustomForm(data) { + await waitUntil(() => document.querySelector(".custom-request-panel")); + is( + document.getElementById("custom-method-value").value, + data.method, + "new request form showing correct method" + ); + + is( + document.getElementById("custom-url-value").value, + data.url, + "new request form showing correct url" + ); + + const query = document.getElementById("custom-query-value"); + is( + query.value, + "foo=bar\nbaz=42\ntype=urlencoded", + "new request form showing correct query string" + ); + + const headers = document + .getElementById("custom-headers-value") + .value.split("\n"); + for (const { name, value } of data.requestHeaders.headers) { + ok( + headers.includes(name + ": " + value), + "form contains header from request" + ); + } + + const postData = document.getElementById("custom-postdata-value"); + is( + postData.value, + data.requestPostData.postData.text, + "new request form showing correct post data" + ); + } + + /* + * Add some params and headers to the request form + */ + async function editCustomForm() { + monitor.panelWin.focus(); + + const query = document.getElementById("custom-query-value"); + const queryFocus = once(query, "focus", false); + // Bug 1195825: Due to some unexplained dark-matter with promise, + // focus only works if delayed by one tick. + query.setSelectionRange(query.value.length, query.value.length); + executeSoon(() => query.focus()); + await queryFocus; + + // add params to url query string field + typeInNetmonitor(["VK_RETURN"], monitor); + typeInNetmonitor(ADD_QUERY, monitor); + + const headers = document.getElementById("custom-headers-value"); + const headersFocus = once(headers, "focus", false); + headers.setSelectionRange(headers.value.length, headers.value.length); + headers.focus(); + await headersFocus; + + // add a header + typeInNetmonitor(["VK_RETURN"], monitor); + typeInNetmonitor(ADD_HEADER, monitor); + + // add a User-Agent header, to check if default headers can be modified + // (there will be two of them, first gets overwritten by the second) + typeInNetmonitor(["VK_RETURN"], monitor); + typeInNetmonitor(ADD_UA_HEADER, monitor); + + const postData = document.getElementById("custom-postdata-value"); + const postFocus = once(postData, "focus", false); + postData.setSelectionRange(postData.value.length, postData.value.length); + postData.focus(); + await postFocus; + + // add to POST data once textarea has updated + await waitUntil(() => postData.textContent !== ""); + typeInNetmonitor(ADD_POSTDATA, monitor); + } + + /* + * Make sure newly created event matches expected request + */ + async function testSentRequest(data, origData) { + is(data.method, origData.method, "correct method in sent request"); + is(data.url, origData.url + "&" + ADD_QUERY, "correct url in sent request"); + + const { headers } = data.requestHeaders; + const hasHeader = headers.some(h => `${h.name}: ${h.value}` == ADD_HEADER); + ok(hasHeader, "new header added to sent request"); + + const hasUAHeader = headers.some( + h => `${h.name}: ${h.value}` == ADD_UA_HEADER + ); + ok(hasUAHeader, "User-Agent header added to sent request"); + + is( + data.requestPostData.postData.text, + origData.requestPostData.postData.text + ADD_POSTDATA, + "post data added to sent request" + ); + } +} |