browser_net_overrides.js (11627B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // This test might take a very long time on slow platforms such as TSAN. 7 requestLongerTimeout(2); 8 9 /* import-globals-from network-overrides-test-helpers.js */ 10 Services.scriptloader.loadSubScript( 11 CHROME_URL_ROOT + "network-overrides-test-helpers.js", 12 this 13 ); 14 15 function clearMemoryCache(browser) { 16 info("Clearing subresource cache"); 17 return SpecialPowers.spawn(browser, [], () => { 18 ChromeUtils.clearResourceCache(); 19 }); 20 } 21 22 /** 23 * Test adding and removing overrides for three resources: 24 * - HTML file 25 * - JS file 26 * - CSS file 27 */ 28 29 async function testHTMLOverrideWithOptions(options) { 30 const { monitor, tab, document } = await setupNetworkOverridesTest(options); 31 32 let htmlRequest = findRequestByInitiator(document, "document"); 33 ok( 34 !htmlRequest.querySelector(".requests-list-override"), 35 "There is no override cell" 36 ); 37 await assertOverrideColumnStatus(monitor, { visible: false }); 38 39 info("Set a network override for the HTML request"); 40 const overrideFileName = `index-override.html`; 41 const overridePath = await setNetworkOverride( 42 monitor, 43 htmlRequest, 44 overrideFileName, 45 OVERRIDDEN_HTML 46 ); 47 48 // Assert override column is checked but disabled in context menu 49 await assertOverrideColumnStatus(monitor, { visible: true }); 50 51 // Assert override is only displayed for appropriate request 52 assertOverrideCellStatus(htmlRequest, { overridden: true }); 53 const overrideCell = htmlRequest.querySelector(".requests-list-override"); 54 ok( 55 overrideCell.getAttribute("title").includes(overrideFileName), 56 "The override icon's title contains the overridden path" 57 ); 58 59 const scriptRequest = findRequestByInitiator(document, "script"); 60 assertOverrideCellStatus(scriptRequest, { overridden: false }); 61 const stylesheetRequest = findRequestByInitiator(document, "stylesheet"); 62 assertOverrideCellStatus(stylesheetRequest, { overridden: false }); 63 64 info("Reloading to check override is applied on the page"); 65 let waitForEvents = waitForNetworkEvents(monitor, 1); 66 tab.linkedBrowser.reload(); 67 await waitForEvents; 68 69 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 70 ok(content.document.body.textContent.includes("Overridden content")); 71 }); 72 73 htmlRequest = findRequestByInitiator(document, "document"); 74 // If the HTML file was properly overridden, reloading the page should only 75 // create one request, because there is no longer any JS or CSS file loaded 76 // by the overridden HTML response. 77 is( 78 document.querySelectorAll(".request-list-item").length, 79 1, 80 "Only one request (html file) - no additional script or stylesheet" 81 ); 82 83 // Assert Response Tab shows the appropriate content 84 await assertOverriddenResponseTab(document, htmlRequest, overridePath); 85 86 // Remove Network override 87 await removeNetworkOverride(monitor, htmlRequest); 88 89 await assertOverrideColumnStatus(monitor, { visible: false }); 90 ok( 91 !htmlRequest.querySelector(".requests-list-override"), 92 "There is no override cell" 93 ); 94 95 info("Reload again to check the override is no longer applied on the page"); 96 waitForEvents = waitForNetworkEvents(monitor, 3); 97 tab.linkedBrowser.reload(); 98 await waitForEvents; 99 100 is( 101 document.querySelectorAll(".request-list-item").length, 102 3, 103 "3 requests displayed after removing the override and reloading" 104 ); 105 106 // Assert HTML content is back to normal 107 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 108 ok(content.document.body.textContent.includes("Original content")); 109 }); 110 111 return teardown(monitor); 112 } 113 114 add_task(async function testHTMLOverrideWithoutCache() { 115 await testHTMLOverrideWithOptions({ enableCache: false }); 116 }); 117 118 add_task(async function testHTMLOverrideWithCache() { 119 await testHTMLOverrideWithOptions({ enableCache: true }); 120 }); 121 122 async function testScriptOverrideWithOptions(options) { 123 const { monitor, tab, document } = await setupNetworkOverridesTest(options); 124 125 async function assertScriptOverrideInContent({ override }) { 126 await SpecialPowers.spawn( 127 gBrowser.selectedBrowser, 128 [override], 129 _override => { 130 is( 131 !!content.document.querySelector("#created-by-original"), 132 !_override, 133 `original div should ${!_override ? "" : "not "}be found` 134 ); 135 is( 136 !!content.document.querySelector("#created-by-override"), 137 _override, 138 `override div should ${_override ? "" : "not "}be found` 139 ); 140 } 141 ); 142 } 143 144 let scriptRequest = findRequestByInitiator(document, "script"); 145 ok( 146 !scriptRequest.querySelector(".requests-list-override"), 147 "There is no override cell" 148 ); 149 await assertOverrideColumnStatus(monitor, { visible: false }); 150 151 info("Check the original div was created by the script in the content page"); 152 await assertScriptOverrideInContent({ override: false }); 153 154 info("Set a network override for the script request"); 155 const overrideFileName = `script-override.js`; 156 const overridePath = await setNetworkOverride( 157 monitor, 158 scriptRequest, 159 overrideFileName, 160 OVERRIDDEN_SCRIPT, 161 // If cache is used and the navigation cache is enabled, the response is 162 // not available. 163 Services.prefs.getBoolPref( 164 "dom.script_loader.experimental.navigation_cache" 165 ) && options.enableCache 166 ); 167 168 // Assert override column is checked but disabled in context menu 169 await assertOverrideColumnStatus(monitor, { visible: true }); 170 171 // Assert override is only displayed for appropriate request 172 assertOverrideCellStatus(scriptRequest, { overridden: true }); 173 const overrideCell = scriptRequest.querySelector(".requests-list-override"); 174 ok( 175 overrideCell.getAttribute("title").includes(overrideFileName), 176 "The override icon's title contains the overridden path" 177 ); 178 const htmlRequest = findRequestByInitiator(document, "document"); 179 assertOverrideCellStatus(htmlRequest, { overridden: false }); 180 const stylesheetRequest = findRequestByInitiator(document, "stylesheet"); 181 assertOverrideCellStatus(stylesheetRequest, { overridden: false }); 182 183 info("Reloading to check the overridden script is loaded on the page"); 184 let waitForEvents = waitForNetworkEvents(monitor, 3); 185 tab.linkedBrowser.reload(); 186 await waitForEvents; 187 188 info("Check the override div was created by the script in the content page"); 189 await assertScriptOverrideInContent({ override: true }); 190 191 scriptRequest = findRequestByInitiator(document, "script"); 192 193 // Assert Response Tab shows the appropriate content 194 await assertOverriddenResponseTab(document, scriptRequest, overridePath); 195 196 // Remove Network override 197 await removeNetworkOverride(monitor, scriptRequest); 198 199 await assertOverrideColumnStatus(monitor, { visible: false }); 200 ok( 201 !scriptRequest.querySelector(".requests-list-override"), 202 "There is no override cell" 203 ); 204 205 info("Reload again to check the override script is no longer loaded"); 206 waitForEvents = waitForNetworkEvents(monitor, 3); 207 tab.linkedBrowser.reload(); 208 await waitForEvents; 209 210 info("Check the original div was created by the script in the content page"); 211 await assertScriptOverrideInContent({ override: false }); 212 213 return teardown(monitor); 214 } 215 216 add_task(async function testScriptOverrideWithoutCache() { 217 await testScriptOverrideWithOptions({ enableCache: false }); 218 }); 219 220 add_task(async function testScriptOverrideWithCache() { 221 await testScriptOverrideWithOptions({ enableCache: true }); 222 }); 223 224 async function testStylesheetOverrideWithOptions(options) { 225 const { monitor, tab, document } = await setupNetworkOverridesTest(options); 226 227 async function assertStylesheetOverrideInContent({ override }) { 228 await SpecialPowers.spawn( 229 gBrowser.selectedBrowser, 230 [override], 231 _override => { 232 const body = content.document.body; 233 const color = content.getComputedStyle(body).color; 234 is(color, _override ? "rgb(0, 0, 255)" : "rgb(255, 0, 0)"); 235 } 236 ); 237 } 238 239 let stylesheetRequest = findRequestByInitiator(document, "stylesheet"); 240 ok( 241 !stylesheetRequest.querySelector(".requests-list-override"), 242 "There is no override cell" 243 ); 244 await assertOverrideColumnStatus(monitor, { visible: false }); 245 246 info("Check the original div was created by the script in the content page"); 247 await assertStylesheetOverrideInContent({ override: false }); 248 249 info("Set a network override for the stylesheet request"); 250 const overrideFileName = `style-override.css`; 251 const overridePath = await setNetworkOverride( 252 monitor, 253 stylesheetRequest, 254 overrideFileName, 255 OVERRIDDEN_STYLESHEET, 256 // If cache is used, the response is not available. 257 options.enableCache 258 ); 259 260 // Assert override column is checked but disabled in context menu 261 await assertOverrideColumnStatus(monitor, { visible: true }); 262 263 // Assert override is only displayed for appropriate request 264 assertOverrideCellStatus(stylesheetRequest, { overridden: true }); 265 const overrideCell = stylesheetRequest.querySelector( 266 ".requests-list-override" 267 ); 268 ok( 269 overrideCell.getAttribute("title").includes(overrideFileName), 270 "The override icon's title contains the overridden path" 271 ); 272 const htmlRequest = findRequestByInitiator(document, "document"); 273 assertOverrideCellStatus(htmlRequest, { overridden: false }); 274 const scriptRequest = findRequestByInitiator(document, "script"); 275 assertOverrideCellStatus(scriptRequest, { overridden: false }); 276 277 await clearMemoryCache(tab.linkedBrowser); 278 279 info("Reloading to check the overridden script is loaded on the page"); 280 let waitForEvents = waitForNetworkEvents(monitor, 3); 281 tab.linkedBrowser.reload(); 282 await waitForEvents; 283 284 info("Check the overridden stylesheet was loaded in the content page"); 285 await assertStylesheetOverrideInContent({ override: true }); 286 287 info("Check the response tab"); 288 stylesheetRequest = findRequestByInitiator(document, "stylesheet"); 289 await assertOverriddenResponseTab(document, stylesheetRequest, overridePath); 290 291 info("Remove the network override"); 292 await removeNetworkOverride(monitor, stylesheetRequest); 293 await assertOverrideColumnStatus(monitor, { visible: false }); 294 ok( 295 !stylesheetRequest.querySelector(".requests-list-override"), 296 "There is no override cell" 297 ); 298 299 await clearMemoryCache(tab.linkedBrowser); 300 301 info("Reload again to check the overridden stylesheet is no longer loaded"); 302 waitForEvents = waitForNetworkEvents(monitor, 3); 303 tab.linkedBrowser.reload(); 304 await waitForEvents; 305 306 info("Check the original div was created by the script in the content page"); 307 await assertStylesheetOverrideInContent({ override: false }); 308 309 return teardown(monitor); 310 } 311 312 add_task(async function testStylesheetOverrideWithoutCache() { 313 await testStylesheetOverrideWithOptions({ enableCache: false }); 314 }); 315 316 add_task(async function testStylesheetOverrideWithCache() { 317 await testStylesheetOverrideWithOptions({ enableCache: true }); 318 }); 319 320 async function assertOverriddenResponseTab(doc, request, overrideFileName) { 321 EventUtils.sendMouseEvent({ type: "mousedown" }, request); 322 await waitFor( 323 () => doc.querySelector("#response-tab"), 324 "Wait for the response tab to be displayed" 325 ); 326 ok( 327 doc.querySelector(".tab-response-overridden"), 328 "Response tab is marked as overridden" 329 ); 330 const responsePanelTab = doc.querySelector("#response-tab"); 331 ok( 332 responsePanelTab.getAttribute("title").includes(overrideFileName), 333 "The response panel tab title contains the overridden path" 334 ); 335 }