test_input_file_picker.html (13148B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test for <input type='file'> file picker</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="/tests/SimpleTest/EventUtils.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 8 </head> 9 <body> 10 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=377624">Mozilla Bug 36619</a> 11 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=377624">Mozilla Bug 377624</a> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=565274">Mozilla Bug 565274</a> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=701353">Mozilla Bug 701353</a> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=826176">Mozilla Bug 826176</a> 15 <p id="display"></p> 16 <div id="content"> 17 <input id='a' type='file' accept="image/*"> 18 <input id='b' type='file' accept="audio/*"> 19 <input id='c' type='file' accept="video/*"> 20 <input id='d' type='file' accept="image/*, audio/* "> 21 <input id='e' type='file' accept=" image/*,video/*"> 22 <input id='f' type='file' accept="audio/*,video/*"> 23 <input id='g' type='file' accept="image/*, audio/* ,video/*"> 24 <input id='h' type='file' accept="foo/baz,image/*,bogus/duh"> 25 <input id='i' type='file' accept="mime/type;parameter,video/*"> 26 <input id='j' type='file' accept="audio/*, audio/*, audio/*"> 27 <input id='k' type="file" accept="image/gif,image/png"> 28 <input id='l' type="file" accept="image/*,image/gif,image/png"> 29 <input id='m' type="file" accept="image/gif,image/gif"> 30 <input id='n' type="file" accept=""> 31 <input id='o' type="file" accept=".test"> 32 <input id='p' type="file" accept="image/gif,.csv"> 33 <input id='q' type="file" accept="image/gif,.gif"> 34 <input id='r' type="file" accept=".prefix,.prefixPlusSomething"> 35 <input id='s' type="file" accept=".xls,.xlsx"> 36 <input id='t' type="file" accept=".mp3,.wav,.flac"> 37 <input id='u' type="file" accept=".xls, .xlsx"> 38 <input id='v' type="file" accept=".xlsx, .xls"> 39 <input id='w' type="file" accept=".xlsx; .xls"> 40 <input id='x' type="file" accept=".xls, .xlsx"> 41 <input id='y' type="file" accept=".xlsx, .xls"> 42 <input id='z' type='file' accept="i/am,a,pathological,;,,,,test/case"> 43 <input id='A' type="file" accept=".xlsx, .xls*"> 44 <input id='mix-ref' type="file" accept="image/jpeg"> 45 <input id='mix' type="file" accept="image/jpeg,.jpg"> 46 <input id='hidden' hidden type='file'> 47 <input id='untrusted-click' type='file'> 48 <input id='prevent-default' type='file'> 49 <input id='prevent-default-false' type='file'> 50 <input id='right-click' type='file'> 51 <input id='middle-click' type='file'> 52 <input id='left-click' type='file'> 53 <label id='label-1'>foo<input type='file'></label> 54 <label id='label-2' for='labeled-2'>foo</label><input id='labeled-2' type='file'></label> 55 <label id='label-3'>foo<input type='file'></label> 56 <label id='label-4' for='labeled-4'>foo</label><input id='labeled-4' type='file'></label> 57 <input id='by-button' type='file'> 58 <button id='button-click' onclick="document.getElementById('by-button').click();">foo</button> 59 <button id='button-down' onclick="document.getElementById('by-button').click();">foo</button> 60 <button id='button-up' onclick="document.getElementById('by-button').click();">foo</button> 61 <div id='div-click' onclick="document.getElementById('by-button').click();" tabindex='1'>foo</div> 62 <div id='div-click-on-demand' onclick="var i=document.createElement('input'); i.type='file'; i.click();" tabindex='1'>foo</div> 63 <div id='div-keydown' onkeydown="document.getElementById('by-button').click();" tabindex='1'>foo</div> 64 <a id='link-click' href="javascript:document.getElementById('by-button').click();" tabindex='1'>foo</a> 65 <input id='show-picker' type='file'> 66 </div> 67 <pre id="test"> 68 <script type="application/javascript"> 69 70 /** 71 * This test checks various scenarios and make sure that a file picker is being 72 * shown in all of them (minus a few exceptions). 73 * |testData| defines the tests to do and |launchNextTest| can be used to have 74 * specific behaviour for some tests. Everything else should just work. 75 */ 76 77 SimpleTest.waitForExplicitFinish(); 78 SimpleTest.requestFlakyTimeout("untriaged"); 79 80 var MockFilePicker = SpecialPowers.MockFilePicker; 81 MockFilePicker.init(SpecialPowers.wrap(window).browsingContext); 82 83 // The following lists are from toolkit/content/filepicker.properties which is used by filePicker 84 var imageExtensionList = "*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp; *.heic" 85 86 var audioExtensionList = "*.aac; *.aif; *.flac; *.iff; *.m4a; *.m4b; *.mid; *.midi; *.mp3; *.mpa; *.mpc; *.oga; *.ogg; *.opus; *.ra; *.ram; *.snd; *.wav; *.wma" 87 88 var videoExtensionList = "*.avi; *.divx; *.flv; *.m4v; *.mkv; *.mov; *.mp4; *.mpeg; *.mpg; *.ogm; *.ogv; *.ogx; *.rm; *.rmvb; *.smil; *.webm; *.wmv; *.xvid" 89 90 // [ element name | number of filters | extension list or filter mask | filter index ] 91 var testData = [["a", 1, MockFilePicker.filterImages, 1], 92 ["b", 1, MockFilePicker.filterAudio, 1], 93 ["c", 1, MockFilePicker.filterVideo, 1], 94 ["d", 3, imageExtensionList + "; " + audioExtensionList, 1], 95 ["e", 3, imageExtensionList + "; " + videoExtensionList, 1], 96 ["f", 3, audioExtensionList + "; " + videoExtensionList, 1], 97 ["g", 4, imageExtensionList + "; " + audioExtensionList + "; " + videoExtensionList, 1], 98 ["h", 1, MockFilePicker.filterImages, 1], 99 ["i", 1, MockFilePicker.filterVideo, 1], 100 ["j", 1, MockFilePicker.filterAudio, 1], 101 ["k", 3, "*.gif; *.png", 1], 102 ["l", 4, imageExtensionList + "; " + "*.gif; *.png", 1], 103 ["m", 1, "*.gif", 1], 104 ["n", 0, undefined, 0], 105 ["o", 1, "*.test", 1], 106 ["p", 3, "*.gif; *.csv", 1], 107 ["q", 1, "*.gif", 1], 108 ["r", 3, "*.prefix; *.prefixPlusSomething", 1], 109 ["s", 3, "*.xls; *.xlsx", 1], 110 ["t", 4, "*.mp3; *.wav; *.flac", 1], 111 ["u", 3, "*.xls; *.xlsx", 1], 112 ["v", 3, "*.xlsx; *.xls", 1], 113 ["w", 0, undefined, 0], 114 ["x", 3, "*.xls; *.xlsx", 1], 115 ["y", 3, "*.xlsx; *.xls", 1], 116 ["z", 0, undefined, 0], 117 ["A", 1, "*.xlsx", 1], 118 // Note: mix and mix-ref tests extension lists are checked differently: see SimpleTest.executeSoon below 119 ["mix-ref", undefined, undefined, undefined], 120 ["mix", 1, undefined, 1], 121 ["hidden", 0, undefined, 0], 122 ["untrusted-click", 0, undefined, 0], 123 ["prevent-default", 0, undefined, 0, true], 124 ["prevent-default-false", 0, undefined, 0, true], 125 ["right-click", 0, undefined, 0, true], 126 ["middle-click", 0, undefined, 0, true], 127 ["left-click", 0, undefined, 0], 128 ["label-1", 0, undefined, 0], 129 ["label-2", 0, undefined, 0], 130 ["label-3", 0, undefined, 0], 131 ["label-4", 0, undefined, 0], 132 ["button-click", 0, undefined, 0], 133 ["button-down", 0, undefined, 0], 134 ["button-up", 0, undefined, 0], 135 ["div-click", 0, undefined, 0], 136 ["div-click-on-demand", 0, undefined, 0], 137 ["div-keydown", 0, undefined, 0], 138 ["link-click", 0, undefined, 0], 139 ["show-picker", 0, undefined, 0], 140 ]; 141 142 var currentTest = 0; 143 var filterAllAdded; 144 var filters; 145 var filterIndex; 146 var mixRefExtensionList; 147 148 // Make sure picker works with popup blocker enabled and no allowed events 149 SpecialPowers.pushPrefEnv({'set': [["dom.popup_allowed_events", ""]]}, runTests); 150 151 function launchNextTest() { 152 MockFilePicker.shown = false; 153 filterAllAdded = false; 154 filters = []; 155 filterIndex = 0; 156 157 // Focusing the element will scroll them into view so making sure the clicks 158 // will work. 159 document.getElementById(testData[currentTest][0]).focus(); 160 161 // Do not worry about user activation for these tests. 162 SpecialPowers.wrap(document).notifyUserGestureActivation(); 163 164 if (testData[currentTest][0] == "untrusted-click") { 165 var e = document.createEvent('MouseEvents'); 166 e.initEvent('click', true, false); 167 document.getElementById(testData[currentTest][0]).dispatchEvent(e); 168 // All tests that should *NOT* show a file picker. 169 } else if (testData[currentTest][0] == "prevent-default" || 170 testData[currentTest][0] == "prevent-default-false" || 171 testData[currentTest][0] == "right-click" || 172 testData[currentTest][0] == "middle-click") { 173 if (testData[currentTest][0] == "right-click" || 174 testData[currentTest][0] == "middle-click") { 175 var b = testData[currentTest][0] == "middle-click" ? 1 : 2; 176 synthesizeMouseAtCenter(document.getElementById(testData[currentTest][0]), 177 { button: b }); 178 } else { 179 if (testData[currentTest][0] == "prevent-default-false") { 180 document.getElementById(testData[currentTest][0]).onclick = function() { 181 return false; 182 }; 183 } else { 184 document.getElementById(testData[currentTest][0]).onclick = function(event) { 185 event.preventDefault(); 186 }; 187 } 188 document.getElementById(testData[currentTest][0]).click(); 189 } 190 191 // Wait a bit and assume we can continue. If the file picker shows later, 192 // behaviour is uncertain but that would be a random green, no big deal... 193 setTimeout(function() { 194 ok(true, "we should be there without a file picker being opened"); 195 ++currentTest; 196 launchNextTest(); 197 }, 500); 198 } else if (testData[currentTest][0] == 'label-3' || 199 testData[currentTest][0] == 'label-4') { 200 synthesizeMouse(document.getElementById(testData[currentTest][0]), 5, 5, {}); 201 } else if (testData[currentTest][0] == 'button-click' || 202 testData[currentTest][0] == 'button-down' || 203 testData[currentTest][0] == 'button-up' || 204 testData[currentTest][0] == 'div-click' || 205 testData[currentTest][0] == 'div-click-on-demand' || 206 testData[currentTest][0] == 'link-click') { 207 synthesizeMouseAtCenter(document.getElementById(testData[currentTest][0]), {}); 208 } else if (testData[currentTest][0] == 'div-keydown') { 209 sendString("a"); 210 } else if (testData[currentTest][0] == 'show-picker') { 211 document.getElementById(testData[currentTest][0]).showPicker(); 212 } else { 213 document.getElementById(testData[currentTest][0]).click(); 214 } 215 } 216 217 function runTests() { 218 MockFilePicker.appendFilterCallback = function(filepicker, title, val) { 219 filters.push(val); 220 }; 221 MockFilePicker.appendFiltersCallback = function(filepicker, val) { 222 if (val === MockFilePicker.filterAll) { 223 filterAllAdded = true; 224 } else { 225 filters.push(val); 226 } 227 }; 228 MockFilePicker.showCallback = function(filepicker) { 229 if (testData[currentTest][4]) { 230 ok(false, "we shouldn't have a file picker showing!"); 231 return; 232 } 233 234 filterIndex = filepicker.filterIndex; 235 testName = testData[currentTest][0]; 236 SimpleTest.executeSoon(function () { 237 ok(MockFilePicker.shown, 238 "File picker show method should have been called (" + testName + ")"); 239 ok(filterAllAdded, 240 "filterAll is missing (" + testName + ")"); 241 if (testName == "mix-ref") { 242 // Used only for reference for next test: nothing to be tested here 243 mixRefExtensionList = filters[0]; 244 if (mixRefExtensionList == undefined) { 245 mixRefExtensionList = ""; 246 } 247 } else { 248 if (testName == "mix") { 249 // Mixing mime type and file extension filters ("image/jpeg" and 250 // ".jpg" here) shouldn't restrict the list but only extend it, if file 251 // extension filter isn't a duplicate 252 ok(filters[0].includes(mixRefExtensionList), 253 "Mixing mime types and file extension filters shouldn't restrict extension list: " + 254 mixRefExtensionList + " | " + filters[0]); 255 ok(filters[0].includes("*.jpg"), 256 "Filter should contain '.jpg' extension. Filter was:" + filters[0]); 257 } else { 258 is(filters[0], testData[currentTest][2], 259 "Correct filters should have been added (" + testName + ")"); 260 is(filters.length, testData[currentTest][1], 261 "appendFilters not called as often as expected (" + testName + ")"); 262 } 263 is(filterIndex, testData[currentTest][3], 264 "File picker should show the correct filter index (" + testName + ")"); 265 } 266 267 if (++currentTest == testData.length) { 268 MockFilePicker.cleanup(); 269 SimpleTest.finish(); 270 } else { 271 launchNextTest(); 272 } 273 }); 274 }; 275 276 launchNextTest(); 277 } 278 279 </script> 280 </pre> 281 </body> 282 </html>