/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; /** * Test that for delayed responses the network details are displayed * before the response is complete. */ function setupTestServer() { const httpServer = createTestHTTPServer(); httpServer.registerContentType("html", "text/html"); httpServer.registerPathHandler("/index.html", function (request, response) { response.setStatusLine(request.httpVersion, 200, "OK"); response.write( ` Test for delayed responses ` ); }); const { promise, resolve } = Promise.withResolvers(); let delayedResponse; httpServer.registerPathHandler( "/delayed-response", function (request, response) { response.processAsync(); delayedResponse = response; resolve(); } ); const resolveResponse = () => { delayedResponse.setStatusLine(delayedResponse.httpVersion, 200, "OK"); delayedResponse.setHeader("Content-Type", "text/plain", false); delayedResponse.write("Here is some content"); delayedResponse.finish(); }; return { httpServer, responseCreated: promise, resolveResponse }; } add_task(async function () { const { httpServer, responseCreated, resolveResponse } = setupTestServer(); const port = httpServer.identity.primaryPort; const { tab, monitor } = await initNetMonitor( `http://localhost:${port}/index.html`, { 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)); const URL = `http://localhost:${port}/delayed-response`; info("Start fetching delayed content"); const waitForRequest = waitUntil(() => document.querySelector(".request-list-item") ); SpecialPowers.spawn(tab.linkedBrowser, [URL], async url => { await content.wrappedJSObject.fetch(url); }); await Promise.all([responseCreated, waitForRequest]); let request = document.querySelector(".request-list-item"); // Should be available when the network event is created info("Assert that the URL is in the column"); is( request.querySelector(".requests-list-url")?.textContent, URL, "The URL of the request should be displayed" ); // Should be available on the `response start` event info("Assert that the status is not yet in the column"); is( request.querySelector(".requests-list-status-code")?.textContent, undefined, "The status of the request should not be displayed" ); info("Open the headers panel and check that the panel is not empty"); let waitForHeadersPanel = waitForDOM(document, "#headers-panel"); store.dispatch(Actions.toggleNetworkDetails()); EventUtils.sendMouseEvent({ type: "mousedown" }, request); await waitForHeadersPanel; info("Assert that the status is not yet in the column"); is( request.querySelector(".requests-list-status-code")?.textContent, undefined, "The status of the request should not yet be displayed" ); info("Wait for the response headers"); await waitForDOM(document, "#requestHeaders"); ok( !!document.querySelectorAll("#requestHeaders .treeRow").length, "The list of request headers should be visible" ); ok( !document.querySelectorAll("#responseHeaders .treeRow").length, "The list of response headers should not be visible yet" ); info("Open the response panel and wait for the response content"); let waitForResponsePanel = waitForDOM( document, "#response-panel .empty-notice" ); clickOnSidebarTab(document, "response"); await waitForResponsePanel; is( document.querySelector("#response-panel .empty-notice").innerText, "No response data available for this request", "The response text is not available yet" ); info("Switch back to the headers panel"); waitForHeadersPanel = waitForDOM(document, "#headers-panel"); clickOnSidebarTab(document, "headers"); await waitForHeadersPanel; info("Complete the response"); resolveResponse(); info("Wait for the response headers"); await waitForDOM(document, "#responseHeaders"); info("Assert that the status is now in the column"); request = document.querySelector(".request-list-item"); is( request.querySelector(".requests-list-status-code").textContent, "200", "The status of the request should be displayed" ); ok( !!document.querySelectorAll("#requestHeaders .treeRow").length, "The list of request headers should still be visible" ); ok( !!document.querySelectorAll("#responseHeaders .treeRow").length, "The list of response headers should now be visible" ); info("Open the response panel and wait for the response content"); waitForResponsePanel = waitForDOM(document, "#response-panel .cm-content"); clickOnSidebarTab(document, "response"); await waitForResponsePanel; is( getCodeMirrorValue(monitor), "Here is some content", "The text shown in the source editor is correct." ); await teardown(monitor); });