test_formSubmission.html (38315B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=523771 5 --> 6 <head> 7 <title>Test for Bug 523771</title> 8 <script src="/tests/SimpleTest/SimpleTest.js"></script> 9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 10 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 11 </head> 12 <body onload="bodyLoaded()"> 13 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=523771">Mozilla Bug 523771</a> 14 <p id="display"></p> 15 <iframe name="target_iframe" id="target_iframe"></iframe> 16 <form action="form_submit_server.sjs" target="target_iframe" id="form" 17 method="POST" enctype="multipart/form-data"> 18 <table> 19 <tr> 20 <td>Control type</td> 21 <td>Name and value</td> 22 <td>Name, empty value</td> 23 <td>Name, no value</td> 24 <td>Empty name, with value</td> 25 <td>No name, with value</td> 26 <td>No name or value</td> 27 <td>Strange name/value</td> 28 </tr> 29 <tr> 30 <td>Default input</td> 31 <td><input name="n1_1" value="v1_1"></td> 32 <td><input name="n1_2" value=""></td> 33 <td><input name="n1_3"></td> 34 <td><input name="" value="v1_4"></td> 35 <td><input value="v1_5"></td> 36 <td><input></td> 37 <td><input name="n1_7_ _ _ _ _"" 38 value="v1_7_ _ _ _ _""></td> 39 </tr> 40 <tr> 41 <td>Text input</td> 42 <td><input type=text name="n2_1" value="v2_1"></td> 43 <td><input type=text name="n2_2" value=""></td> 44 <td><input type=text name="n2_3"></td> 45 <td><input type=text name="" value="v2_4"></td> 46 <td><input type=text value="v2_5"></td> 47 <td><input type=text></td> 48 <td><input type=text name="n2_7_ _ _ _ _"" 49 value="v2_7_ _ _ _ _""></td> 50 </tr> 51 <tr> 52 <td>Checkbox unchecked</td> 53 <td><input type=checkbox name="n3_1" value="v3_1"></td> 54 <td><input type=checkbox name="n3_2" value=""></td> 55 <td><input type=checkbox name="n3_3"></td> 56 <td><input type=checkbox name="" value="v3_4"></td> 57 <td><input type=checkbox value="v3_5"></td> 58 <td><input type=checkbox></td> 59 <td><input type=checkbox name="n3_7_ _ _ _ _"" 60 value="v3_7_ _ _ _ _""></td> 61 </tr> 62 <tr> 63 <td>Checkbox checked</td> 64 <td><input checked type=checkbox name="n4_1" value="v4_1"></td> 65 <td><input checked type=checkbox name="n4_2" value=""></td> 66 <td><input checked type=checkbox name="n4_3"></td> 67 <td><input checked type=checkbox name="" value="v4_4"></td> 68 <td><input checked type=checkbox value="v4_5"></td> 69 <td><input checked type=checkbox></td> 70 <td><input checked type=checkbox 71 name="n4_7_ _ _ _ _"" 72 value="v4_7_ _ _ _ _""></td> 73 </tr> 74 <tr> 75 <td>Radio unchecked</td> 76 <td><input type=radio name="n5_1" value="v5_1"></td> 77 <td><input type=radio name="n5_2" value=""></td> 78 <td><input type=radio name="n5_3"></td> 79 <td><input type=radio name="" value="v5_4"></td> 80 <td><input type=radio value="v5_5"></td> 81 <td><input type=radio></td> 82 <td><input type=radio name="n5_7_ _ _ _ _"" 83 value="v5_7_ _ _ _ _""></td> 84 </tr> 85 <tr> 86 <td>Radio checked</td> 87 <td><input checked type=radio name="n6_1" value="v6_1"></td> 88 <td><input checked type=radio name="n6_2" value=""></td> 89 <td><input checked type=radio name="n6_3"></td> 90 <td><input checked type=radio name="" value="v6_4"></td> 91 <td><input checked type=radio value="v6_5"></td> 92 <td><input checked type=radio></td> 93 <td><input checked type=radio 94 name="n6_7_ _ _ _ _"" 95 value="v6_7_ _ _ _ _""></td> 96 </tr> 97 <tr> 98 <td>Hidden input</td> 99 <td><input type=hidden name="n7_1" value="v7_1"></td> 100 <td><input type=hidden name="n7_2" value=""></td> 101 <td><input type=hidden name="n7_3"></td> 102 <td><input type=hidden nane="" value="v7_4"></td> 103 <td><input type=hidden value="v7_5"></td> 104 <td><input type=hidden></td> 105 <td><input type=hidden name="n7_7_ _ _ _ _"" 106 value="v7_7_ _ _ _ _""></td> 107 </tr> 108 <tr> 109 <td>Password input</td> 110 <td><input type=password name="n8_1" value="v8_1"></td> 111 <td><input type=password name="n8_2" value=""></td> 112 <td><input type=password name="n8_3"></td> 113 <td><input type=password name="" value="v8_4"></td> 114 <td><input type=password value="v8_5"></td> 115 <td><input type=password></td> 116 <td><input type=password name="n8_7_ _ _ _ _"" 117 value="v8_7_ _ _ _ _""></td> 118 </tr> 119 <tr> 120 <td>Submit input</td> 121 <td><input type=submit name="n9_1" value="v9_1"></td> 122 <td><input type=submit name="n9_2" value=""></td> 123 <td><input type=submit name="n9_3"></td> 124 <td><input type=submit name="" value="v9_4"></td> 125 <td><input type=submit value="v9_5"></td> 126 <td><input type=submit></td> 127 <td><input type=submit name="n9_7_ _ _ _ _"" 128 value="v9_7_ _ _ _ _""></td> 129 </tr> 130 <tr> 131 <td>Button input</td> 132 <td><input type=button name="n10_1" value="v10_1"></td> 133 <td><input type=button name="n10_2" value=""></td> 134 <td><input type=button name="n10_3"></td> 135 <td><input type=button name="" value="v10_4"></td> 136 <td><input type=button value="v10_5"></td> 137 <td><input type=button></td> 138 <td><input type=button name="n10_7_ _ _ _ _"" 139 value="v10_7_ _ _ _ _""></td> 140 </tr> 141 <tr> 142 <td>Image input</td> 143 <td><input type=image src="file_formSubmission_img.jpg" name="n11_1" value="v11_1"></td> 144 <td><input type=image src="file_formSubmission_img.jpg" name="n11_2" value=""></td> 145 <td><input type=image src="file_formSubmission_img.jpg" name="n11_3"></td> 146 <td><input type=image src="file_formSubmission_img.jpg" name="" value="v11_4"></td> 147 <td><input type=image src="file_formSubmission_img.jpg" value="v11_5"></td> 148 <td><input type=image src="file_formSubmission_img.jpg"></td> 149 <td><input type=image src="file_formSubmission_img.jpg" 150 name="n11_7_ _ _ _ _"" 151 value="v11_7_ _ _ _ _""></td> 152 </tr> 153 <tr> 154 <td>Reset input</td> 155 <td><input type=reset name="n12_1" value="v12_1"></td> 156 <td><input type=reset name="n12_2" value=""></td> 157 <td><input type=reset name="n12_3"></td> 158 <td><input type=reset name="" value="v12_4"></td> 159 <td><input type=reset value="v12_5"></td> 160 <td><input type=reset></td> 161 <td><input type=reset name="n12_7_ _ _ _ _"" 162 value="v12_7_ _ _ _ _""></td> 163 </tr> 164 <tr> 165 <td>Unknown input</td> 166 <td><input type=foobar name="n13_1" value="v13_1"></td> 167 <td><input type=foobar name="n13_2" value=""></td> 168 <td><input type=foobar name="n13_3"></td> 169 <td><input type=foobar name="" value="v13_4"></td> 170 <td><input type=foobar value="v13_5"></td> 171 <td><input type=foobar></td> 172 <td><input type=foobar name="n13_7_ _ _ _ _"" 173 value="v13_7_ _ _ _ _""></td> 174 </tr> 175 <tr> 176 <td>Default button</td> 177 <td><button name="n14_1" value="v14_1"></button></td> 178 <td><button name="n14_2" value=""></button></td> 179 <td><button name="n14_3"></button></td> 180 <td><button name="" value="v14_4"></button></td> 181 <td><button value="v14_5"></button></td> 182 <td><button></button></td> 183 <td><button name="n14_7_ _ _ _ _"" 184 value="v14_7_ _ _ _ _""></button></td> 185 </tr> 186 <tr> 187 <td>Submit button</td> 188 <td><button type=submit name="n15_1" value="v15_1"></button></td> 189 <td><button type=submit name="n15_2" value=""></button></td> 190 <td><button type=submit name="n15_3"></button></td> 191 <td><button type=submit name="" value="v15_4"></button></td> 192 <td><button type=submit value="v15_5"></button></td> 193 <td><button type=submit></button></td> 194 <td><button type=submit name="n15_7_ _ _ _ _"" 195 value="v15_7_ _ _ _ _""></button></td> 196 </tr> 197 <tr> 198 <td>Button button</td> 199 <td><button type=button name="n16_1" value="v16_1"></button></td> 200 <td><button type=button name="n16_2" value=""></button></td> 201 <td><button type=button name="n16_3"></button></td> 202 <td><button type=button name="" value="v16_4"></button></td> 203 <td><button type=button value="v16_5"></button></td> 204 <td><button type=button></button></td> 205 <td><button type=button name="n16_7_ _ _ _ _"" 206 value="v16_7_ _ _ _ _""></button></td> 207 </tr> 208 <tr> 209 <td>Reset button</td> 210 <td><button type=reset name="n17_1" value="v17_1"></button></td> 211 <td><button type=reset name="n17_2" value=""></button></td> 212 <td><button type=reset name="n17_3"></button></td> 213 <td><button type=reset name="" value="v17_4"></button></td> 214 <td><button type=reset value="v17_5"></button></td> 215 <td><button type=reset></button></td> 216 <td><button type=reset name="n17_7_ _ _ _ _"" 217 value="v17_7_ _ _ _ _""></button></td> 218 </tr> 219 <tr> 220 <td>Unknown button</td> 221 <td><button type=foobar name="n18_1" value="v18_1"></button></td> 222 <td><button type=foobar name="n18_2" value=""></button></td> 223 <td><button type=foobar name="n18_3"></button></td> 224 <td><button type=foobar name="" value="v18_4"></button></td> 225 <td><button type=foobar value="v18_5"></button></td> 226 <td><button type=foobar ></button></td> 227 <td><button type=foobar name="n18_7_ _ _ _ _"" 228 value="v18_7_ _ _ _ _""></button></td> 229 </tr> 230 <tr> 231 <td><input type='url'></td> 232 <td><input type=url name="n19_1" value="http://v19_1.org"></td> 233 <td><input type=url name="n19_2" value=""></td> 234 <td><input type=url name="n19_3"></td> 235 <td><input type=url name="" value="http://v19_4.org"></td> 236 <td><input type=url value="http://v19_5.org"></td> 237 <td><input type=url ></td> 238 <td><input type=url name="n19_7_ _ _ __"" 239 value="http://v19_7_ _ _ __""> 240 <!-- Put UTF-8 value in the "strange" column. --> 241 <input type=url name="n19_8" value="http://mózillä.órg"></td> 242 </tr> 243 <tr> 244 <td><input type='email'></td> 245 <td><input type=email name="n20_1" value="v20_1@bar"></td> 246 <td><input type=email name="n20_2" value=""></td> 247 <td><input type=email name="n20_3"></td> 248 <td><input type=email name="" value="v20_4@bar"></td> 249 <td><input type=email value="v20_5@bar"></td> 250 <td><input type=email ></td> 251 <td><input type=email name="n20_7_ _ _ __"" 252 value="v20_7_ _ _ __"@bar"> 253 <!-- Put UTF-8 value is the "strange" column. --> 254 <input type=email name="n20_8" value="foo@mózillä.órg"></td> 255 </tr> 256 </table> 257 258 <p> 259 File input: 260 <input type=file name="file_1" class="setfile"> 261 <input type=file name="file_2"> 262 <input type=file name="" class="setfile"> 263 <input type=file name=""> 264 <input type=file class="setfile"> 265 <input type=file> 266 </p> 267 <p> 268 Multifile input: 269 <input multiple type=file name="file_3" class="setfile"> 270 <input multiple type=file name="file_4" class="setfile multi"> 271 <input multiple type=file name="file_5"> 272 <input multiple type=file name="" class="setfile"> 273 <input multiple type=file name="" class="setfile multi"> 274 <input multiple type=file name=""> 275 <input multiple type=file class="setfile"> 276 <input multiple type=file class="setfile multi"> 277 <input multiple type=file> 278 </p> 279 280 <p> 281 Textarea: 282 <textarea name="t1">t_1_v</textarea> 283 <textarea name="t2"></textarea> 284 <textarea name="">t_3_v</textarea> 285 <textarea>t_4_v</textarea> 286 <textarea></textarea> 287 <textarea name="t6"> 288 t_6_v</textarea> 289 <textarea name="t7">t_7_v 290 </textarea> 291 <textarea name="t8"> 292 293 t_8_v  294 </textarea> 295 <textarea name="t9_ _ _ _ _"">t_9_ _ _ _ _"_v</textarea> 296 <textarea name="t10" value="t_10_bogus">t_10_v</textarea> 297 </p> 298 299 <p> 300 Select one: 301 302 <select name="sel_1"></select> 303 <select name="sel_1b"><option></option></select> 304 <select name="sel_1c"><option selected></option></select> 305 306 <select name="sel_2"><option value="sel_2_v"></option></select> 307 <select name="sel_3"><option selected value="sel_3_v"></option></select> 308 309 <select name="sel_4"><option value="sel_4_v1"></option><option value="sel_4_v2"></option></select> 310 <select name="sel_5"><option selected value="sel_5_v1"></option><option value="sel_5_v2"></option></select> 311 <select name="sel_6"><option value="sel_6_v1"></option><option selected value="sel_6_v2"></option></select> 312 313 <select name="sel_7"><option>sel_7_v1</option><option>sel_7_v2</option></select> 314 <select name="sel_8"><option selected>sel_8_v1</option><option>sel_8_v2</option></select> 315 <select name="sel_9"><option>sel_9_v1</option><option selected>sel_9_v2</option></select> 316 317 <select name="sel_10"><option value="sel_10_v1">sel_10_v1_text</option><option value="sel_10_v2">sel_10_v2_text</option></select> 318 <select name="sel_11"><option selected value="sel_11_v1">sel_11_v1_text</option><option value="sel_11_v2">sel_11_v2_text</option></select> 319 <select name="sel_12"><option value="sel_12_v1">sel_12_v1_text</option><option selected value="sel_12_v2">sel_12_v2_text</option></select> 320 321 <select name="sel_13"><option disabled>sel_13_v1</option><option>sel_13_v2</option></select> 322 <select name="sel_14"><option disabled selected>sel_14_v1</option><option>sel_14_v2</option></select> 323 <select name="sel_15"><option disabled>sel_15_v1</option><option selected>sel_15_v2</option></select> 324 325 <select name="sel_16"><option>sel_16_v1</option><option disabled>sel_16_v2</option></select> 326 <select name="sel_17"><option selected>sel_17_v1</option><option disabled>sel_17_v2</option></select> 327 <select name="sel_18"><option>sel_18_v1</option><option disabled selected>sel_18_v2</option></select> 328 329 <select name=""><option selected value="sel_13_v1"></option><option value="sel_13_v2"></option></select> 330 <select name=""><option value="sel_14_v1"></option><option selected value="sel_14_v2"></option></select> 331 <select name=""><option selected>sel_15_v1</option><option>sel_15_v2</option></select> 332 <select name=""><option>sel_16_v1</option><option selected>sel_16_v2</option></select> 333 334 <select><option selected value="sel_17_v1"></option><option value="sel_17_v2"></option></select> 335 <select><option value="sel_18_v1"></option><option selected value="sel_18_v2"></option></select> 336 <select><option selected>sel_19_v1</option><option>sel_19_v2</option></select> 337 <select><option>sel_20_v1</option><option selected>sel_20_v2</option></select> 338 </p> 339 340 <p> 341 Select multiple: 342 343 <select multiple name="msel_1"></select> 344 <select multiple name="msel_1b"><option></option></select> 345 <select multiple name="msel_1c"><option selected></option></select> 346 347 <select multiple name="msel_2"><option value="msel_2_v"></option></select> 348 <select multiple name="msel_3"><option selected value="msel_3_v"></option></select> 349 350 <select multiple name="msel_4"><option value="msel_4_v1"></option><option value="msel_4_v2"></option></select> 351 <select multiple name="msel_5"><option selected value="msel_5_v1"></option><option value="msel_5_v2"></option></select> 352 <select multiple name="msel_6"><option value="msel_6_v1"></option><option selected value="msel_6_v2"></option></select> 353 <select multiple name="msel_7"><option selected value="msel_7_v1"></option><option selected value="msel_7_v2"></option></select> 354 355 <select multiple name="msel_8"><option>msel_8_v1</option><option>msel_8_v2</option></select> 356 <select multiple name="msel_9"><option selected>msel_9_v1</option><option>msel_9_v2</option></select> 357 <select multiple name="msel_10"><option>msel_10_v1</option><option selected>msel_10_v2</option></select> 358 <select multiple name="msel_11"><option selected>msel_11_v1</option><option selected>msel_11_v2</option></select> 359 360 <select multiple name="msel_12"><option value="msel_12_v1">msel_12_v1_text</option><option value="msel_12_v2">msel_12_v2_text</option></select> 361 <select multiple name="msel_13"><option selected value="msel_13_v1">msel_13_v1_text</option><option value="msel_13_v2">msel_13_v2_text</option></select> 362 <select multiple name="msel_14"><option value="msel_14_v1">msel_14_v1_text</option><option selected value="msel_14_v2">msel_14_v2_text</option></select> 363 <select multiple name="msel_15"><option selected value="msel_15_v1">msel_15_v1_text</option><option selected value="msel_15_v2">msel_15_v2_text</option></select> 364 365 <select multiple name="msel_16"><option>msel_16_v1</option><option>msel_16_v2</option><option>msel_16_v3</option></select> 366 <select multiple name="msel_17"><option selected>msel_17_v1</option><option>msel_17_v2</option><option>msel_17_v3</option></select> 367 <select multiple name="msel_18"><option>msel_18_v1</option><option selected>msel_18_v2</option><option>msel_18_v3</option></select> 368 <select multiple name="msel_19"><option selected>msel_19_v1</option><option selected>msel_19_v2</option><option>msel_19_v3</option></select> 369 <select multiple name="msel_20"><option>msel_20_v1</option><option>msel_20_v2</option><option selected>msel_20_v3</option></select> 370 <select multiple name="msel_21"><option selected>msel_21_v1</option><option>msel_21_v2</option><option selected>msel_21_v3</option></select> 371 <select multiple name="msel_22"><option>msel_22_v1</option><option selected>msel_22_v2</option><option selected>msel_22_v3</option></select> 372 <select multiple name="msel_23"><option selected>msel_23_v1</option><option selected>msel_23_v2</option><option selected>msel_23_v3</option></select> 373 374 <select multiple name="msel_24"><option disabled>msel_24_v1</option><option>msel_24_v2</option></select> 375 <select multiple name="msel_25"><option disabled selected>msel_25_v1</option><option>msel_25_v2</option></select> 376 <select multiple name="msel_26"><option disabled>msel_26_v1</option><option selected>msel_26_v2</option></select> 377 <select multiple name="msel_27"><option disabled selected>msel_27_v1</option><option selected>msel_27_v2</option></select> 378 379 <select multiple name="msel_28"><option>msel_28_v1</option><option disabled>msel_28_v2</option></select> 380 <select multiple name="msel_29"><option selected>msel_29_v1</option><option disabled>msel_29_v2</option></select> 381 <select multiple name="msel_30"><option>msel_30_v1</option><option disabled selected>msel_30_v2</option></select> 382 <select multiple name="msel_31"><option selected>msel_31_v1</option><option disabled selected>msel_31_v2</option></select> 383 384 <select multiple name="msel_32"><option disabled selected>msel_32_v1</option><option disabled selected>msel_32_v2</option></select> 385 386 <select multiple name=""><option>msel_33_v1</option><option>msel_33_v2</option></select> 387 <select multiple name=""><option selected>msel_34_v1</option><option>msel_34_v2</option></select> 388 <select multiple name=""><option>msel_35_v1</option><option selected>msel_35_v2</option></select> 389 <select multiple name=""><option selected>msel_36_v1</option><option selected>msel_36_v2</option></select> 390 391 <select multiple><option>msel_37_v1</option><option>msel_37_v2</option></select> 392 <select multiple><option selected>msel_38_v1</option><option>msel_38_v2</option></select> 393 <select multiple><option>msel_39_v1</option><option selected>msel_39_v2</option></select> 394 <select multiple><option selected>msel_40_v1</option><option selected>msel_40_v2</option></select> 395 </p> 396 </form> 397 <pre id="test"> 398 <script class="testbody" type="text/javascript"> 399 400 SimpleTest.waitForExplicitFinish(); 401 402 const placeholder_myFile1 = {}; 403 const placeholder_myFile2 = {}; 404 const placeholder_emptyFile = {}; 405 406 var myFile1, myFile2, emptyFile; 407 let openerURL, opener; 408 var gen; 409 410 function bodyLoaded() { 411 openerURL = SimpleTest.getTestFileURL("formSubmission_chrome.js"); 412 opener = SpecialPowers.loadChromeScript(openerURL); 413 414 let xhr = new XMLHttpRequest; 415 xhr.open("GET", "/dynamic/getMyDirectory.sjs", false); 416 xhr.send(); 417 let basePath = xhr.responseText; 418 419 opener.addMessageListener("files.opened", onFilesOpened); 420 opener.sendAsyncMessage("files.open", [ 421 basePath + "file_formSubmission_text.txt", 422 basePath + "file_formSubmission_img.jpg", 423 ]); 424 425 /* 426 * The below test function uses callbacks that invoke gen.next() rather than 427 * creating and resolving Promises. I'm trying to minimize churn since these 428 * changes want to be uplifted. Some kind soul might want to clean this all up 429 * at some point. 430 */ 431 432 $("target_iframe").onload = function() { gen.next(); }; 433 } 434 435 436 function onFilesOpened(files) { 437 let [textFile, imageFile] = files; 438 opener.destroy(); 439 440 let singleFile = textFile; 441 let multiFile = [textFile, imageFile]; 442 443 var addList = document.getElementsByClassName("setfile"); 444 let i = 0; 445 var input; 446 while ((input = addList[i++])) { 447 if (input.classList.contains("multi")) { 448 SpecialPowers.wrap(input).mozSetFileArray(multiFile); 449 } else { 450 SpecialPowers.wrap(input).mozSetFileArray([singleFile]); 451 } 452 } 453 454 input = document.createElement("input"); 455 input.type = "file"; 456 input.multiple = true; 457 SpecialPowers.wrap(input).mozSetFileArray(multiFile); 458 myFile1 = input.files[0]; 459 myFile2 = input.files[1]; 460 is(myFile1.size, 20, "File1 size"); 461 is(myFile2.size, 2711, "File2 size"); 462 emptyFile = { name: "", type: "application/octet-stream" }; 463 464 // Now, actually run the tests; see below. 465 runAllTestVariants(); 466 }; 467 468 var expectedSub = [ 469 // Default input 470 { name: "n1_1", value: "v1_1" }, 471 { name: "n1_2", value: "" }, 472 { name: "n1_3", value: "" }, 473 { name: "n1_7_\r\n_\r\n_\r\n_ _\"", value: "v1_7____ _\"" }, 474 // Text input 475 { name: "n2_1", value: "v2_1" }, 476 { name: "n2_2", value: "" }, 477 { name: "n2_3", value: "" }, 478 { name: "n2_7_\r\n_\r\n_\r\n_ _\"", value: "v2_7____ _\"" }, 479 // Checkbox unchecked 480 // Checkbox checked 481 { name: "n4_1", value: "v4_1" }, 482 { name: "n4_2", value: "" }, 483 { name: "n4_3", value: "on" }, 484 { name: "n4_7_\r\n_\r\n_\r\n_ _\"", value: "v4_7_\r\n_\r\n_\r\n_ _\"" }, 485 // Radio unchecked 486 // Radio checked 487 { name: "n6_1", value: "v6_1" }, 488 { name: "n6_2", value: "" }, 489 { name: "n6_3", value: "on" }, 490 { name: "n6_7_\r\n_\r\n_\r\n_ _\"", value: "v6_7_\r\n_\r\n_\r\n_ _\"" }, 491 // Hidden input 492 { name: "n7_1", value: "v7_1" }, 493 { name: "n7_2", value: "" }, 494 { name: "n7_3", value: "" }, 495 { name: "n7_7_\r\n_\r\n_\r\n_ _\"", value: "v7_7_\r\n_\r\n_\r\n_ _\"" }, 496 // Password input 497 { name: "n8_1", value: "v8_1" }, 498 { name: "n8_2", value: "" }, 499 { name: "n8_3", value: "" }, 500 { name: "n8_7_\r\n_\r\n_\r\n_ _\"", value: "v8_7____ _\"" }, 501 // Submit input 502 // Button input 503 // Image input 504 // Reset input 505 // Unknown input 506 { name: "n13_1", value: "v13_1" }, 507 { name: "n13_2", value: "" }, 508 { name: "n13_3", value: "" }, 509 { name: "n13_7_\r\n_\r\n_\r\n_ _\"", value: "v13_7____ _\"" }, 510 // <input type='url'> 511 { name: "n19_1", value: "http://v19_1.org" }, 512 { name: "n19_2", value: "" }, 513 { name: "n19_3", value: "" }, 514 { name: "n19_7_\r\n_\r\n_\r\n__\"", value: "http://v19_7_____\"" }, 515 { name: "n19_8", value: "http://m\xf3zill\xe4.\xf3rg" }, 516 // <input type='email'> 517 { name: "n20_1", value: "v20_1@bar" }, 518 { name: "n20_2", value: "" }, 519 { name: "n20_3", value: "" }, 520 { name: "n20_7_\r\n_\r\n_\r\n__\"", value: "v20_7_____\"@bar" }, 521 { name: "n20_8", value: "foo@mózillä.órg" }, 522 // Default button 523 // Submit button 524 // Button button 525 // Reset button 526 // Unknown button 527 // File 528 { name: "file_1", value: placeholder_myFile1 }, 529 { name: "file_2", value: placeholder_emptyFile }, 530 // Multiple file 531 { name: "file_3", value: placeholder_myFile1 }, 532 { name: "file_4", value: placeholder_myFile1 }, 533 { name: "file_4", value: placeholder_myFile2 }, 534 { name: "file_5", value: placeholder_emptyFile }, 535 // Textarea 536 { name: "t1", value: "t_1_v" }, 537 { name: "t2", value: "" }, 538 { name: "t6", value: "t_6_v" }, 539 { name: "t7", value: "t_7_v\r\n" }, 540 { name: "t8", value: "\r\n t_8_v \r\n" }, 541 { name: "t9_\r\n_\r\n_\r\n_ _\"", value: "t_9_\r\n_\r\n_\r\n_ _\"_v" }, 542 { name: "t10", value: "t_10_v" }, 543 544 // Select one 545 { name: "sel_1b", value: "" }, 546 { name: "sel_1c", value: "" }, 547 { name: "sel_2", value: "sel_2_v" }, 548 { name: "sel_3", value: "sel_3_v" }, 549 { name: "sel_4", value: "sel_4_v1" }, 550 { name: "sel_5", value: "sel_5_v1" }, 551 { name: "sel_6", value: "sel_6_v2" }, 552 { name: "sel_7", value: "sel_7_v1" }, 553 { name: "sel_8", value: "sel_8_v1" }, 554 { name: "sel_9", value: "sel_9_v2" }, 555 { name: "sel_10", value: "sel_10_v1" }, 556 { name: "sel_11", value: "sel_11_v1" }, 557 { name: "sel_12", value: "sel_12_v2" }, 558 { name: "sel_13", value: "sel_13_v2" }, 559 { name: "sel_15", value: "sel_15_v2" }, 560 { name: "sel_16", value: "sel_16_v1" }, 561 { name: "sel_17", value: "sel_17_v1" }, 562 // Select three 563 { name: "msel_1c", value: "" }, 564 { name: "msel_3", value: "msel_3_v" }, 565 { name: "msel_5", value: "msel_5_v1" }, 566 { name: "msel_6", value: "msel_6_v2" }, 567 { name: "msel_7", value: "msel_7_v1" }, 568 { name: "msel_7", value: "msel_7_v2" }, 569 { name: "msel_9", value: "msel_9_v1" }, 570 { name: "msel_10", value: "msel_10_v2" }, 571 { name: "msel_11", value: "msel_11_v1" }, 572 { name: "msel_11", value: "msel_11_v2" }, 573 { name: "msel_13", value: "msel_13_v1" }, 574 { name: "msel_14", value: "msel_14_v2" }, 575 { name: "msel_15", value: "msel_15_v1" }, 576 { name: "msel_15", value: "msel_15_v2" }, 577 { name: "msel_17", value: "msel_17_v1" }, 578 { name: "msel_18", value: "msel_18_v2" }, 579 { name: "msel_19", value: "msel_19_v1" }, 580 { name: "msel_19", value: "msel_19_v2" }, 581 { name: "msel_20", value: "msel_20_v3" }, 582 { name: "msel_21", value: "msel_21_v1" }, 583 { name: "msel_21", value: "msel_21_v3" }, 584 { name: "msel_22", value: "msel_22_v2" }, 585 { name: "msel_22", value: "msel_22_v3" }, 586 { name: "msel_23", value: "msel_23_v1" }, 587 { name: "msel_23", value: "msel_23_v2" }, 588 { name: "msel_23", value: "msel_23_v3" }, 589 { name: "msel_26", value: "msel_26_v2" }, 590 { name: "msel_27", value: "msel_27_v2" }, 591 { name: "msel_29", value: "msel_29_v1" }, 592 { name: "msel_31", value: "msel_31_v1" }, 593 ]; 594 595 var expectedAugment = [ 596 { name: "aName", value: "aValue" }, 597 //{ name: "aNameBool", value: "false" }, 598 { name: "aNameNum", value: "9.2" }, 599 { name: "aNameFile1", value: placeholder_myFile1 }, 600 { name: "aNameFile2", value: placeholder_myFile2 }, 601 //{ name: "aNameObj", value: "[object XMLHttpRequest]" }, 602 //{ name: "aNameNull", value: "null" }, 603 //{ name: "aNameUndef", value: "undefined" }, 604 ]; 605 606 function checkMPSubmission(sub, expected, test) { 607 function getPropCount(o) { 608 var x, l = 0; 609 for (x in o) ++l; 610 return l; 611 } 612 function mpquote_name(s) { 613 return s.replace(/\r?\n|\r/g, "%0D%0A") 614 .replace(/\"/g, "%22"); 615 } 616 function mpquote_filename(s) { 617 return s.replace(/\r/g, "%0D") 618 .replace(/\n/g, "%0A") 619 .replace(/\"/g, "%22"); 620 } 621 622 is(sub.length, expected.length, 623 "Correct number of multipart items in " + test); 624 625 if (sub.length != expected.length) { 626 alert(JSON.stringify(sub)); 627 } 628 629 var i; 630 for (i = 0; i < expected.length; ++i) { 631 if (!("fileName" in expected[i])) { 632 is(sub[i].headers["Content-Disposition"], 633 "form-data; name=\"" + mpquote_name(expected[i].name) + "\"", 634 "Correct name in " + test); 635 is (getPropCount(sub[i].headers), 1, 636 "Wrong number of headers in " + test); 637 is(sub[i].body, 638 expected[i].value.replace(/\r\n|\r|\n/, "\r\n"), 639 "Correct value in " + test); 640 } 641 else { 642 is(sub[i].headers["Content-Disposition"], 643 "form-data; name=\"" + mpquote_name(expected[i].name) + "\"; filename=\"" + 644 mpquote_filename(expected[i].fileName) + "\"", 645 "Correct name in " + test); 646 is(sub[i].headers["Content-Type"], 647 expected[i].contentType, 648 "Correct content type in " + test); 649 is (getPropCount(sub[i].headers), 2, 650 "Wrong number of headers in " + test); 651 is(sub[i].body, 652 expected[i].value, 653 "Correct value in " + test); 654 } 655 } 656 } 657 658 function utf8encode(s) { 659 return unescape(encodeURIComponent(s)); 660 } 661 662 function checkURLSubmission(sub, expected) { 663 function urlEscape(s) { 664 return escape(utf8encode(s)).replace(/%20/g, "+") 665 .replace(/\//g, "%2F") 666 .replace(/@/g, "%40"); 667 } 668 669 subItems = sub.split("&"); 670 is(subItems.length, expected.length, 671 "Correct number of url items"); 672 var i; 673 for (i = 0; i < expected.length; ++i) { 674 let expect = urlEscape(expected[i].name) + "=" + 675 urlEscape(("fileName" in expected[i]) ? expected[i].fileName : expected[i].value); 676 is (subItems[i], expect, "expected URL part"); 677 } 678 } 679 680 function checkPlainSubmission(sub, expected) { 681 682 is(sub, 683 expected.map(function(v) { 684 return v.name + "=" + 685 (("fileName" in v) ? v.fileName : v.value) + 686 "\r\n"; 687 }).join(""), 688 "Correct submission"); 689 } 690 691 function setDisabled(list, state) { 692 Array.prototype.forEach.call(list, function(e) { 693 e.disabled = state; 694 }); 695 } 696 697 // Run the suite of tests for this variant, returning a Promise that will be 698 // resolved when the batch completes. Then and only then runTestVariant may 699 // be invoked to run a different variation. 700 function runTestVariant(variantLabel) { 701 info("starting test variant: " + variantLabel); 702 return new Promise((resolve) => { 703 // Instantiate the generator. 704 gen = runTestVariantUsingWeirdGenDriver(resolve); 705 // Run the generator to the first yield, at which point it is self-driving. 706 gen.next(); 707 }); 708 } 709 function* runTestVariantUsingWeirdGenDriver(finishedVariant) { 710 // Set up the expectedSub array 711 fileReader1 = new FileReader; 712 fileReader1.readAsBinaryString(myFile1); 713 fileReader2 = new FileReader; 714 fileReader2.readAsBinaryString(myFile2); 715 fileReader1.onload = fileReader2.onload = function() { gen.next(); }; 716 yield undefined; // Wait for both FileReaders. We don't care which order they finish. 717 yield undefined; 718 function fileFixup(o) { 719 if (o.value === placeholder_myFile1) { 720 o.value = fileReader1.result; 721 o.fileName = myFile1.name; 722 o.contentType = myFile1.type; 723 } 724 else if (o.value === placeholder_myFile2) { 725 o.value = fileReader2.result; 726 o.fileName = myFile2.name; 727 o.contentType = myFile2.type; 728 } 729 else if (o.value === placeholder_emptyFile) { 730 o.value = ""; 731 o.fileName = emptyFile.name; 732 o.contentType = emptyFile.type; 733 } 734 }; 735 expectedSub.forEach(fileFixup); 736 expectedAugment.forEach(fileFixup); 737 738 var form = $("form"); 739 740 // multipart/form-data 741 var iframe = $("target_iframe"); 742 743 // Make normal submission 744 form.action = "form_submit_server.sjs"; 745 form.method = "POST"; 746 form.enctype = "multipart/form-data"; 747 form.submit(); 748 yield undefined; // Wait for iframe to load as a result of the submission 749 var submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 750 checkMPSubmission(submission, expectedSub, "normal submission"); 751 752 // Disabled controls 753 setDisabled(document.querySelectorAll("input, select, textarea"), true); 754 form.submit(); 755 yield undefined; 756 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 757 checkMPSubmission(submission, [], "disabled controls"); 758 759 // Reenabled controls 760 setDisabled(document.querySelectorAll("input, select, textarea"), false); 761 form.submit(); 762 yield undefined; 763 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 764 checkMPSubmission(submission, expectedSub, "reenabled controls"); 765 766 // text/plain 767 form.action = "form_submit_server.sjs?plain"; 768 form.enctype = "text/plain"; 769 form.submit(); 770 yield undefined; 771 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 772 checkPlainSubmission(submission, expectedSub); 773 774 // application/x-www-form-urlencoded 775 form.action = "form_submit_server.sjs?url"; 776 form.enctype = "application/x-www-form-urlencoded"; 777 form.submit(); 778 yield undefined; 779 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 780 checkURLSubmission(submission, expectedSub); 781 782 // application/x-www-form-urlencoded 783 form.action = "form_submit_server.sjs?xxyy"; 784 form.method = "GET"; 785 form.enctype = ""; 786 form.submit(); 787 yield undefined; 788 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 789 checkURLSubmission(submission, expectedSub); 790 791 // application/x-www-form-urlencoded 792 form.action = "form_submit_server.sjs"; 793 form.method = ""; 794 form.enctype = ""; 795 form.submit(); 796 yield undefined; 797 submission = JSON.parse(iframe.contentDocument.documentElement.textContent); 798 checkURLSubmission(submission, expectedSub); 799 800 // Send form using XHR and FormData 801 xhr = new XMLHttpRequest(); 802 xhr.onload = function() { gen.next(); }; 803 xhr.open("POST", "form_submit_server.sjs"); 804 xhr.send(new FormData(form)); 805 yield undefined; // Wait for XHR load 806 checkMPSubmission(JSON.parse(xhr.responseText), expectedSub, "send form using XHR and FormData"); 807 808 // Send disabled form using XHR and FormData 809 setDisabled(document.querySelectorAll("input, select, textarea"), true); 810 xhr.open("POST", "form_submit_server.sjs"); 811 xhr.send(new FormData(form)); 812 yield undefined; 813 checkMPSubmission(JSON.parse(xhr.responseText), [], "send disabled form using XHR and FormData"); 814 setDisabled(document.querySelectorAll("input, select, textarea"), false); 815 816 // Send FormData 817 function addToFormData(fd) { 818 fd.append("aName", "aValue"); 819 fd.append("aNameNum", 9.2); 820 fd.append("aNameFile1", myFile1); 821 fd.append("aNameFile2", myFile2); 822 } 823 var fd = new FormData(); 824 addToFormData(fd); 825 xhr.open("POST", "form_submit_server.sjs"); 826 xhr.send(fd); 827 yield undefined; 828 checkMPSubmission(JSON.parse(xhr.responseText), expectedAugment, "send FormData"); 829 830 // Augment <form> using FormData 831 fd = new FormData(form); 832 addToFormData(fd); 833 xhr.open("POST", "form_submit_server.sjs"); 834 xhr.send(fd); 835 yield undefined; 836 checkMPSubmission(JSON.parse(xhr.responseText), 837 expectedSub.concat(expectedAugment), "send augmented FormData"); 838 839 finishedVariant(); 840 } 841 842 /** 843 * Install our service-worker (parameterized by appending "?MODE"), which will 844 * invoke skipWaiting() and clients.claim() to begin controlling us ASAP. We 845 * wait on the controllerchange event 846 */ 847 async function installAndBeControlledByServiceWorker(mode) { 848 const scriptURL = "sw_formSubmission.js?" + mode; 849 const controllerChanged = new Promise((resolve) => { 850 navigator.serviceWorker.addEventListener( 851 "controllerchange", () => { resolve(); }, { once: true }); 852 }); 853 854 info("installing ServiceWorker: " + scriptURL); 855 const swr = await navigator.serviceWorker.register(scriptURL, 856 { scope: "./" }); 857 await controllerChanged; 858 ok(navigator.serviceWorker.controller.scriptURL.endsWith(scriptURL), 859 "controlled by the SW we expected"); 860 info("became controlled by ServiceWorker."); 861 862 return swr; 863 } 864 865 async function runAllTestVariants() { 866 // Run the test as it has historically been run, with no ServiceWorkers 867 // anywhere! 868 await runTestVariant("no ServiceWorker"); 869 870 // Uncomment the below if something in the test seems broken and you're not 871 // sure whether it's a side-effect of the multiple passes or not. 872 //await runTestVariant("no ServiceWorker second paranoia time"); 873 874 // Ensure ServiceWorkers are enabled and that testing mode (which disables 875 // security checks) is on too. 876 await SpecialPowers.pushPrefEnv({"set": [ 877 ["dom.serviceWorkers.enabled", true], 878 ["dom.serviceWorkers.testing.enabled", true] 879 ]}); 880 881 // Now run the test with a ServiceWorker that covers the scope but has no 882 // fetch handler, so the optimization case will not actually dispatch a 883 // "fetch" event, but some stuff will happen that can change things enough 884 // to break them like in https://bugzilla.mozilla.org/show_bug.cgi?id=1383518. 885 await installAndBeControlledByServiceWorker("no-fetch"); 886 await runTestVariant("ServiceWorker that does not listen for fetch events"); 887 888 // Now the ServiceWorker does have a "fetch" event listener, but it will reset 889 // interception every time. This is similar to the prior case but different 890 // enough that it could break things in a different exciting way. 891 await installAndBeControlledByServiceWorker("reset-fetch"); 892 await runTestVariant("ServiceWorker that resets all fetches"); 893 894 // Now the ServiceWorker resolves the fetch event with `fetch(event.request)` 895 // which makes little sense but is a thing that can happen. 896 const swr = await installAndBeControlledByServiceWorker("proxy-fetch"); 897 await runTestVariant("ServiceWorker that proxies all fetches"); 898 899 // cleanup. 900 info("unregistering ServiceWorker"); 901 await swr.unregister(); 902 info("ServiceWorker uninstalled"); 903 904 SimpleTest.finish(); 905 } 906 907 </script> 908 </pre> 909 </body> 910 </html>