browser_save_link_when_window_navigates.js (6152B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 var MockFilePicker = SpecialPowers.MockFilePicker; 5 MockFilePicker.init(window.browsingContext); 6 7 const SAVE_PER_SITE_PREF = "browser.download.lastDir.savePerSite"; 8 const ALWAYS_DOWNLOAD_DIR_PREF = "browser.download.useDownloadDir"; 9 const ALWAYS_ASK_PREF = "browser.download.always_ask_before_handling_new_types"; 10 const UCT_URI = "chrome://mozapps/content/downloads/unknownContentType.xhtml"; 11 12 Services.scriptloader.loadSubScript( 13 "chrome://mochitests/content/browser/toolkit/content/tests/browser/common/mockTransfer.js", 14 this 15 ); 16 17 function createTemporarySaveDirectory() { 18 var saveDir = Services.dirsvc.get("TmpD", Ci.nsIFile); 19 saveDir.append("testsavedir"); 20 if (!saveDir.exists()) { 21 info("create testsavedir!"); 22 saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755); 23 } 24 25 Services.prefs.setIntPref("browser.download.folderList", 2); 26 Services.prefs.setCharPref("browser.download.dir", saveDir); 27 info("return from createTempSaveDir: " + saveDir.path); 28 return saveDir; 29 } 30 31 function triggerSave(aWindow, aCallback) { 32 info( 33 "started triggerSave, persite downloads: " + 34 (Services.prefs.getBoolPref(SAVE_PER_SITE_PREF) ? "on" : "off") 35 ); 36 var fileName; 37 let testBrowser = aWindow.gBrowser.selectedBrowser; 38 let testURI = 39 "http://mochi.test:8888/browser/browser/base/content/test/general/navigating_window_with_download.html"; 40 41 // Only observe the UTC dialog if it's enabled by pref 42 if (Services.prefs.getBoolPref(ALWAYS_ASK_PREF)) { 43 windowObserver.setCallback(onUCTDialog); 44 } 45 46 BrowserTestUtils.startLoadingURIString(testBrowser, testURI); 47 48 // Create the folder the link will be saved into. 49 var destDir = createTemporarySaveDirectory(); 50 var destFile = destDir.clone(); 51 52 MockFilePicker.displayDirectory = destDir; 53 MockFilePicker.showCallback = function (fp) { 54 info("showCallback"); 55 fileName = fp.defaultString; 56 info("fileName: " + fileName); 57 destFile.append(fileName); 58 MockFilePicker.setFiles([destFile]); 59 MockFilePicker.filterIndex = 1; // kSaveAsType_URL 60 info("done showCallback"); 61 }; 62 63 mockTransferCallback = function (downloadSuccess) { 64 info("mockTransferCallback"); 65 onTransferComplete(aWindow, downloadSuccess, destDir); 66 destDir.remove(true); 67 ok(!destDir.exists(), "Destination dir should be removed"); 68 ok(!destFile.exists(), "Destination file should be removed"); 69 mockTransferCallback = null; 70 info("done mockTransferCallback"); 71 }; 72 73 function onUCTDialog() { 74 SpecialPowers.spawn(testBrowser, [], async () => { 75 content.document.querySelector("iframe").remove(); 76 }).then(() => executeSoon(continueDownloading)); 77 } 78 79 function continueDownloading() { 80 for (let win of Services.wm.getEnumerator("")) { 81 if (win.location && win.location.href == UCT_URI) { 82 win.document 83 .getElementById("unknownContentType") 84 ._fireButtonEvent("accept"); 85 win.close(); 86 return; 87 } 88 } 89 ok(false, "No Unknown Content Type dialog yet?"); 90 } 91 92 function onTransferComplete(aWindow2, downloadSuccess) { 93 ok(downloadSuccess, "Link should have been downloaded successfully"); 94 aWindow2.close(); 95 96 executeSoon(aCallback); 97 } 98 } 99 100 var windowObserver = { 101 setCallback(aCallback) { 102 if (this._callback) { 103 ok(false, "Should only be dealing with one callback at a time."); 104 } 105 this._callback = aCallback; 106 }, 107 observe(aSubject, aTopic) { 108 if (aTopic != "domwindowopened") { 109 return; 110 } 111 112 let win = aSubject; 113 114 win.addEventListener( 115 "load", 116 function () { 117 if (win.location == UCT_URI) { 118 SimpleTest.executeSoon(function () { 119 if (windowObserver._callback) { 120 windowObserver._callback(win); 121 delete windowObserver._callback; 122 } else { 123 ok(false, "Unexpected UCT dialog!"); 124 } 125 }); 126 } 127 }, 128 { once: true } 129 ); 130 }, 131 }; 132 133 Services.ww.registerNotification(windowObserver); 134 135 function test() { 136 waitForExplicitFinish(); 137 Services.prefs.setBoolPref(ALWAYS_ASK_PREF, false); 138 139 function testOnWindow(options, callback) { 140 info("testOnWindow(" + options + ")"); 141 var win = OpenBrowserWindow(options); 142 info("got " + win); 143 whenDelayedStartupFinished(win, () => callback(win)); 144 } 145 146 function whenDelayedStartupFinished(aWindow, aCallback) { 147 info("whenDelayedStartupFinished"); 148 Services.obs.addObserver(function observer(aSubject, aTopic) { 149 info( 150 "whenDelayedStartupFinished, got topic: " + 151 aTopic + 152 ", got subject: " + 153 aSubject + 154 ", waiting for " + 155 aWindow 156 ); 157 if (aWindow == aSubject) { 158 Services.obs.removeObserver(observer, aTopic); 159 executeSoon(aCallback); 160 info("whenDelayedStartupFinished found our window"); 161 } 162 }, "browser-delayed-startup-finished"); 163 } 164 165 mockTransferRegisterer.register(); 166 167 registerCleanupFunction(function () { 168 info("Running the cleanup code"); 169 mockTransferRegisterer.unregister(); 170 MockFilePicker.cleanup(); 171 Services.ww.unregisterNotification(windowObserver); 172 Services.prefs.clearUserPref(ALWAYS_DOWNLOAD_DIR_PREF); 173 Services.prefs.clearUserPref(SAVE_PER_SITE_PREF); 174 Services.prefs.clearUserPref(ALWAYS_ASK_PREF); 175 Services.prefs.clearUserPref("browser.download.folderList"); 176 Services.prefs.clearUserPref("browser.download.dir"); 177 info("Finished running the cleanup code"); 178 }); 179 180 info( 181 `Running test with ${ALWAYS_ASK_PREF} set to ${Services.prefs.getBoolPref( 182 ALWAYS_ASK_PREF, 183 false 184 )}` 185 ); 186 testOnWindow(undefined, function (win) { 187 let windowGonePromise = BrowserTestUtils.domWindowClosed(win); 188 Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, true); 189 triggerSave(win, async function () { 190 await windowGonePromise; 191 Services.prefs.setBoolPref(SAVE_PER_SITE_PREF, false); 192 testOnWindow(undefined, function (win2) { 193 triggerSave(win2, finish); 194 }); 195 }); 196 }); 197 }