browser_toolbox_backward_forward_navigation.js (6570B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // The test can take a while to run 7 requestLongerTimeout(3); 8 9 const FILENAME = "doc_backward_forward_navigation.html"; 10 const TEST_URI_ORG = `${URL_ROOT_ORG_SSL}${FILENAME}`; 11 const TEST_URI_COM = `${URL_ROOT_COM_SSL}${FILENAME}`; 12 13 Services.scriptloader.loadSubScript( 14 "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/shared-head.js", 15 this 16 ); 17 18 add_task(async function testMultipleNavigations() { 19 // Disable bfcache for Fission for now. 20 // If Fission is disabled, the pref is no-op. 21 await SpecialPowers.pushPrefEnv({ 22 set: [["fission.bfcacheInParent", false]], 23 }); 24 25 info( 26 "Test that DevTools works fine after multiple backward/forward navigations" 27 ); 28 // Don't show the third panel to limit the logs and activity. 29 await pushPref("devtools.inspector.three-pane-enabled", false); 30 await pushPref("devtools.inspector.activeSidebar", "ruleview"); 31 const DATA_URL = `data:text/html,<meta charset=utf8>`; 32 const tab = await addTab(DATA_URL); 33 34 // Select the debugger so there will be more activity 35 const toolbox = await openToolboxForTab(tab, "jsdebugger"); 36 const inspector = await toolbox.selectTool("inspector"); 37 38 info("Navigate to the ORG test page"); 39 // We don't use `navigateTo` as the page is adding stylesheets and js files which might 40 // delay the load event indefinitely (and we don't need for anything to be loaded, or 41 // ready, just to register the initial navigation so we can go back and forth between urls) 42 let onLocationChange = BrowserTestUtils.waitForLocationChange( 43 gBrowser, 44 TEST_URI_ORG 45 ); 46 BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URI_ORG); 47 await onLocationChange; 48 49 info("And then navigate to a different origin"); 50 onLocationChange = BrowserTestUtils.waitForLocationChange( 51 gBrowser, 52 TEST_URI_COM 53 ); 54 BrowserTestUtils.startLoadingURIString(gBrowser, TEST_URI_COM); 55 await onLocationChange; 56 57 info( 58 "Navigate backward and forward multiple times between the two origins, with different delays" 59 ); 60 await navigateBackAndForth(TEST_URI_ORG, TEST_URI_COM); 61 62 // Navigate one last time to a document with less activity so we don't have to deal 63 // with pending promises when we destroy the toolbox 64 const onInspectorReloaded = inspector.once("reloaded"); 65 info("Navigate to final document"); 66 await navigateTo(`${TEST_URI_ORG}?no-mutation`); 67 info("Waiting for inspector to reload…"); 68 await onInspectorReloaded; 69 info("-> inspector reloaded"); 70 await checkToolboxState(toolbox); 71 }); 72 73 add_task(async function testSingleBackAndForthInstantNavigation() { 74 // Disable bfcache for Fission for now. 75 // If Fission is disabled, the pref is no-op. 76 await SpecialPowers.pushPrefEnv({ 77 set: [["fission.bfcacheInParent", false]], 78 }); 79 80 info( 81 "Test that DevTools works fine after navigating backward and forward right after" 82 ); 83 84 // Don't show the third panel to limit the logs and activity. 85 await pushPref("devtools.inspector.three-pane-enabled", false); 86 await pushPref("devtools.inspector.activeSidebar", "ruleview"); 87 const DATA_URL = `data:text/html,<meta charset=utf8>`; 88 const tab = await addTab(DATA_URL); 89 90 // Select the debugger so there will be more activity 91 const toolbox = await openToolboxForTab(tab, "jsdebugger"); 92 const inspector = await toolbox.selectTool("inspector"); 93 94 info("Navigate to a different origin"); 95 await navigateTo(TEST_URI_COM); 96 97 info("Then navigate back, and forth immediatly"); 98 // We can't call goBack and right away goForward as goForward and even the call to navigateTo 99 // a bit later might be ignored. So we wait at least for the location to change. 100 await safelyGoBack(DATA_URL); 101 await safelyGoForward(TEST_URI_COM); 102 103 // Navigate one last time to a document with less activity so we don't have to deal 104 // with pending promises when we destroy the toolbox 105 const onInspectorReloaded = inspector.once("reloaded"); 106 info("Navigate to final document"); 107 await navigateTo(`${TEST_URI_ORG}?no-mutation`); 108 info("Waiting for inspector to reload…"); 109 await onInspectorReloaded; 110 info("-> inspector reloaded"); 111 await checkToolboxState(toolbox); 112 }); 113 114 async function checkToolboxState(toolbox) { 115 info("Check that the toolbox toolbar is still visible"); 116 const toolboxTabsEl = toolbox.doc.querySelector(".toolbox-tabs"); 117 ok(toolboxTabsEl, "Toolbar is still visible"); 118 119 info( 120 "Check that the markup view is rendered correctly and elements can be selected" 121 ); 122 const inspector = await toolbox.selectTool("inspector"); 123 await waitFor( 124 () => 125 inspector.markup && 126 inspector.markup.win.document.body.innerText.includes( 127 `<body class="no-mutation">` 128 ), 129 `wait for <body class="no-mutation"> to be displayed in the markup view, got: ${inspector.markup?.win.document.body.innerText}`, 130 100, 131 100 132 ); 133 ok(true, "the markup view is still rendered fine"); 134 await selectNode("ul.logs", inspector); 135 ok(true, "Nodes can be selected"); 136 137 info("Check that the debugger has some sources"); 138 const dbgPanel = await toolbox.selectTool("jsdebugger"); 139 const dbg = createDebuggerContext(toolbox); 140 141 info(`Wait for ${FILENAME} to be displayed in the debugger source panel`); 142 const rootNode = await waitFor(() => 143 dbgPanel.panelWin.document.querySelector(selectors.sourceTreeRootNode) 144 ); 145 await expandAllSourceNodes(dbg, rootNode); 146 const sourcesTreeScriptNode = await waitFor(() => 147 findSourceNodeWithText(dbg, FILENAME) 148 ); 149 150 ok( 151 sourcesTreeScriptNode.innerText.includes(FILENAME), 152 "The debugger has the expected source" 153 ); 154 } 155 156 async function navigateBackAndForth( 157 expectedUrlAfterBackwardNavigation, 158 expectedUrlAfterForwardNavigation 159 ) { 160 const delays = [100, 0, 500]; 161 for (const delay of delays) { 162 // For each delays, do 3 back/forth navigations 163 for (let i = 0; i < 3; i++) { 164 await safelyGoBack(expectedUrlAfterBackwardNavigation); 165 await wait(delay); 166 await safelyGoForward(expectedUrlAfterForwardNavigation); 167 await wait(delay); 168 } 169 } 170 } 171 172 async function safelyGoBack(expectedUrl) { 173 const onLocationChange = BrowserTestUtils.waitForLocationChange( 174 gBrowser, 175 expectedUrl 176 ); 177 gBrowser.goBack(); 178 await onLocationChange; 179 } 180 181 async function safelyGoForward(expectedUrl) { 182 const onLocationChange = BrowserTestUtils.waitForLocationChange( 183 gBrowser, 184 expectedUrl 185 ); 186 gBrowser.goForward(); 187 await onLocationChange; 188 }