@@ -339,21 +339,21 @@ public void resetByClick() throws Exception {
339339 + " var file = document.getElementById('testId');\n "
340340 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
341341
342- + " document.getElementById('testReset').click;\n "
342+ + " document.getElementById('testReset').click() ;\n "
343343 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
344344
345345 + " try{\n "
346346 + " file.value = 'newValue';\n "
347347 + " } catch(e) { logEx(e); }\n "
348348 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
349349
350- + " document.getElementById('testReset').click;\n "
350+ + " document.getElementById('testReset').click() ;\n "
351351 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
352352
353353 + " file.defaultValue = 'newDefault';\n "
354354 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
355355
356- + " document.forms[0].reset;\n "
356+ + " document.forms[0].reset() ;\n "
357357 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
358358 + " }\n "
359359 + "</script>\n "
@@ -383,21 +383,21 @@ public void resetByJS() throws Exception {
383383 + " var file = document.getElementById('testId');\n "
384384 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
385385
386- + " document.forms[0].reset;\n "
386+ + " document.forms[0].reset() ;\n "
387387 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
388388
389389 + " try{\n "
390390 + " file.value = 'newValue';\n "
391391 + " } catch(e) { logEx(e); }\n "
392392 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
393393
394- + " document.forms[0].reset;\n "
394+ + " document.forms[0].reset() ;\n "
395395 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
396396
397397 + " file.defaultValue = 'newDefault';\n "
398398 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
399399
400- + " document.forms[0].reset;\n "
400+ + " document.forms[0].reset() ;\n "
401401 + " log(file.value + '-' + file.defaultValue + '-' + file.getAttribute('value'));\n "
402402 + " }\n "
403403 + "</script>\n "
@@ -896,6 +896,20 @@ public void validationRequired() throws Exception {
896896 validation ("<input type='file' id='e1' required>\n " , "" );
897897 }
898898
899+ /**
900+ * A DISABLED + required file input with no files selected must
901+ * still report itself as valid, since disabled fields are barred from
902+ * constraint validation entirely.
903+ * @throws Exception if an error occurs
904+ */
905+ @ Test
906+ @ Alerts ({"true" ,
907+ "false-false-false-false-false-false-false-false-false-false-true" ,
908+ "false" })
909+ public void validationRequiredDisabled () throws Exception {
910+ validation ("<input type='file' id='e1' required disabled>\n " , "" );
911+ }
912+
899913 private void validation (final String htmlPart , final String jsPart ) throws Exception {
900914 final String html = DOCTYPE_HTML
901915 + "<html><head>\n "
@@ -1021,4 +1035,118 @@ public void valueWebkitdirectory() throws Exception {
10211035 driver .findElement (By .id ("clickMe" )).click ();
10221036 verifyTitle2 (driver , getExpectedAlerts ());
10231037 }
1038+
1039+ /**
1040+ * Method reset() must not fire a change event, and must not try to
1041+ * resurrect a fake File from the 'value' attribute. This uses
1042+ * a REAL file selection (via sendKeys) so reset() has something genuine to
1043+ * clear, and counts onchange firings across the whole sequence.
1044+ * @throws Exception if the test fails
1045+ */
1046+ @ Test
1047+ @ Alerts ({"0-1" })
1048+ public void resetClearsRealFileSelectionWithoutSpuriousChange () throws Exception {
1049+ final String html = DOCTYPE_HTML
1050+ + "<html><body>\n "
1051+ + "<script>\n "
1052+ + LOG_TITLE_FUNCTION
1053+ + "var changeCount = 0;\n "
1054+ + "</script>\n "
1055+ + "<form id='form1'>\n "
1056+ + " <input type='file' id='f' onchange='changeCount++;'>\n "
1057+ + " <input type='reset' id='resetBtn'>\n "
1058+ + "</form>\n "
1059+ + "<button id='check' onclick='"
1060+ + "log(document.getElementById(\" f\" ).files.length + \" -\" + changeCount);"
1061+ + "'>check</button>\n "
1062+ + "</body></html>" ;
1063+
1064+ final WebDriver driver = loadPage2 (html );
1065+ final File tmpFile = File .createTempFile ("htmlunit-test" , ".txt" );
1066+ try {
1067+ driver .findElement (By .id ("f" )).sendKeys (tmpFile .getAbsolutePath ());
1068+ }
1069+ finally {
1070+ assertTrue (tmpFile .delete ());
1071+ }
1072+
1073+ driver .findElement (By .id ("resetBtn" )).click ();
1074+ driver .findElement (By .id ("check" )).click ();
1075+
1076+ verifyTitle2 (driver , getExpectedAlerts ());
1077+ }
1078+
1079+ /**
1080+ * Calling reset() on a file input that was NEVER touched (no real selection made)
1081+ * must be a true no-op -- specifically must NOT fire a change event, since
1082+ * nothing actually changed.
1083+ * @throws Exception if the test fails
1084+ */
1085+ @ Test
1086+ @ Alerts ({"0" })
1087+ public void resetOnNeverTouchedFileInput_noChangeEventFired () throws Exception {
1088+ final String html = DOCTYPE_HTML
1089+ + "<html><head>\n "
1090+ + "<script>\n "
1091+ + LOG_TITLE_FUNCTION
1092+ + " function test() {\n "
1093+ + " document.getElementById('resetBtn').click();\n "
1094+ + " log(document.getElementById('f').files.length);\n "
1095+ + " }\n "
1096+ + "</script>\n "
1097+ + "</head>\n "
1098+ + "<body>\n "
1099+ + "<form id='form1'>\n "
1100+ + " <input type='file' id='f' onchange='log(\" unexpected change\" );'>\n "
1101+ + " <input type='reset' id='resetBtn'>\n "
1102+ + "</form>\n "
1103+ + "<button id='go' onclick='test()'>go</button>\n "
1104+ + "</body></html>" ;
1105+
1106+ final WebDriver driver = loadPage2 (html );
1107+ driver .findElement (By .id ("go" )).click ();
1108+
1109+ verifyTitle2 (DEFAULT_WAIT_TIME , driver , getExpectedAlerts ());
1110+ }
1111+
1112+ /**
1113+ * Changing the 'type' attribute of an
1114+ * input away from 'file' and then back to 'file' should leave it with an
1115+ * empty value/file selection, not retain a stale selection from before the
1116+ * type change.
1117+ * @throws Exception if an error occurs
1118+ */
1119+ @ Test
1120+ @ Alerts ({"" , "0" })
1121+ public void changingTypeAwayFromFileAndBackClearsSelection () throws Exception {
1122+ final String html = DOCTYPE_HTML
1123+ + "<html><head>\n "
1124+ + "<script>\n "
1125+ + LOG_TITLE_FUNCTION
1126+ + " function test() {\n "
1127+ + " var input = document.getElementById('f');\n "
1128+ + " input.type = 'text';\n "
1129+ + " input.type = 'file';\n "
1130+ + " log(input.value);\n "
1131+ + " log(input.files.length);\n "
1132+ + " }\n "
1133+ + "</script>\n "
1134+ + "</head>\n "
1135+ + "<body>\n "
1136+ + " <input type='file' id='f'>\n "
1137+ + " <button id='go' onclick='test()'>go</button>\n "
1138+ + "</body></html>" ;
1139+
1140+ final WebDriver driver = loadPage2 (html );
1141+ final File tmpFile = File .createTempFile ("htmlunit-test" , ".txt" );
1142+ try {
1143+ driver .findElement (By .id ("f" )).sendKeys (tmpFile .getAbsolutePath ());
1144+ }
1145+ finally {
1146+ assertTrue (tmpFile .delete ());
1147+ }
1148+
1149+ driver .findElement (By .id ("go" )).click ();
1150+ verifyTitle2 (driver , getExpectedAlerts ()); // expect "" and "0"
1151+ }
10241152}
0 commit comments