browser_bug676619.js (6922B)
1 var MockFilePicker = SpecialPowers.MockFilePicker; 2 MockFilePicker.init(window.browsingContext); 3 4 function waitForNewWindow() { 5 return new Promise(resolve => { 6 var listener = { 7 onOpenWindow: aXULWindow => { 8 info("Download window shown..."); 9 Services.wm.removeListener(listener); 10 11 function downloadOnLoad() { 12 domwindow.removeEventListener("load", downloadOnLoad, true); 13 14 is( 15 domwindow.document.location.href, 16 "chrome://mozapps/content/downloads/unknownContentType.xhtml", 17 "Download page appeared" 18 ); 19 resolve(domwindow); 20 } 21 22 var domwindow = aXULWindow.docShell.domWindow; 23 domwindow.addEventListener("load", downloadOnLoad, true); 24 }, 25 onCloseWindow: () => {}, 26 }; 27 28 Services.wm.addListener(listener); 29 registerCleanupFunction(() => { 30 try { 31 Services.wm.removeListener(listener); 32 } catch (e) {} 33 }); 34 }); 35 } 36 37 async function waitForFilePickerTest(link, name) { 38 let filePickerShownPromise = new Promise(resolve => { 39 MockFilePicker.showCallback = function (fp) { 40 ok(true, "Filepicker shown."); 41 is(name, fp.defaultString, " filename matches download name"); 42 setTimeout(resolve, 0); 43 return Ci.nsIFilePicker.returnCancel; 44 }; 45 }); 46 47 SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => { 48 content.document.getElementById(contentLink).click(); 49 }); 50 51 await filePickerShownPromise; 52 53 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 54 Assert.equal( 55 content.document.getElementById("unload-flag").textContent, 56 "Okay", 57 "beforeunload shouldn't have fired" 58 ); 59 }); 60 } 61 62 async function testLink(link, name) { 63 info("Checking " + link + " with name: " + name); 64 65 if ( 66 Services.prefs.getBoolPref( 67 "browser.download.always_ask_before_handling_new_types", 68 false 69 ) 70 ) { 71 let winPromise = waitForNewWindow(); 72 73 SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => { 74 content.document.getElementById(contentLink).click(); 75 }); 76 77 let win = await winPromise; 78 79 await SpecialPowers.spawn(gBrowser.selectedBrowser, [], () => { 80 Assert.equal( 81 content.document.getElementById("unload-flag").textContent, 82 "Okay", 83 "beforeunload shouldn't have fired" 84 ); 85 }); 86 87 is( 88 win.document.getElementById("location").value, 89 name, 90 `file name should match (${link})` 91 ); 92 93 await BrowserTestUtils.closeWindow(win); 94 } else { 95 await waitForFilePickerTest(link, name); 96 } 97 } 98 99 // Cross-origin URL does not trigger a download 100 async function testLocation(link) { 101 let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser); 102 103 SpecialPowers.spawn(gBrowser.selectedBrowser, [link], contentLink => { 104 content.document.getElementById(contentLink).click(); 105 }); 106 107 let tab = await tabPromise; 108 BrowserTestUtils.removeTab(tab); 109 } 110 111 async function runTest(url) { 112 let tab = BrowserTestUtils.addTab(gBrowser, url); 113 gBrowser.selectedTab = tab; 114 115 let browser = gBrowser.getBrowserForTab(tab); 116 await BrowserTestUtils.browserLoaded(browser); 117 118 await testLink("link1", "test.txt"); 119 await testLink("link2", "video.webm"); 120 await testLink("link3", "just some video.webm"); 121 await testLink("link4", "with-target.txt"); 122 await testLink("link5", "javascript.html"); 123 await testLink("link6", "test.blob"); 124 await testLink("link7", "test.file"); 125 await testLink("link8", "download_page_3.txt"); 126 await testLink("link9", "download_page_3.txt"); 127 await testLink("link10", "download_page_4.txt"); 128 await testLink("link11", "download_page_4.txt"); 129 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 130 await testLocation("link12", "http://example.com/"); 131 132 // Check that we enforce the correct extension if the website's 133 // is bogus or missing. These extensions can differ slightly (ogx vs ogg, 134 // htm vs html) on different OSes. 135 let webmExtension = getMIMEInfoForType("video/webm").primaryExtension; 136 await testLink("link13", "no file extension." + webmExtension); 137 138 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1690051#c8 139 if (AppConstants.platform != "win") { 140 const PREF = "browser.download.sanitize_non_media_extensions"; 141 ok(Services.prefs.getBoolPref(PREF), "pref is set before"); 142 143 // Check that ics (iCal) extension is changed/fixed when the pref is true. 144 await testLink("link14", "dummy.ics"); 145 146 // And not changed otherwise. 147 Services.prefs.setBoolPref(PREF, false); 148 await testLink("link14", "dummy.not-ics"); 149 Services.prefs.clearUserPref(PREF); 150 } 151 152 await testLink("link15", "download_page_3.txt"); 153 await testLink("link16", "download_page_3.txt"); 154 await testLink("link17", "download_page_4.txt"); 155 await testLink("link18", "download_page_4.txt"); 156 await testLink("link19", "download_page_4.txt"); 157 await testLink("link20", "download_page_4.txt"); 158 await testLink("link21", "download_page_4.txt"); 159 await testLink("link22", "download_page_4.txt"); 160 161 BrowserTestUtils.removeTab(tab); 162 } 163 164 async function setDownloadDir() { 165 let tmpDir = PathUtils.join( 166 PathUtils.tempDir, 167 "testsavedir" + Math.floor(Math.random() * 2 ** 32) 168 ); 169 // Create this dir if it doesn't exist (ignores existing dirs) 170 await IOUtils.makeDirectory(tmpDir); 171 registerCleanupFunction(async function () { 172 try { 173 await IOUtils.remove(tmpDir, { recursive: true }); 174 } catch (e) { 175 console.error(e); 176 } 177 Services.prefs.clearUserPref("browser.download.folderList"); 178 Services.prefs.clearUserPref("browser.download.dir"); 179 }); 180 Services.prefs.setIntPref("browser.download.folderList", 2); 181 Services.prefs.setCharPref("browser.download.dir", tmpDir); 182 } 183 184 add_task(async function () { 185 requestLongerTimeout(3); 186 waitForExplicitFinish(); 187 188 await setDownloadDir(); 189 190 info( 191 "Test with browser.download.always_ask_before_handling_new_types enabled." 192 ); 193 await SpecialPowers.pushPrefEnv({ 194 set: [ 195 ["browser.download.always_ask_before_handling_new_types", true], 196 ["browser.download.useDownloadDir", true], 197 ], 198 }); 199 200 await runTest( 201 "http://mochi.test:8888/browser/browser/base/content/test/general/download_page.html" 202 ); 203 await runTest( 204 "https://example.com:443/browser/browser/base/content/test/general/download_page.html" 205 ); 206 207 info( 208 "Test with browser.download.always_ask_before_handling_new_types disabled." 209 ); 210 await SpecialPowers.pushPrefEnv({ 211 set: [ 212 ["browser.download.always_ask_before_handling_new_types", false], 213 ["browser.download.useDownloadDir", false], 214 ], 215 }); 216 217 await runTest( 218 "http://mochi.test:8888/browser/browser/base/content/test/general/download_page.html" 219 ); 220 await runTest( 221 "https://example.com:443/browser/browser/base/content/test/general/download_page.html" 222 ); 223 224 MockFilePicker.cleanup(); 225 });