/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at . */ "use strict"; /* * Test loading inline scripts from cache: * - Load document with inline script * - Reload inside debugger with toolbox caching disabled * - Reload inside debugger with toolbox caching enabled */ // Breakpoint position calculations can throw when interrupted by a navigation. PromiseTestUtils.allowMatchingRejectionsGlobally(/Resource .*? does not exist/); const server = createTestHTTPServer(); let docValue = 1; server.registerPathHandler("/inline-cache.html", (request, response) => { response.setHeader("Content-Type", "text/html"); // HTTP should assume cacheable by default. // Toolbox defaults to disabling cache for subsequent loads when open. response.setHeader("Cache-Control", "public, max-age=3600"); response.write(` `); }); const SOURCE_URL = `http://localhost:${ server.identity.primaryPort }/inline-cache.html`; add_task(async function() { info("Load document with inline script"); const tab = await addTab(SOURCE_URL); info("Open debugger"); clearDebuggerPreferences(); const toolbox = await openToolboxForTab(tab, "jsdebugger"); const dbg = createDebuggerContext(toolbox); info("Reload tab to ensure debugger finds script"); await reloadTabAndDebugger(tab, dbg); let pageValue = await getPageValue(tab); is(pageValue, "let x = 1;", "Content loads from network, has doc value 1"); await waitForSource(dbg, "inline-cache.html"); await selectSource(dbg, "inline-cache.html"); await waitForLoadedSource(dbg, "inline-cache.html"); let dbgValue = findSourceContent(dbg, "inline-cache.html"); info(`Debugger text: ${dbgValue.value}`); ok( dbgValue.value.includes(pageValue), "Debugger loads from cache, gets value 1 like page" ); info("Disable HTTP cache for page"); await toolbox.target.reconfigure({ options: { cacheDisabled: true } }); makeChanges(); info("Reload inside debugger with toolbox caching disabled (attempt 1)"); await reloadTabAndDebugger(tab, dbg); pageValue = await getPageValue(tab); is(pageValue, "let x = 2;", "Content loads from network, has doc value 2"); await waitForLoadedSource(dbg, "inline-cache.html"); dbgValue = findSourceContent(dbg, "inline-cache.html"); info(`Debugger text: ${dbgValue.value}`); ok( dbgValue.value.includes(pageValue), "Debugger loads from network, gets value 2 like page" ); makeChanges(); info("Reload inside debugger with toolbox caching disabled (attempt 2)"); await reloadTabAndDebugger(tab, dbg); pageValue = await getPageValue(tab); is(pageValue, "let x = 3;", "Content loads from network, has doc value 3"); await waitForLoadedSource(dbg, "inline-cache.html"); dbgValue = findSourceContent(dbg, "inline-cache.html"); info(`Debugger text: ${dbgValue.value}`); ok( dbgValue.value.includes(pageValue), "Debugger loads from network, gets value 3 like page" ); info("Enable HTTP cache for page"); await toolbox.target.reconfigure({ options: { cacheDisabled: false } }); makeChanges(); // Even though the HTTP cache is now enabled, Gecko sets the VALIDATE_ALWAYS flag when // reloading the page. So, it will always make a request to the server for the main // document contents. info("Reload inside debugger with toolbox caching enabled (attempt 1)"); await reloadTabAndDebugger(tab, dbg); pageValue = await getPageValue(tab); is(pageValue, "let x = 4;", "Content loads from network, has doc value 4"); await waitForLoadedSource(dbg, "inline-cache.html"); dbgValue = findSourceContent(dbg, "inline-cache.html"); info(`Debugger text: ${dbgValue.value}`); ok( dbgValue.value.includes(pageValue), "Debugger loads from cache, gets value 4 like page" ); makeChanges(); info("Reload inside debugger with toolbox caching enabled (attempt 2)"); await reloadTabAndDebugger(tab, dbg); pageValue = await getPageValue(tab); is(pageValue, "let x = 5;", "Content loads from network, has doc value 5"); await waitForLoadedSource(dbg, "inline-cache.html"); await waitForSelectedSource(dbg, "inline-cache.html"); dbgValue = findSourceContent(dbg, "inline-cache.html"); info(`Debugger text: ${dbgValue.value}`); ok( dbgValue.value.includes(pageValue), "Debugger loads from cache, gets value 5 like page" ); await toolbox.destroy(); await removeTab(tab); }); /** * This is meant to simulate the developer editing the inline source and saving. * Effectively, we change the source during the test at specific controlled points. */ function makeChanges() { docValue++; } function getPageValue(tab) { return SpecialPowers.spawn(tab.linkedBrowser, [], function() { return content.document.querySelector("script").textContent.trim(); }); } async function reloadTabAndDebugger(tab, dbg) { let navigated = waitForDispatch(dbg, "NAVIGATE"); let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser); await reload(dbg, "inline-cache.html"); return Promise.all([navigated, loaded]); }