browser_webconsole_network_messages_expand.js (7968B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const TEST_FILE = "test-network-request.html"; 7 const TEST_PATH = 8 "https://example.com/browser/devtools/client/webconsole/test/browser/"; 9 const TEST_URI = TEST_PATH + TEST_FILE; 10 const XHR_URL = TEST_PATH + "sjs_slow-response-test-server.sjs"; 11 12 requestLongerTimeout(2); 13 14 registerCleanupFunction(async function () { 15 await new Promise(resolve => { 16 Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL, () => 17 resolve() 18 ); 19 }); 20 }); 21 22 pushPref("devtools.webconsole.filter.net", false); 23 pushPref("devtools.webconsole.filter.netxhr", true); 24 25 /** 26 * Main test for checking HTTP logs in the Console panel. 27 */ 28 add_task(async function task() { 29 const hud = await openNewTabAndConsole(TEST_URI); 30 31 const messageNode = await doXhrAndExpand(hud); 32 33 await testNetworkMessage(hud.toolbox, messageNode); 34 35 await closeToolboxIfOpen(); 36 }); 37 38 add_task(async function task() { 39 info( 40 "Verify that devtools.netmonitor.saveRequestAndResponseBodies=false disable response content collection" 41 ); 42 await pushPref("devtools.netmonitor.saveRequestAndResponseBodies", false); 43 const hud = await openNewTabAndConsole(TEST_URI); 44 45 const messageNode = await doXhrAndExpand(hud); 46 47 const responseTab = messageNode.querySelector("#response-tab"); 48 ok(responseTab, "Response tab is available"); 49 50 const { 51 TEST_EVENTS, 52 } = require("resource://devtools/client/netmonitor/src/constants.js"); 53 const onResponseContent = hud.ui.once(TEST_EVENTS.RECEIVED_RESPONSE_CONTENT); 54 // Select Response tab and check the content. 55 responseTab.click(); 56 57 // Even if response content aren't collected by NetworkObserver, 58 // we do try to fetch the content via an RDP request, which 59 // we try to wait for here. 60 info("Wait for the async getResponseContent request"); 61 await onResponseContent; 62 const responsePanel = messageNode.querySelector("#response-panel"); 63 64 // This is updated only after we tried to fetch the response content 65 // and fired the getResponseContent request 66 info("Wait for the empty response content"); 67 ok( 68 responsePanel.querySelector("div.empty-notice"), 69 "An empty notice is displayed instead of the response content" 70 ); 71 const responseContent = messageNode.querySelector( 72 "#response-panel .editor-row-container .CodeMirror" 73 ); 74 ok(!responseContent, "Response content is really not displayed"); 75 76 await waitForLazyRequests(hud.toolbox); 77 await closeToolboxIfOpen(); 78 }); 79 80 async function doXhrAndExpand(hud) { 81 // Execute XHR and expand it after all network 82 // update events are received. Consequently, 83 // check out content of all (HTTP details) tabs. 84 const onMessage = waitForMessageByType(hud, XHR_URL, ".network"); 85 const onRequestUpdates = waitForRequestUpdates(hud); 86 const onPayloadReady = waitForPayloadReady(hud); 87 88 // Fire an XHR POST request. 89 SpecialPowers.spawn(gBrowser.selectedBrowser, [], function () { 90 content.wrappedJSObject.testXhrPostSlowResponse(); 91 }); 92 93 const { node: messageNode } = await onMessage; 94 ok(messageNode, "Network message found."); 95 96 await onRequestUpdates; 97 98 // Expand network log 99 await expandXhrMessage(messageNode); 100 101 const toggleButtonNode = messageNode.querySelector(".sidebar-toggle"); 102 ok(!toggleButtonNode, "Sidebar toggle button shouldn't be shown"); 103 104 await onPayloadReady; 105 106 return messageNode; 107 } 108 109 // Panel testing helpers 110 111 async function testNetworkMessage(toolbox, messageNode) { 112 await testStatusInfo(messageNode); 113 await testHeaders(messageNode); 114 await testCookies(messageNode); 115 await testRequest(messageNode); 116 await testResponse(messageNode); 117 await testTimings(messageNode); 118 await testStackTrace(messageNode); 119 await testSecurity(messageNode); 120 await waitForLazyRequests(toolbox); 121 } 122 123 // Status Info 124 125 function testStatusInfo(messageNode) { 126 const statusInfo = messageNode.querySelector(".status-info"); 127 ok(statusInfo, "Status info is not empty"); 128 } 129 130 // Headers 131 async function testHeaders(messageNode) { 132 const headersTab = messageNode.querySelector("#headers-tab"); 133 ok(headersTab, "Headers tab is available"); 134 135 // Select Headers tab and check the content. 136 headersTab.click(); 137 await waitFor( 138 () => messageNode.querySelector("#headers-panel .headers-overview"), 139 "Wait for .header-overview to be rendered" 140 ); 141 } 142 143 // Cookies 144 async function testCookies(messageNode) { 145 const cookiesTab = messageNode.querySelector("#cookies-tab"); 146 ok(cookiesTab, "Cookies tab is available"); 147 148 // Select tab and check the content. 149 cookiesTab.click(); 150 await waitFor( 151 () => messageNode.querySelector("#cookies-panel .treeValueCell"), 152 "Wait for .treeValueCell to be rendered" 153 ); 154 } 155 156 // Request 157 async function testRequest(messageNode) { 158 const requestTab = messageNode.querySelector("#request-tab"); 159 ok(requestTab, "Request tab is available"); 160 161 // Select Request tab and check the content. CodeMirror initialization 162 // is delayed to prevent UI freeze, so wait for a little while. 163 requestTab.click(); 164 const requestPanel = messageNode.querySelector("#request-panel"); 165 await waitForSourceEditor(requestPanel); 166 const requestContent = requestPanel.querySelector( 167 ".panel-container .cm-editor" 168 ); 169 ok(requestContent, "Request content is available"); 170 ok( 171 requestContent.textContent.includes("Hello world!"), 172 "Request POST body is correct" 173 ); 174 } 175 176 // Response 177 async function testResponse(messageNode) { 178 const responseTab = messageNode.querySelector("#response-tab"); 179 ok(responseTab, "Response tab is available"); 180 181 // Select Response tab and check the content. CodeMirror initialization 182 // is delayed, so again wait for a little while. 183 responseTab.click(); 184 const responsePanel = messageNode.querySelector("#response-panel"); 185 await waitForSourceEditor(responsePanel); 186 const responseContent = messageNode.querySelector( 187 "#response-panel .editor-row-container .cm-editor" 188 ); 189 ok(responseContent, "Response content is available"); 190 ok(responseContent.textContent, "Response text is available"); 191 } 192 193 // Timings 194 async function testTimings(messageNode) { 195 const timingsTab = messageNode.querySelector("#timings-tab"); 196 ok(timingsTab, "Timings tab is available"); 197 198 // Select Timings tab and check the content. 199 timingsTab.click(); 200 const timingsContent = await waitFor(() => 201 messageNode.querySelector( 202 "#timings-panel .timings-container .timings-label", 203 "Wait for .timings-label to be rendered" 204 ) 205 ); 206 ok(timingsContent, "Timings content is available"); 207 ok(timingsContent.textContent, "Timings text is available"); 208 } 209 210 // Stack Trace 211 async function testStackTrace(messageNode) { 212 const stackTraceTab = messageNode.querySelector("#stack-trace-tab"); 213 ok(stackTraceTab, "StackTrace tab is available"); 214 215 // Select Stack Trace tab and check the content. 216 stackTraceTab.click(); 217 await waitFor( 218 () => messageNode.querySelector("#stack-trace-panel .frame-link"), 219 "Wait for .frame-link to be rendered" 220 ); 221 } 222 223 // Security 224 async function testSecurity(messageNode) { 225 const securityTab = messageNode.querySelector("#security-tab"); 226 ok(securityTab, "Security tab is available"); 227 228 // Select Security tab and check the content. 229 securityTab.click(); 230 await waitFor( 231 () => messageNode.querySelector("#security-panel .treeTable .treeRow"), 232 "Wait for #security-panel .treeTable .treeRow to be rendered" 233 ); 234 } 235 236 // Waiting helpers 237 238 async function waitForPayloadReady(hud) { 239 return hud.ui.once("network-request-payload-ready"); 240 } 241 242 async function waitForRequestUpdates(hud) { 243 return hud.ui.once("network-messages-updated"); 244 } 245 246 function expandXhrMessage(node) { 247 info( 248 "Click on XHR message and wait for the network detail panel to be displayed" 249 ); 250 node.querySelector(".url").click(); 251 return waitFor( 252 () => node.querySelector(".network-info"), 253 "Wait for .network-info to be rendered" 254 ); 255 }