/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; // Test the script caches in the network monitor. async function do_test_script_cache(enableCache) { await SpecialPowers.pushPrefEnv({ set: [["dom.script_loader.experimental.navigation_cache", enableCache]], }); registerCleanupFunction(() => SpecialPowers.popPrefEnv()); const { monitor } = await initNetMonitor(SCRIPT_CACHE_URL, { enableCache: true, requestCount: 1, }); info("Starting test... "); const { document, store, windowRequire } = monitor.panelWin; const { getDisplayedRequests, getSortedRequests } = windowRequire( "devtools/client/netmonitor/src/selectors/index" ); const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); store.dispatch(Actions.batchEnable(false)); const waitForEvents = waitForNetworkEvents(monitor, 4); BrowserTestUtils.startLoadingURIString( gBrowser.selectedBrowser, SCRIPT_CACHE_URL ); await waitForEvents; const requests = document.querySelectorAll(".request-list-item"); is(requests.length, 4, "There should be 4 requests"); const requestData = { uri: HTTPS_EXAMPLE_URL + "sjs_test-script.sjs", details: { status: 200, statusText: "OK (cached)", displayedStatus: "cached", type: "js", fullMimeType: "text/javascript", }, }; is(requests[0].querySelector(".requests-list-type").textContent, "html"); // All script elements should create corresponding requests. for (let i = 1; i < requests.length; ++i) { const request = requests[i]; const requestsListStatus = request.querySelector(".status-code"); EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus); await waitUntil(() => requestsListStatus.title); await verifyRequestItemTarget( document, getDisplayedRequests(store.getState()), getSortedRequests(store.getState())[i], "GET", requestData.uri, requestData.details ); EventUtils.sendMouseEvent({ type: "mousedown" }, request); const wait = waitForDOM(document, "#responseHeaders"); clickOnSidebarTab(document, "headers"); await wait; const responseScope = document.querySelectorAll( "#headers-panel .accordion tr[id^='/responseHeaders']" ); const responseHeaders = [ { name: "cache-control", value: "max-age=10000", index: 1, }, { name: "connection", value: "close", index: 2, }, { name: "content-length", value: "29", index: 3, }, { name: "content-type", value: "text/javascript", index: 4, }, { name: "server", value: "httpd.js", index: 6, }, ]; responseHeaders.forEach(header => { is( responseScope[header.index - 1].querySelector(".treeLabel").innerHTML, header.name, `${header.name} label` ); is( responseScope[header.index - 1].querySelector(".objectBox").innerHTML, `${header.value}`, `${header.name} value` ); }); } await teardown(monitor); } add_task(async function test_script_cache_disabled() { await do_test_script_cache(false); }); add_task(async function test_script_cache_enabled() { await do_test_script_cache(true); }); /** * Importing the same module script multiple times within the same document * should not generate multiple fetch, regardless of whether the script cache * is used or not, and there should be only one request shown in the network * monitor. */ async function do_test_module_cache(enableCache) { await SpecialPowers.pushPrefEnv({ set: [["dom.script_loader.experimental.navigation_cache", enableCache]], }); registerCleanupFunction(() => SpecialPowers.popPrefEnv()); const { monitor } = await initNetMonitor(MODULE_SCRIPT_CACHE_URL, { enableCache: true, requestCount: 1, }); info("Starting test... "); const { document, store, windowRequire } = monitor.panelWin; const { getDisplayedRequests, getSortedRequests } = windowRequire( "devtools/client/netmonitor/src/selectors/index" ); const Actions = windowRequire("devtools/client/netmonitor/src/actions/index"); store.dispatch(Actions.batchEnable(false)); const waitForEvents = waitForNetworkEvents(monitor, 2); BrowserTestUtils.startLoadingURIString( gBrowser.selectedBrowser, MODULE_SCRIPT_CACHE_URL ); await waitForEvents; const requests = document.querySelectorAll(".request-list-item"); is(requests.length, 2, "There should be 2 requests"); const requestData = { uri: HTTPS_EXAMPLE_URL + "sjs_test-module-script.sjs", details: { status: 200, statusText: "OK (cached)", displayedStatus: "cached", type: "js", fullMimeType: "text/javascript", }, }; is(requests[0].querySelector(".requests-list-type").textContent, "html"); const request = requests[1]; const requestsListStatus = request.querySelector(".status-code"); EventUtils.sendMouseEvent({ type: "mouseover" }, requestsListStatus); await waitUntil(() => requestsListStatus.title); await verifyRequestItemTarget( document, getDisplayedRequests(store.getState()), getSortedRequests(store.getState())[1], "GET", requestData.uri, requestData.details ); EventUtils.sendMouseEvent({ type: "mousedown" }, request); const wait = waitForDOM(document, "#responseHeaders"); clickOnSidebarTab(document, "headers"); await wait; const responseScope = document.querySelectorAll( "#headers-panel .accordion tr[id^='/responseHeaders']" ); const responseHeaders = [ { name: "cache-control", value: "max-age=10000", index: 1, }, { name: "connection", value: "close", index: 2, }, { name: "content-length", value: "53", index: 3, }, { name: "content-type", value: "text/javascript", index: 4, }, { name: "server", value: "httpd.js", index: 6, }, ]; responseHeaders.forEach(header => { is( responseScope[header.index - 1].querySelector(".treeLabel").innerHTML, header.name, `${header.name} label` ); is( responseScope[header.index - 1].querySelector(".objectBox").innerHTML, `${header.value}`, `${header.name} value` ); }); await teardown(monitor); } add_task(async function test_module_cache_disabled() { await do_test_module_cache(false); }); add_task(async function test_module_cache_enabled() { await do_test_module_cache(true); });