browser_open_download_preferences.js (8267B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { HandlerServiceTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/HandlerServiceTestUtils.sys.mjs" 8 ); 9 10 const TEST_PATH = getRootDirectory(gTestPath).replace( 11 "chrome://mochitests/content", 12 "https://example.com" 13 ); 14 15 async function selectPdfCategoryItem() { 16 await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true }); 17 info("Preferences page opened on the general pane."); 18 19 await gBrowser.selectedBrowser.contentWindow.promiseLoadHandlersList; 20 info("Apps list loaded."); 21 22 let win = gBrowser.selectedBrowser.contentWindow; 23 let container = win.document.getElementById("handlersView"); 24 let pdfCategory = container.querySelector( 25 "richlistitem[type='application/pdf']" 26 ); 27 28 pdfCategory.closest("richlistbox").selectItem(pdfCategory); 29 Assert.ok(pdfCategory.selected, "Should be able to select our item."); 30 31 return pdfCategory; 32 } 33 34 async function selectItemInPopup(item, list) { 35 let popup = list.menupopup; 36 let popupShown = BrowserTestUtils.waitForEvent(popup, "popupshown"); 37 // Synthesizing the mouse on the .actionsMenu menulist somehow just selects 38 // the top row. Probably something to do with the multiple layers of anon 39 // content - workaround by using the `.open` setter instead. 40 list.open = true; 41 await popupShown; 42 let popupHidden = BrowserTestUtils.waitForEvent(popup, "popuphidden"); 43 44 item.click(); 45 popup.hidePopup(); 46 await popupHidden; 47 return item; 48 } 49 50 function downloadHadFinished(publicList) { 51 return new Promise(resolve => { 52 publicList.addView({ 53 onDownloadChanged(download) { 54 if (download.succeeded || download.error) { 55 publicList.removeView(this); 56 resolve(download); 57 } 58 }, 59 }); 60 }); 61 } 62 63 async function removeTheFile(download) { 64 Assert.ok( 65 await IOUtils.exists(download.target.path), 66 "The file should have been downloaded." 67 ); 68 69 try { 70 info("removing " + download.target.path); 71 if (Services.appinfo.OS === "WINNT") { 72 // We need to make the file writable to delete it on Windows. 73 await IOUtils.setPermissions(download.target.path, 0o600); 74 } 75 await IOUtils.remove(download.target.path); 76 } catch (ex) { 77 info("The file " + download.target.path + " is not removed, " + ex); 78 } 79 } 80 81 add_task(async function alwaysAskPreferenceWorks() { 82 await SpecialPowers.pushPrefEnv({ 83 set: [ 84 ["browser.download.always_ask_before_handling_new_types", false], 85 ["browser.download.useDownloadDir", true], 86 ], 87 }); 88 89 let pdfCategory = await selectPdfCategoryItem(); 90 let list = pdfCategory.querySelector(".actionsMenu"); 91 92 let alwaysAskItem = list.querySelector( 93 `menuitem[action='${Ci.nsIHandlerInfo.alwaysAsk}']` 94 ); 95 96 await selectItemInPopup(alwaysAskItem, list); 97 Assert.equal( 98 list.selectedItem, 99 alwaysAskItem, 100 "Should have selected 'always ask' for pdf" 101 ); 102 let alwaysAskBeforeHandling = HandlerServiceTestUtils.getHandlerInfo( 103 pdfCategory.getAttribute("type") 104 ).alwaysAskBeforeHandling; 105 Assert.ok( 106 alwaysAskBeforeHandling, 107 "Should have turned on 'always asking before handling'" 108 ); 109 110 let domWindowPromise = BrowserTestUtils.domWindowOpenedAndLoaded(); 111 let loadingTab = await BrowserTestUtils.openNewForegroundTab({ 112 gBrowser, 113 opening: TEST_PATH + "empty_pdf_file.pdf", 114 waitForLoad: false, 115 waitForStateStop: true, 116 }); 117 118 let domWindow = await domWindowPromise; 119 let dialog = domWindow.document.querySelector("#unknownContentType"); 120 let button = dialog.getButton("cancel"); 121 122 await TestUtils.waitForCondition( 123 () => !button.disabled, 124 "Wait for Cancel button to get enabled" 125 ); 126 Assert.ok(dialog, "Dialog should be shown"); 127 dialog.cancelDialog(); 128 BrowserTestUtils.removeTab(loadingTab); 129 130 gBrowser.removeCurrentTab(); 131 }); 132 133 add_task(async function handleInternallyPreferenceWorks() { 134 await SpecialPowers.pushPrefEnv({ 135 set: [ 136 ["browser.download.always_ask_before_handling_new_types", false], 137 ["browser.download.useDownloadDir", true], 138 ], 139 }); 140 141 let pdfCategory = await selectPdfCategoryItem(); 142 let list = pdfCategory.querySelector(".actionsMenu"); 143 144 let handleInternallyItem = list.querySelector( 145 `menuitem[action='${Ci.nsIHandlerInfo.handleInternally}']` 146 ); 147 148 await selectItemInPopup(handleInternallyItem, list); 149 Assert.equal( 150 list.selectedItem, 151 handleInternallyItem, 152 "Should have selected 'handle internally' for pdf" 153 ); 154 155 let loadingTab = await BrowserTestUtils.openNewForegroundTab({ 156 gBrowser, 157 opening: TEST_PATH + "empty_pdf_file.pdf", 158 waitForLoad: false, 159 waitForStateStop: true, 160 }); 161 162 await ContentTask.spawn(loadingTab.linkedBrowser, null, async () => { 163 await ContentTaskUtils.waitForCondition( 164 () => content.document.readyState == "complete" 165 ); 166 Assert.ok( 167 content.document.querySelector("div#viewer"), 168 "document content has viewer UI" 169 ); 170 }); 171 172 BrowserTestUtils.removeTab(loadingTab); 173 174 gBrowser.removeCurrentTab(); 175 }); 176 177 add_task(async function saveToDiskPreferenceWorks() { 178 await SpecialPowers.pushPrefEnv({ 179 set: [ 180 ["browser.download.always_ask_before_handling_new_types", false], 181 ["browser.download.useDownloadDir", true], 182 ], 183 }); 184 185 let pdfCategory = await selectPdfCategoryItem(); 186 let list = pdfCategory.querySelector(".actionsMenu"); 187 188 let saveToDiskItem = list.querySelector( 189 `menuitem[action='${Ci.nsIHandlerInfo.saveToDisk}']` 190 ); 191 192 await selectItemInPopup(saveToDiskItem, list); 193 Assert.equal( 194 list.selectedItem, 195 saveToDiskItem, 196 "Should have selected 'save to disk' for pdf" 197 ); 198 199 let publicList = await Downloads.getList(Downloads.PUBLIC); 200 registerCleanupFunction(async () => { 201 await publicList.removeFinished(); 202 }); 203 204 let downloadFinishedPromise = downloadHadFinished(publicList); 205 206 let loadingTab = await BrowserTestUtils.openNewForegroundTab({ 207 gBrowser, 208 opening: TEST_PATH + "empty_pdf_file.pdf", 209 waitForLoad: false, 210 waitForStateStop: true, 211 }); 212 213 let download = await downloadFinishedPromise; 214 BrowserTestUtils.removeTab(loadingTab); 215 216 await removeTheFile(download); 217 218 gBrowser.removeCurrentTab(); 219 }); 220 221 add_task(async function useSystemDefaultPreferenceWorks() { 222 await SpecialPowers.pushPrefEnv({ 223 set: [ 224 ["browser.download.always_ask_before_handling_new_types", false], 225 ["browser.download.useDownloadDir", true], 226 ], 227 }); 228 229 let pdfCategory = await selectPdfCategoryItem(); 230 let list = pdfCategory.querySelector(".actionsMenu"); 231 232 let useSystemDefaultItem = list.querySelector( 233 `menuitem[action='${Ci.nsIHandlerInfo.useSystemDefault}']` 234 ); 235 236 // Whether there's a "use default" item depends on the OS, there might not be a system default viewer. 237 if (!useSystemDefaultItem) { 238 info( 239 "No 'Use default' item, so no testing for setting 'use system default' preference" 240 ); 241 gBrowser.removeCurrentTab(); 242 return; 243 } 244 245 await selectItemInPopup(useSystemDefaultItem, list); 246 Assert.equal( 247 list.selectedItem, 248 useSystemDefaultItem, 249 "Should have selected 'use system default' for pdf" 250 ); 251 252 let oldLaunchFile = DownloadIntegration.launchFile; 253 254 let waitForLaunchFileCalled = new Promise(resolve => { 255 DownloadIntegration.launchFile = () => { 256 ok(true, "The file should be launched with an external application"); 257 resolve(); 258 }; 259 }); 260 261 let publicList = await Downloads.getList(Downloads.PUBLIC); 262 registerCleanupFunction(async () => { 263 await publicList.removeFinished(); 264 }); 265 266 let downloadFinishedPromise = downloadHadFinished(publicList); 267 268 let loadingTab = await BrowserTestUtils.openNewForegroundTab({ 269 gBrowser, 270 opening: TEST_PATH + "empty_pdf_file.pdf", 271 waitForLoad: false, 272 waitForStateStop: true, 273 }); 274 275 info("Downloading had finished"); 276 let download = await downloadFinishedPromise; 277 278 info("Waiting until DownloadIntegration.launchFile is called"); 279 await waitForLaunchFileCalled; 280 281 DownloadIntegration.launchFile = oldLaunchFile; 282 283 await removeTheFile(download); 284 285 BrowserTestUtils.removeTab(loadingTab); 286 287 gBrowser.removeCurrentTab(); 288 });