browser_net_script_cache.js (6732B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test the script caches in the network monitor. 7 async function do_test_script_cache(enableCache) { 8 await SpecialPowers.pushPrefEnv({ 9 set: [["dom.script_loader.experimental.navigation_cache", enableCache]], 10 }); 11 registerCleanupFunction(() => SpecialPowers.popPrefEnv()); 12 13 const { monitor } = await initNetMonitor(SCRIPT_CACHE_URL, { 14 enableCache: true, 15 requestCount: 1, 16 }); 17 info("Starting test... "); 18 19 const { document, store, windowRequire } = monitor.panelWin; 20 const { getDisplayedRequests, getSortedRequests } = windowRequire( 21 "devtools/client/netmonitor/src/selectors/index" 22 ); 23 const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); 24 store.dispatch(Actions.batchEnable(false)); 25 26 const waitForEvents = waitForNetworkEvents(monitor, 4); 27 28 BrowserTestUtils.startLoadingURIString( 29 gBrowser.selectedBrowser, 30 SCRIPT_CACHE_URL 31 ); 32 await waitForEvents; 33 34 const requests = document.querySelectorAll(".request-list-item"); 35 36 is(requests.length, 4, "There should be 4 requests"); 37 38 const requestData = { 39 uri: HTTPS_EXAMPLE_URL + "sjs_test-script.sjs", 40 details: { 41 status: 200, 42 statusText: "OK (cached)", 43 displayedStatus: "cached", 44 type: "js", 45 fullMimeType: "text/javascript", 46 }, 47 }; 48 49 is(requests[0].querySelector(".requests-list-type").textContent, "html"); 50 51 // All script elements should create corresponding requests. 52 for (let i = 1; i < requests.length; ++i) { 53 const request = requests[i]; 54 55 const requestsListStatus = request.querySelector(".status-code"); 56 EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus); 57 await waitUntil(() => requestsListStatus.title); 58 59 await verifyRequestItemTarget( 60 document, 61 getDisplayedRequests(store.getState()), 62 getSortedRequests(store.getState())[i], 63 "GET", 64 requestData.uri, 65 requestData.details 66 ); 67 68 EventUtils.sendMouseEvent({ type: "mousedown" }, request); 69 70 const wait = waitForDOM(document, "#responseHeaders"); 71 clickOnSidebarTab(document, "headers"); 72 await wait; 73 74 const responseScope = document.querySelectorAll( 75 "#headers-panel .accordion tr[id^='/responseHeaders']" 76 ); 77 78 const responseHeaders = [ 79 { 80 name: "cache-control", 81 value: "max-age=10000", 82 index: 1, 83 }, 84 { 85 name: "connection", 86 value: "close", 87 index: 2, 88 }, 89 { 90 name: "content-length", 91 value: "29", 92 index: 3, 93 }, 94 { 95 name: "content-type", 96 value: "text/javascript", 97 index: 4, 98 }, 99 { 100 name: "server", 101 value: "httpd.js", 102 index: 6, 103 }, 104 ]; 105 responseHeaders.forEach(header => { 106 is( 107 responseScope[header.index - 1].querySelector(".treeLabel").innerHTML, 108 header.name, 109 `${header.name} label` 110 ); 111 is( 112 responseScope[header.index - 1].querySelector(".objectBox").innerHTML, 113 `${header.value}`, 114 `${header.name} value` 115 ); 116 }); 117 } 118 await teardown(monitor); 119 } 120 121 add_task(async function test_script_cache_disabled() { 122 await do_test_script_cache(false); 123 }); 124 125 add_task(async function test_script_cache_enabled() { 126 await do_test_script_cache(true); 127 }); 128 129 /** 130 * Importing the same module script multiple times within the same document 131 * should not generate multiple fetch, regardless of whether the script cache 132 * is used or not, and there should be only one request shown in the network 133 * monitor. 134 */ 135 async function do_test_module_cache(enableCache) { 136 await SpecialPowers.pushPrefEnv({ 137 set: [["dom.script_loader.experimental.navigation_cache", enableCache]], 138 }); 139 registerCleanupFunction(() => SpecialPowers.popPrefEnv()); 140 141 const { monitor } = await initNetMonitor(MODULE_SCRIPT_CACHE_URL, { 142 enableCache: true, 143 requestCount: 1, 144 }); 145 info("Starting test... "); 146 147 const { document, store, windowRequire } = monitor.panelWin; 148 const { getDisplayedRequests, getSortedRequests } = windowRequire( 149 "devtools/client/netmonitor/src/selectors/index" 150 ); 151 const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); 152 store.dispatch(Actions.batchEnable(false)); 153 154 const waitForEvents = waitForNetworkEvents(monitor, 2); 155 156 BrowserTestUtils.startLoadingURIString( 157 gBrowser.selectedBrowser, 158 MODULE_SCRIPT_CACHE_URL 159 ); 160 await waitForEvents; 161 162 const requests = document.querySelectorAll(".request-list-item"); 163 164 is(requests.length, 2, "There should be 2 requests"); 165 166 const requestData = { 167 uri: HTTPS_EXAMPLE_URL + "sjs_test-module-script.sjs", 168 details: { 169 status: 200, 170 statusText: "OK (cached)", 171 displayedStatus: "cached", 172 type: "js", 173 fullMimeType: "text/javascript", 174 }, 175 }; 176 177 is(requests[0].querySelector(".requests-list-type").textContent, "html"); 178 179 const request = requests[1]; 180 181 const requestsListStatus = request.querySelector(".status-code"); 182 EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus); 183 await waitUntil(() => requestsListStatus.title); 184 185 await verifyRequestItemTarget( 186 document, 187 getDisplayedRequests(store.getState()), 188 getSortedRequests(store.getState())[1], 189 "GET", 190 requestData.uri, 191 requestData.details 192 ); 193 194 EventUtils.sendMouseEvent({ type: "mousedown" }, request); 195 196 const wait = waitForDOM(document, "#responseHeaders"); 197 clickOnSidebarTab(document, "headers"); 198 await wait; 199 200 const responseScope = document.querySelectorAll( 201 "#headers-panel .accordion tr[id^='/responseHeaders']" 202 ); 203 204 const responseHeaders = [ 205 { 206 name: "cache-control", 207 value: "max-age=10000", 208 index: 1, 209 }, 210 { 211 name: "connection", 212 value: "close", 213 index: 2, 214 }, 215 { 216 name: "content-length", 217 value: "53", 218 index: 3, 219 }, 220 { 221 name: "content-type", 222 value: "text/javascript", 223 index: 4, 224 }, 225 { 226 name: "server", 227 value: "httpd.js", 228 index: 6, 229 }, 230 ]; 231 responseHeaders.forEach(header => { 232 is( 233 responseScope[header.index - 1].querySelector(".treeLabel").innerHTML, 234 header.name, 235 `${header.name} label` 236 ); 237 is( 238 responseScope[header.index - 1].querySelector(".objectBox").innerHTML, 239 `${header.value}`, 240 `${header.name} value` 241 ); 242 }); 243 await teardown(monitor); 244 } 245 246 add_task(async function test_module_cache_disabled() { 247 await do_test_module_cache(false); 248 }); 249 250 add_task(async function test_module_cache_enabled() { 251 await do_test_module_cache(true); 252 });