browser_downloads.js (3935B)
1 /* Any copyright is dedicated to the Public Domain. 2 * http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 let { TelemetryTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/TelemetryTestUtils.sys.mjs" 8 ); 9 const { MockFilePicker } = SpecialPowers; 10 11 add_task(async function testSelectDownloadDir() { 12 // Setup 13 const tempDirPath = await IOUtils.createUniqueDirectory( 14 PathUtils.tempDir, 15 "test_downloads" 16 ); 17 const tempDir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 18 tempDir.initWithPath(tempDirPath); 19 const downloadsDirPath = await Downloads.getSystemDownloadsDirectory(); 20 const downloadsDir = new FileUtils.File(downloadsDirPath); 21 22 await SpecialPowers.pushPrefEnv({ 23 set: [ 24 ["browser.download.folderList", 1], 25 ["browser.download.dir", downloadsDirPath], 26 ], 27 }); 28 29 // Open preferences pane 30 await openPreferencesViaOpenPreferencesAPI("general", { 31 leaveOpen: true, 32 }); 33 34 let win = gBrowser.selectedBrowser.contentWindow; 35 let doc = gBrowser.contentDocument; 36 await doc.l10n.ready; 37 38 let inputFolder = doc.getElementById("chooseFolder"); 39 let button = inputFolder.chooseFolderButtonEl; 40 button.scrollIntoView({ block: "center" }); 41 42 // Get Downloads folder details 43 const [downloadsFolderName] = await doc.l10n.formatValues([ 44 { id: "downloads-folder-name" }, 45 ]); 46 let downloadsDirLeafName; 47 try { 48 downloadsDirLeafName = downloadsDir.leafName; 49 } catch (ex) { 50 /* ignored */ 51 } 52 let downloadsFolderDisplayValue = 53 downloadsDirLeafName == downloadsFolderName 54 ? downloadsFolderName 55 : `\u2066${downloadsDirPath}\u2069`; 56 57 // Initialize file picker 58 MockFilePicker.init(window.browsingContext); 59 MockFilePicker.returnValue = MockFilePicker.returnOK; 60 61 function mockFilePickerWithDirectory(dir) { 62 return new Promise(resolve => { 63 MockFilePicker.showCallback = () => { 64 ok(true, `FilePicker shown for ${dir.path}`); 65 MockFilePicker.setFiles([dir]); 66 resolve(); 67 }; 68 }); 69 } 70 71 async function selectDirectory(dir) { 72 const pickerPromise = mockFilePickerWithDirectory(dir); 73 const changeEvent = BrowserTestUtils.waitForEvent(inputFolder, "change"); 74 75 EventUtils.synthesizeMouseAtCenter(button, {}, win); 76 await pickerPromise; 77 await changeEvent; 78 await inputFolder.updateComplete; 79 await TestUtils.waitForTick(); 80 } 81 82 // Check initial state 83 is( 84 inputFolder.value, 85 downloadsDirPath, 86 "Initial input folder value is set to the Downloads folder path" 87 ); 88 is( 89 inputFolder.displayValue, 90 downloadsFolderDisplayValue, 91 "Initial display value of the input folder is set to Downloads" 92 ); 93 94 // Select temp dir 95 await selectDirectory(tempDir); 96 97 is( 98 inputFolder.value, 99 tempDirPath, 100 "Input folder value is set to the temporary folder path" 101 ); 102 ok( 103 inputFolder.displayValue.includes("test_downloads"), 104 "Input folder displayValue is set to the temporary folder path" 105 ); 106 107 // Assert telemetry after first interaction 108 TelemetryTestUtils.assertKeyedScalar( 109 TelemetryTestUtils.getProcessScalars("parent", true, false), 110 "browser.ui.interaction.preferences_paneGeneral", 111 "chooseFolder", 112 1 113 ); 114 115 // Select Downloads again 116 await selectDirectory(downloadsDir); 117 is( 118 inputFolder.value, 119 downloadsDirPath, 120 "Input folder value is set to the Downloads folder path" 121 ); 122 is( 123 inputFolder.displayValue, 124 downloadsFolderDisplayValue, 125 "Display value of the input folder is set to Downloads" 126 ); 127 128 // Reassert telemetry 129 TelemetryTestUtils.assertKeyedScalar( 130 TelemetryTestUtils.getProcessScalars("parent", true, true), 131 "browser.ui.interaction.preferences_paneGeneral", 132 "chooseFolder", 133 2 134 ); 135 136 // Cleanup 137 MockFilePicker.cleanup(); 138 await IOUtils.remove(tempDirPath, { recursive: true }); 139 BrowserTestUtils.removeTab(gBrowser.selectedTab); 140 });