browser_confirmFolderUpload.js (5293B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { PromptTestUtils } = ChromeUtils.importESModule( 7 "resource://testing-common/PromptTestUtils.sys.mjs" 8 ); 9 10 /** 11 * Create a temporary test directory that will be cleaned up on test shutdown. 12 * 13 * @returns {string} - absolute directory path. 14 */ 15 function getTestDirectory() { 16 let tmpDir = Services.dirsvc.get("TmpD", Ci.nsIFile); 17 tmpDir.append("testdir"); 18 if (!tmpDir.exists()) { 19 tmpDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755); 20 registerCleanupFunction(() => { 21 tmpDir.remove(true); 22 }); 23 } 24 25 let file1 = tmpDir.clone(); 26 file1.append("foo.txt"); 27 if (!file1.exists()) { 28 file1.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); 29 } 30 31 let file2 = tmpDir.clone(); 32 file2.append("bar.txt"); 33 if (!file2.exists()) { 34 file2.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); 35 } 36 37 return tmpDir.path; 38 } 39 40 add_setup(async function () { 41 await SpecialPowers.pushPrefEnv({ 42 set: [ 43 // Allow using our MockFilePicker in the content process. 44 ["dom.filesystem.pathcheck.disabled", true], 45 ["dom.webkitBlink.dirPicker.enabled", true], 46 ], 47 }); 48 }); 49 50 /** 51 * Create a file input, select a folder and wait for the upload confirmation 52 * prompt to open. 53 * 54 * @param {boolean} confirmUpload - Whether to accept (true) or cancel the 55 * prompt (false). 56 * @returns {Promise} - Resolves once the prompt has been closed. 57 */ 58 async function testUploadPrompt(confirmUpload) { 59 // eslint-disable-next-line @microsoft/sdl/no-insecure-url 60 await BrowserTestUtils.withNewTab("http://example.com", async browser => { 61 // Create file input element 62 await ContentTask.spawn(browser, null, () => { 63 let input = content.document.createElement("input"); 64 input.id = "filepicker"; 65 input.setAttribute("type", "file"); 66 input.setAttribute("webkitdirectory", ""); 67 content.document.body.appendChild(input); 68 }); 69 70 // If we're confirming the dialog, register a "change" listener on the 71 // file input. 72 let changePromise; 73 if (confirmUpload) { 74 changePromise = ContentTask.spawn(browser, null, async () => { 75 let input = content.document.getElementById("filepicker"); 76 return ContentTaskUtils.waitForEvent(input, "change").then( 77 e => e.target.files.length 78 ); 79 }); 80 } 81 82 // Register prompt promise 83 let promptPromise = PromptTestUtils.waitForPrompt(browser, { 84 modalType: Services.prompt.MODAL_TYPE_TAB, 85 promptType: "confirmEx", 86 }); 87 88 // Open filepicker 89 let path = getTestDirectory(); 90 await ContentTask.spawn(browser, { path }, args => { 91 let MockFilePicker = content.SpecialPowers.MockFilePicker; 92 MockFilePicker.init( 93 content.browsingContext, 94 "A Mock File Picker", 95 content.SpecialPowers.Ci.nsIFilePicker.modeGetFolder 96 ); 97 MockFilePicker.useDirectory(args.path); 98 99 let input = content.document.getElementById("filepicker"); 100 101 // Activate the page to allow opening the file picker. 102 content.SpecialPowers.wrap( 103 content.document 104 ).notifyUserGestureActivation(); 105 106 input.click(); 107 }); 108 109 // Wait for confirmation prompt 110 let prompt = await promptPromise; 111 ok(prompt, "Shown upload confirmation prompt"); 112 113 is(prompt.ui.button0.label, "Upload", "Accept button label"); 114 ok( 115 prompt.ui.button0.disabled, 116 "Accept button should be disabled by the security delay initially." 117 ); 118 119 ok(prompt.ui.button1.hasAttribute("default"), "Cancel is default button"); 120 ok( 121 !prompt.ui.button1.disabled, 122 "Cancel button should not be disabled by the security delay." 123 ); 124 125 info("Wait for the security delay to pass."); 126 let delayTime = Services.prefs.getIntPref("security.dialog_enable_delay"); 127 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 128 await new Promise(resolve => setTimeout(resolve, delayTime + 100)); 129 130 ok( 131 !prompt.ui.button0.disabled, 132 "Accept button should no longer be disabled." 133 ); 134 ok(!prompt.ui.button1.disabled, "Cancel button should remain enabled."); 135 136 // Close confirmation prompt 137 await PromptTestUtils.handlePrompt(prompt, { 138 buttonNumClick: confirmUpload ? 0 : 1, 139 }); 140 141 // If we accepted, wait for the input elements "change" event 142 if (changePromise) { 143 let fileCount = await changePromise; 144 is(fileCount, 2, "Should have selected 2 files"); 145 } else { 146 let fileCount = await ContentTask.spawn(browser, null, () => { 147 return content.document.getElementById("filepicker").files.length; 148 }); 149 150 is(fileCount, 0, "Should not have selected any files"); 151 } 152 153 // Cleanup 154 await ContentTask.spawn(browser, null, () => { 155 content.SpecialPowers.MockFilePicker.cleanup(); 156 }); 157 }); 158 } 159 160 add_setup(async function () { 161 await SpecialPowers.pushPrefEnv({ 162 set: [["test.wait300msAfterTabSwitch", true]], 163 }); 164 }); 165 166 // Tests the confirmation prompt that shows after the user picked a folder. 167 168 // Confirm the prompt 169 add_task(async function test_confirm() { 170 await testUploadPrompt(true); 171 }); 172 173 // Cancel the prompt 174 add_task(async function test_cancel() { 175 await testUploadPrompt(false); 176 });