View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.html;
16  
17  import static org.junit.jupiter.api.Assertions.fail;
18  
19  import java.util.Collections;
20  
21  import org.htmlunit.WebDriverTestCase;
22  import org.htmlunit.junit.annotation.Alerts;
23  import org.htmlunit.junit.annotation.HtmlUnitNYI;
24  import org.htmlunit.util.MimeType;
25  import org.junit.jupiter.api.Assertions;
26  import org.junit.jupiter.api.Test;
27  import org.openqa.selenium.By;
28  import org.openqa.selenium.InvalidElementStateException;
29  import org.openqa.selenium.JavascriptExecutor;
30  import org.openqa.selenium.Keys;
31  import org.openqa.selenium.WebDriver;
32  import org.openqa.selenium.WebElement;
33  import org.openqa.selenium.htmlunit.HtmlUnitDriver;
34  
35  /**
36   * Tests for {@link HtmlNumberInput}.
37   *
38   * @author Ronald Brill
39   * @author Anton Demydenko
40   * @author Raik Bieniek
41   */
42  public class HtmlNumberInputTest extends WebDriverTestCase {
43  
44      /**
45       * Verifies getVisibleText().
46       * @throws Exception if the test fails
47       */
48      @Test
49      @Alerts("")
50      public void getVisibleTextInteger() throws Exception {
51          final String htmlContent = DOCTYPE_HTML
52              + "<html>\n"
53              + "<head></head>\n"
54              + "<body>\n"
55              + "<form id='form1'>\n"
56              + "  <input type='number' name='tester' id='tester' value='123'>\n"
57              + "</form>\n"
58              + "</body></html>";
59  
60          final WebDriver driver = loadPage2(htmlContent);
61          final String text = driver.findElement(By.id("tester")).getText();
62          assertEquals(getExpectedAlerts()[0], text);
63  
64          if (driver instanceof HtmlUnitDriver) {
65              final HtmlPage page = (HtmlPage) getEnclosedPage();
66              assertEquals(getExpectedAlerts()[0], page.getBody().getVisibleText());
67          }
68      }
69  
70      /**
71       * Verifies getVisibleText().
72       * @throws Exception if the test fails
73       */
74      @Test
75      @Alerts("")
76      public void getVisibleTextDouble() throws Exception {
77          final String htmlContent = DOCTYPE_HTML
78              + "<html>\n"
79              + "<head></head>\n"
80              + "<body>\n"
81              + "<form id='form1'>\n"
82              + "  <input type='number' name='tester' id='tester' value='1.23'>\n"
83              + "</form>\n"
84              + "</body></html>";
85  
86          final WebDriver driver = loadPage2(htmlContent);
87          final String text = driver.findElement(By.id("tester")).getText();
88          assertEquals(getExpectedAlerts()[0], text);
89  
90          if (driver instanceof HtmlUnitDriver) {
91              final HtmlPage page = (HtmlPage) getEnclosedPage();
92              assertEquals(getExpectedAlerts()[0], page.getBody().getVisibleText());
93          }
94      }
95  
96      /**
97       * @throws Exception if the test fails
98       */
99      @Test
100     public void typeInteger() throws Exception {
101         final String html = DOCTYPE_HTML + "<html><head></head><body><input type='number' id='inpt'/></body></html>";
102         final WebDriver driver = loadPage2(html);
103         final WebElement t = driver.findElement(By.id("inpt"));
104 
105         assertNull(t.getDomAttribute("value"));
106         assertEquals("", t.getDomProperty("value"));
107 
108         t.sendKeys("123");
109         assertNull(t.getDomAttribute("value"));
110         assertEquals("123", t.getDomProperty("value"));
111 
112         t.sendKeys(Keys.BACK_SPACE);
113         assertNull(t.getDomAttribute("value"));
114         assertEquals("12", t.getDomProperty("value"));
115 
116         t.sendKeys(Keys.BACK_SPACE);
117         assertNull(t.getDomAttribute("value"));
118         assertEquals("1", t.getDomProperty("value"));
119 
120         t.sendKeys(Keys.BACK_SPACE);
121         assertNull(t.getDomAttribute("value"));
122         assertEquals("", t.getDomProperty("value"));
123 
124         t.sendKeys(Keys.BACK_SPACE);
125         assertNull(t.getDomAttribute("value"));
126         assertEquals("", t.getDomProperty("value"));
127     }
128 
129     /**
130      * @throws Exception if the test fails
131      */
132     @Test
133     @Alerts({"123", "true"})
134     public void typeIntegerValid() throws Exception {
135         final String html = DOCTYPE_HTML
136                 + "<html>\n"
137                 + "<head></head>\n"
138                 + "<body>\n"
139                 + "  <input type='number' id='inpt'/>\n"
140                 + "  <button id='check' "
141                         + "onclick='document.title = document.getElementById(\"inpt\").checkValidity()');'>"
142                 + "DoIt</button>\n"
143                 + "</body>\n"
144                 + "</html>";
145         final WebDriver driver = loadPage2(html);
146 
147         final WebElement input = driver.findElement(By.id("inpt"));
148         final WebElement check = driver.findElement(By.id("check"));
149 
150         input.sendKeys("123");
151         assertNull(input.getDomAttribute("value"));
152         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
153 
154         check.click();
155         assertEquals(getExpectedAlerts()[1], driver.getTitle());
156     }
157 
158     /**
159      * @throws Exception if the test fails
160      */
161     @Test
162     @Alerts({"12", "true", "123", "false"})
163     public void typeIntegerTooLarge() throws Exception {
164         final String html = DOCTYPE_HTML
165                 + "<html>\n"
166                 + "<head></head>\n"
167                 + "<body>\n"
168                 + "  <input type='number' id='inpt' max='100'/>\n"
169                 + "  <button id='check' "
170                         + "onclick='document.title = document.getElementById(\"inpt\").checkValidity()');'>"
171                 + "DoIt</button>\n"
172                 + "</body>\n"
173                 + "</html>";
174         final WebDriver driver = loadPage2(html);
175 
176         final WebElement input = driver.findElement(By.id("inpt"));
177         final WebElement check = driver.findElement(By.id("check"));
178 
179         input.sendKeys("12");
180         assertNull(input.getDomAttribute("value"));
181         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
182         check.click();
183         assertEquals(getExpectedAlerts()[1], driver.getTitle());
184 
185         input.sendKeys("3");
186         assertNull(input.getDomAttribute("value"));
187         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
188         check.click();
189         assertEquals(getExpectedAlerts()[3], driver.getTitle());
190     }
191 
192     /**
193      * @throws Exception if the test fails
194      */
195     @Test
196     @Alerts({"12", "false", "123", "true"})
197     public void typeIntegerTooSmall() throws Exception {
198         final String html = DOCTYPE_HTML
199                 + "<html>\n"
200                 + "<head></head>\n"
201                 + "<body>\n"
202                 + "  <input type='number' id='inpt' min='100'/>\n"
203                 + "  <button id='check' "
204                         + "onclick='document.title = document.getElementById(\"inpt\").checkValidity()');'>"
205                 + "DoIt</button>\n"
206                 + "</body>\n"
207                 + "</html>";
208         final WebDriver driver = loadPage2(html);
209 
210         final WebElement input = driver.findElement(By.id("inpt"));
211         final WebElement check = driver.findElement(By.id("check"));
212 
213         input.sendKeys("12");
214         assertNull(input.getDomAttribute("value"));
215         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
216         check.click();
217         assertEquals(getExpectedAlerts()[1], driver.getTitle());
218 
219         input.sendKeys("3");
220         assertNull(input.getDomAttribute("value"));
221         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
222 
223         check.click();
224         assertEquals(getExpectedAlerts()[3], driver.getTitle());
225     }
226 
227     /**
228      * @throws Exception if the test fails
229      */
230     @Test
231     @Alerts({"1", "1--null-true", "1", "1--null-true", "1.2", "1.2--null-false"})
232     @HtmlUnitNYI(CHROME = {"1", "1--null-true", "1.", "1.--null-true", "1.2", "1.2--null-false"},
233             EDGE = {"1", "1--null-true", "1.", "1.--null-true", "1.2", "1.2--null-false"},
234             FF = {"1", "1--null-true", "", "--null-false", "1.2", "1.2--null-false"},
235             FF_ESR = {"1", "1--null-true", "", "--null-false", "1.2", "1.2--null-false"})
236     public void typeIntegerWithDot() throws Exception {
237         final String html = DOCTYPE_HTML
238                 + "<html>\n"
239                 + "<head>\n"
240                 + "<script>\n"
241                 + "  function test() {\n"
242                 + "    var input = document.getElementById('inpt');\n"
243                 + "    document.title = input.value + '-' "
244                                 + "+ input.defaultValue + '-' "
245                                 + "+ input.getAttribute('value')+ '-' "
246                                 + "+ input.checkValidity();\n"
247                 + "  }\n"
248                 + "</script>\n"
249                 + "</head>\n"
250                 + "<body>\n"
251                 + "  <input type='number' id='inpt' />\n"
252                 + "  <button id='check' onclick='test()');'>"
253                 + "DoIt</button>\n"
254                 + "</body>\n"
255                 + "</html>";
256         final WebDriver driver = loadPage2(html);
257 
258         final WebElement input = driver.findElement(By.id("inpt"));
259         final WebElement check = driver.findElement(By.id("check"));
260 
261         input.sendKeys("1");
262         assertNull(input.getDomAttribute("value"));
263         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
264         check.click();
265         assertEquals(getExpectedAlerts()[1], driver.getTitle());
266 
267         input.sendKeys(".");
268         assertNull(input.getDomAttribute("value"));
269         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
270         check.click();
271         assertEquals(getExpectedAlerts()[3], driver.getTitle());
272 
273         input.sendKeys("2");
274         assertNull(input.getDomAttribute("value"));
275         assertEquals(getExpectedAlerts()[4], input.getDomProperty("value"));
276         check.click();
277         assertEquals(getExpectedAlerts()[5], driver.getTitle());
278     }
279 
280     /**
281      * @throws Exception if the test fails
282      */
283     @Test
284     @Alerts({"", "--null-false", "-12", "-12--null-true", "-123", "-123--null-false"})
285     public void typeIntegerNegativeValid() throws Exception {
286         final String html = DOCTYPE_HTML
287                 + "<html>\n"
288                 + "<head>\n"
289                 + "<script>\n"
290                 + "  function test() {\n"
291                 + "    var input = document.getElementById('inpt');\n"
292                 + "    document.title = input.value + '-' "
293                                 + "+ input.defaultValue + '-' "
294                                 + "+ input.getAttribute('value')+ '-' "
295                                 + "+ input.checkValidity();\n"
296                 + "  }\n"
297                 + "</script>\n"
298                 + "</head>\n"
299                 + "<body>\n"
300                 + "  <input type='number' id='inpt' min='-42' max='1234'/>\n"
301                 + "  <button id='check' onclick='test()');'>"
302                 + "DoIt</button>\n"
303                 + "</body>\n"
304                 + "</html>";
305         final WebDriver driver = loadPage2(html);
306 
307         final WebElement input = driver.findElement(By.id("inpt"));
308         final WebElement check = driver.findElement(By.id("check"));
309 
310         input.sendKeys("-");
311         assertNull(input.getDomAttribute("value"));
312         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
313         check.click();
314         assertEquals(getExpectedAlerts()[1], driver.getTitle());
315 
316         input.sendKeys("12");
317         assertNull(input.getDomAttribute("value"));
318         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
319         check.click();
320         assertEquals(getExpectedAlerts()[3], driver.getTitle());
321 
322         input.sendKeys("3");
323         assertNull(input.getDomAttribute("value"));
324         assertEquals(getExpectedAlerts()[4], input.getDomProperty("value"));
325         check.click();
326         assertEquals(getExpectedAlerts()[5], driver.getTitle());
327     }
328 
329     /**
330      * @throws Exception if the test fails
331      */
332     @Test
333     @Alerts({"", "--null-false", "-12", "-12--null-false"})
334     public void typeIntegerNegativeInvalid() throws Exception {
335         final String html = DOCTYPE_HTML
336                 + "<html>\n"
337                 + "<head>\n"
338                 + "<script>\n"
339                 + "  function test() {\n"
340                 + "    var input = document.getElementById('inpt');\n"
341                 + "    document.title = input.value + '-' "
342                                 + "+ input.defaultValue + '-' "
343                                 + "+ input.getAttribute('value')+ '-' "
344                                 + "+ input.checkValidity();\n"
345                 + "  }\n"
346                 + "</script>\n"
347                 + "</head>\n"
348                 + "<body>\n"
349                 + "  <input type='number' id='inpt' min='1' max='1234'/>\n"
350                 + "  <button id='check' onclick='test()');'>"
351                 + "DoIt</button>\n"
352                 + "</body>\n"
353                 + "</html>";
354         final WebDriver driver = loadPage2(html);
355 
356         final WebElement input = driver.findElement(By.id("inpt"));
357         final WebElement check = driver.findElement(By.id("check"));
358 
359         input.sendKeys("-");
360         assertNull(input.getDomAttribute("value"));
361         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
362         check.click();
363         assertEquals(getExpectedAlerts()[1], driver.getTitle());
364 
365         input.sendKeys("12");
366         assertNull(input.getDomAttribute("value"));
367         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
368         check.click();
369         assertEquals(getExpectedAlerts()[3], driver.getTitle());
370     }
371 
372     /**
373      * @throws Exception if the test fails
374      */
375     @Test
376     public void typeDouble() throws Exception {
377         final String html = DOCTYPE_HTML
378                 + "<html><head></head><body>\n"
379                 + "<input type='number' step='0.01' id='t'/>\n"
380                 + "</body></html>";
381         final WebDriver driver = loadPage2(html);
382         final WebElement t = driver.findElement(By.id("t"));
383         t.sendKeys("1.23");
384         assertNull(t.getDomAttribute("value"));
385         assertEquals("1.23", t.getDomProperty("value"));
386     }
387 
388     /**
389      * @throws Exception if the test fails
390      */
391     @Test
392     public void typeWhileDisabled() throws Exception {
393         final String html = DOCTYPE_HTML
394                 + "<html><body><input type='number' id='p' disabled='disabled'/></body></html>";
395         final WebDriver driver = loadPage2(html);
396         final WebElement p = driver.findElement(By.id("p"));
397         try {
398             p.sendKeys("abc");
399             fail();
400         }
401         catch (final InvalidElementStateException e) {
402             // as expected
403         }
404 
405         assertNull(p.getDomAttribute("value"));
406         assertEquals("", p.getDomProperty("value"));
407     }
408 
409     /**
410      * @throws Exception if the test fails
411      */
412     @Test
413     @Alerts({"null", "null"})
414     public void typeDoesNotChangeValueAttribute() throws Exception {
415         final String html = DOCTYPE_HTML
416                 + "<html>\n"
417                 + "<head></head>\n"
418                 + "<body>\n"
419                 + "  <input type='number' id='t'/>\n"
420                 + "  <button id='check' onclick='document.title = "
421                                     + "document.getElementById(\"t\").getAttribute(\"value\");'>"
422                         + "DoIt</button>\n"
423                 + "</body></html>";
424 
425         final WebDriver driver = loadPage2(html);
426         final WebElement t = driver.findElement(By.id("t"));
427 
428         final WebElement check = driver.findElement(By.id("check"));
429         check.click();
430         assertEquals(getExpectedAlerts()[0], driver.getTitle());
431 
432         t.sendKeys("abc");
433         check.click();
434         assertEquals(getExpectedAlerts()[1], driver.getTitle());
435     }
436 
437     /**
438      * @throws Exception if the test fails
439      */
440     @Test
441     @Alerts({"1234", "1234"})
442     public void typeDoesNotChangeValueAttributeWithInitialValue() throws Exception {
443         final String html = DOCTYPE_HTML
444                 + "<html>\n"
445                 + "<head></head>\n"
446                 + "<body>\n"
447                 + "  <input type='number' id='t' value='1234'/>\n"
448                 + "  <button id='check' onclick='document.title = "
449                                     + "document.getElementById(\"t\").getAttribute(\"value\");'>"
450                         + "DoIt</button>\n"
451                 + "</body></html>";
452 
453         final WebDriver driver = loadPage2(html);
454         final WebElement t = driver.findElement(By.id("t"));
455 
456         final WebElement check = driver.findElement(By.id("check"));
457         check.click();
458         assertEquals(getExpectedAlerts()[0], driver.getTitle());
459 
460         t.sendKeys("987");
461         check.click();
462         assertEquals(getExpectedAlerts()[1], driver.getTitle());
463     }
464 
465     /**
466      * @throws Exception if an error occurs
467      */
468     @Test
469     public void preventDefault_OnKeyDown() throws Exception {
470         final String html = DOCTYPE_HTML
471             + "<html><head><script>\n"
472             + "  function handler(e) {\n"
473             + "    if (e && e.target.value.length > 2)\n"
474             + "      e.preventDefault();\n"
475             + "    else if (!e && window.event.srcElement.value.length > 2)\n"
476             + "      return false;\n"
477             + "  }\n"
478             + "  function init() {\n"
479             + "    document.getElementById('p').onkeydown = handler;\n"
480             + "  }\n"
481             + "</script></head>\n"
482             + "<body onload='init()'>\n"
483             + "<input type='number' id='p'></input>\n"
484             + "</body></html>";
485 
486         final WebDriver driver = loadPage2(html);
487         final WebElement p = driver.findElement(By.id("p"));
488         p.sendKeys("1234");
489         assertNull(p.getDomAttribute("value"));
490         assertEquals("123", p.getDomProperty("value"));
491     }
492 
493     /**
494      * @throws Exception if an error occurs
495      */
496     @Test
497     public void preventDefault_OnKeyPress() throws Exception {
498         final String html = DOCTYPE_HTML
499             + "<html><head><script>\n"
500             + "  function handler(e) {\n"
501             + "    if (e && e.target.value.length > 2)\n"
502             + "      e.preventDefault();\n"
503             + "    else if (!e && window.event.srcElement.value.length > 2)\n"
504             + "      return false;\n"
505             + "  }\n"
506             + "  function init() {\n"
507             + "    document.getElementById('p').onkeypress = handler;\n"
508             + "  }\n"
509             + "</script></head>\n"
510             + "<body onload='init()'>\n"
511             + "<input type='number' id='p'></input>\n"
512             + "</body></html>";
513 
514         final WebDriver driver = loadPage2(html);
515         final WebElement p = driver.findElement(By.id("p"));
516         p.sendKeys("1234");
517         assertNull(p.getDomAttribute("value"));
518         assertEquals("123", p.getDomProperty("value"));
519     }
520 
521     /**
522      * @throws Exception if an error occurs
523      */
524     @Test
525     public void typeOnChange() throws Exception {
526         final String html = DOCTYPE_HTML
527                 + "<html>\n"
528                 + "<head>\n"
529                 + "<script>\n"
530                 + LOG_TITLE_FUNCTION
531                 + "</script>\n"
532                 + "</head>\n"
533                 + "<body>\n"
534                 + "<input type='number' id='p' value='1234'"
535                     + " onChange='log(\"foo\");log(event.type);'"
536                     + " onBlur='log(\"boo\");log(event.type);'>\n"
537             + "<button id='b'>some button</button>\n"
538             + "</body></html>";
539 
540         final WebDriver driver = loadPage2(html);
541         final WebElement p = driver.findElement(By.id("p"));
542         p.sendKeys("567");
543 
544         assertEquals(Collections.emptyList(), getCollectedAlerts(driver));
545 
546         // trigger lost focus
547         driver.findElement(By.id("b")).click();
548         final String[] expectedAlerts1 = {"foo", "change", "boo", "blur"};
549         verifyTitle2(driver, expectedAlerts1);
550 
551         // set only the focus but change nothing
552         p.click();
553         assertTrue(getCollectedAlerts(driver, 1).isEmpty());
554 
555         // trigger lost focus
556         driver.findElement(By.id("b")).click();
557         final String[] expectedAlerts2 = {"foo", "change", "boo", "blur", "boo", "blur"};
558         verifyTitle2(driver, expectedAlerts2);
559     }
560 
561     /**
562      * @throws Exception if an error occurs
563      */
564     @Test
565     public void setValueOnChange() throws Exception {
566         final String html = DOCTYPE_HTML
567               + "<html>\n"
568               + "<head>\n"
569               + "<script>\n"
570               + LOG_TITLE_FUNCTION
571               + "</script>\n"
572               + "</head>\n"
573               + "<body>\n"
574               + "  <input type='number' id='t' value='1234'"
575                     + " onChange='log(\"foo\");log(event.type);'>\n"
576               + "  <button id='b'>some button</button>\n"
577               + "  <button id='set' onclick='document.getElementById(\"t\").value=\"1234\"'>setValue</button>\n"
578               + "</body></html>";
579 
580         final WebDriver driver = loadPage2(html);
581         driver.findElement(By.id("set")).click();
582         verifyTitle2(driver, new String[]{});
583 
584         // trigger lost focus
585         driver.findElement(By.id("b")).click();
586         verifyTitle2(driver, new String[]{});
587     }
588 
589     /**
590      * @throws Exception if an error occurs
591      */
592     @Test
593     public void setDefaultValueOnChange() throws Exception {
594         final String html = DOCTYPE_HTML
595               + "<html>\n"
596               + "<head>"
597               + "<script>\n"
598               + LOG_TITLE_FUNCTION
599               + "</script>\n"
600               + "</head>\n"
601               + "<body>\n"
602               + "  <input type='number' id='t' value='1234'"
603                     + " onChange='log(\"foo\");log(event.type);'>\n"
604               + "  <button id='b'>some button</button>\n"
605               + "  <button id='set' onclick='document.getElementById(\"t\").defaultValue=\"1234\"'>"
606                       + "setValue</button>\n"
607               + "</body></html>";
608 
609         final WebDriver driver = loadPage2(html);
610         driver.findElement(By.id("set")).click();
611         verifyTitle2(driver, new String[]{});
612 
613         // trigger lost focus
614         driver.findElement(By.id("b")).click();
615         verifyTitle2(driver, new String[]{});
616     }
617 
618     /**
619      * @throws Exception if the test fails
620      */
621     @Test
622     @Alerts({"--null-true", "--null-true", "--null-true"})
623     public void defaultValues() throws Exception {
624         final String html = DOCTYPE_HTML
625             + "<html><head>\n"
626             + "<script>\n"
627             + LOG_TITLE_FUNCTION
628             + "  function test() {\n"
629             + "    var input = document.getElementById('inpt');\n"
630             + "    log(input.value + '-' "
631                             + "+ input.defaultValue + '-' "
632                             + "+ input.getAttribute('value')+ '-' "
633                             + "+ input.checkValidity());\n"
634 
635             + "    input = document.createElement('input');\n"
636             + "    input.type = 'number';\n"
637             + "    log(input.value + '-' "
638                             + "+ input.defaultValue + '-' "
639                             + "+ input.getAttribute('value')+ '-' "
640                             + "+ input.checkValidity());\n"
641 
642             + "    var builder = document.createElement('div');\n"
643             + "    builder.innerHTML = '<input type=\"number\">';\n"
644             + "    input = builder.firstChild;\n"
645             + "    log(input.value + '-' "
646                             + "+ input.defaultValue + '-' "
647                             + "+ input.getAttribute('value')+ '-' "
648                             + "+ input.checkValidity());\n"
649             + "  }\n"
650             + "</script>\n"
651             + "</head>\n"
652             + "<body onload='test()'>\n"
653             + "<form>\n"
654             + "  <input type='number' id='inpt'>\n"
655             + "</form>\n"
656             + "</body></html>";
657 
658         loadPageVerifyTitle2(html);
659     }
660 
661     /**
662      * @throws Exception if an error occurs
663      */
664     @Test
665     @Alerts({"8-8-8-true", "-abc-abc-true", "---true",
666              "99999999999999999999999999999-99999999999999999999999999999"
667                                + "-99999999999999999999999999999-true"})
668     public void defaultValuesInvalidValue() throws Exception {
669         final String html = DOCTYPE_HTML
670             + "<html>\n"
671             + "<head>\n"
672             + "<script>\n"
673             + LOG_TITLE_FUNCTION
674             + "  function test() {\n"
675             + "    var input = document.getElementById('foo');\n"
676             + "    log(input.value + '-' "
677                             + "+ input.defaultValue + '-' "
678                             + "+ input.getAttribute('value')+ '-' "
679                             + "+ input.checkValidity());\n"
680 
681             + "    input = document.getElementById('bar');\n"
682             + "    log(input.value + '-' "
683                             + "+ input.defaultValue + '-' "
684                             + "+ input.getAttribute('value')+ '-' "
685                             + "+ input.checkValidity());\n"
686 
687             + "    input = document.getElementById('baz');\n"
688             + "    log(input.value + '-' "
689                             + "+ input.defaultValue + '-' "
690                             + "+ input.getAttribute('value')+ '-' "
691                             + "+ input.checkValidity());\n"
692 
693             + "    input = document.getElementById('another');\n"
694             + "    log(input.value + '-' "
695                             + "+ input.defaultValue + '-' "
696                             + "+ input.getAttribute('value')+ '-' "
697                             + "+ input.checkValidity());\n"
698             + "  }\n"
699             + "</script>\n"
700             + "</head>\n"
701             + "<body onload='test()'>\n"
702             + "  <input type='number' id='foo' value='8'>\n"
703             + "  <input type='number' id='bar' value='abc'>\n"
704             + "  <input type='number' id='baz' value=''>\n"
705             + "  <input type='number' id='another' value='99999999999999999999999999999'>\n"
706             + "</body>\n"
707             + "</html>";
708 
709         loadPageVerifyTitle2(html);
710     }
711 
712     /**
713      * @throws Exception if an error occurs
714      */
715     @Test
716     @Alerts({"8-8-8-true", "-\\s\\s-\\s\\s-true",
717              "-\\s\\s\\n\\s\\s\\t\\s-\\s\\s\\n\\s\\s\\t\\s-true",
718              "-\\s3\\s9\\s-\\s3\\s9\\s-true"})
719     public void defaultValuesBlankValue() throws Exception {
720         final String html = DOCTYPE_HTML
721             + "<html>\n"
722             + "<head>\n"
723             + "<script>\n"
724             + LOG_TITLE_FUNCTION_NORMALIZE
725             + "  function test() {\n"
726             + "    var input = document.getElementById('foo');\n"
727             + "    log(input.value + '-' "
728                             + "+ input.defaultValue + '-' "
729                             + "+ input.getAttribute('value')+ '-' "
730                             + "+ input.checkValidity());\n"
731 
732             + "    input = document.getElementById('bar');\n"
733             + "    log(input.value + '-' "
734                             + "+ input.defaultValue + '-' "
735                             + "+ input.getAttribute('value')+ '-' "
736                             + "+ input.checkValidity());\n"
737 
738             + "    input = document.getElementById('baz');\n"
739             + "    log(input.value + '-' "
740                             + "+ input.defaultValue + '-' "
741                             + "+ input.getAttribute('value')+ '-' "
742                             + "+ input.checkValidity());\n"
743 
744             + "    input = document.getElementById('another');\n"
745             + "    log(input.value + '-' "
746                             + "+ input.defaultValue + '-' "
747                             + "+ input.getAttribute('value')+ '-' "
748                             + "+ input.checkValidity());\n"
749             + "  }\n"
750             + "</script>\n"
751             + "</head>\n"
752             + "<body onload='test()'>\n"
753             + "  <input type='number' id='foo' value='8'>\n"
754             + "  <input type='number' id='bar' value='  '>\n"
755             + "  <input type='number' id='baz' value='  \n  \t '>\n"
756             + "  <input type='number' id='another' value=' 3 9 '>\n"
757             + "</body>\n"
758             + "</html>";
759 
760         loadPageVerifyTitle2(html);
761     }
762 
763     /**
764      * @throws Exception if an error occurs
765      */
766     @Test
767     @Alerts({"8-8-8-true", "7-7-7-false", "6-6-6-false"})
768     public void defaultValuesIntegerValueOutside() throws Exception {
769         final String html = DOCTYPE_HTML
770             + "<html>\n"
771             + "<head>\n"
772             + "<script>\n"
773             + LOG_TITLE_FUNCTION
774             + "  function test() {\n"
775             + "    var input = document.getElementById('foo');\n"
776             + "    log(input.value + '-' "
777                             + "+ input.defaultValue + '-' "
778                             + "+ input.getAttribute('value')+ '-' "
779                             + "+ input.checkValidity());\n"
780 
781             + "    input = document.getElementById('bar');\n"
782             + "    log(input.value + '-' "
783                             + "+ input.defaultValue + '-' "
784                             + "+ input.getAttribute('value')+ '-' "
785                             + "+ input.checkValidity());\n"
786 
787             + "    input = document.getElementById('baz');\n"
788             + "    log(input.value + '-' "
789                             + "+ input.defaultValue + '-' "
790                             + "+ input.getAttribute('value')+ '-' "
791                             + "+ input.checkValidity());\n"
792             + "  }\n"
793             + "</script>\n"
794             + "</head>\n"
795             + "<body onload='test()'>\n"
796             + "  <input type='number' id='foo' value='8' min='1' max='10'>\n"
797             + "  <input type='number' id='bar' value='7'  min='9' max='10'>\n"
798             + "  <input type='number' id='baz' value='6'  min='1' max='4'>\n"
799             + "</body>\n"
800             + "</html>";
801 
802         loadPageVerifyTitle2(html);
803     }
804 
805     /**
806      * @throws Exception if an error occurs
807      */
808     @Test
809     @Alerts({"8-8-8-true", "7-7-7-false", "7.13-7.13-7.13-false"})
810     public void defaultValuesInvalid() throws Exception {
811         final String html = DOCTYPE_HTML
812             + "<html>\n"
813             + "<head>\n"
814             + "<script>\n"
815             + LOG_TITLE_FUNCTION
816             + "  function test() {\n"
817             + "    var input = document.getElementById('foo');\n"
818             + "    log(input.value + '-' "
819                             + "+ input.defaultValue + '-' "
820                             + "+ input.getAttribute('value')+ '-' "
821                             + "+ input.checkValidity());\n"
822 
823             + "    input = document.getElementById('bar');\n"
824             + "    log(input.value + '-' "
825                             + "+ input.defaultValue + '-' "
826                             + "+ input.getAttribute('value')+ '-' "
827                             + "+ input.checkValidity());\n"
828 
829             + "    input = document.getElementById('baz');\n"
830             + "    log(input.value + '-' "
831                             + "+ input.defaultValue + '-' "
832                             + "+ input.getAttribute('value')+ '-' "
833                             + "+ input.checkValidity());\n"
834             + "  }\n"
835             + "</script>\n"
836             + "</head>\n"
837             + "<body onload='test()'>\n"
838             + "  <input type='number' id='foo' value='8' min='2' max='10' step='2' >\n"
839             + "  <input type='number' id='bar' value='7' min='2' max='10' step='2' >\n"
840             + "  <input type='number' id='baz' value='7.13' min='2' max='10' step='2' >\n"
841             + "</body>\n"
842             + "</html>";
843 
844         loadPageVerifyTitle2(html);
845     }
846 
847     /**
848      * @throws Exception if the test fails
849      */
850     @Test
851     @Alerts({"--null", "--null", "--null"})
852     public void defaultValuesAfterClone() throws Exception {
853         final String html = DOCTYPE_HTML
854             + "<html><head>\n"
855             + "<script>\n"
856             + LOG_TITLE_FUNCTION
857             + "  function test() {\n"
858             + "    var input = document.getElementById('inpt');\n"
859             + "    input = input.cloneNode(false);\n"
860             + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
861 
862             + "    input = document.createElement('input');\n"
863             + "    input.type = 'number';\n"
864             + "    input = input.cloneNode(false);\n"
865             + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
866 
867             + "    var builder = document.createElement('div');\n"
868             + "    builder.innerHTML = '<input type=\"number\">';\n"
869             + "    input = builder.firstChild;\n"
870             + "    input = input.cloneNode(false);\n"
871             + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
872             + "  }\n"
873             + "</script>\n"
874             + "</head><body onload='test()'>\n"
875             + "<form>\n"
876             + "  <input type='number' id='inpt'>\n"
877             + "</form>\n"
878             + "</body></html>";
879 
880         loadPageVerifyTitle2(html);
881     }
882 
883     /**
884      * @throws Exception if the test fails
885      */
886     @Test
887     @Alerts({"1234-1234-1234", "1234-1234-1234",
888                 "5678-1234-1234", "5678-1234-1234",
889                 "5678-2345-2345", "5678-2345-2345"})
890     public void resetByClick() throws Exception {
891         final String html = DOCTYPE_HTML
892             + "<html><head>\n"
893             + "<script>\n"
894             + LOG_TITLE_FUNCTION
895             + "  function test() {\n"
896             + "    var text = document.getElementById('testId');\n"
897             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
898 
899             + "    document.getElementById('testReset').click;\n"
900             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
901 
902             + "    text.value = '5678';\n"
903             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
904 
905             + "    document.getElementById('testReset').click;\n"
906             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
907 
908             + "    text.defaultValue = '2345';\n"
909             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
910 
911             + "    document.forms[0].reset;\n"
912             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
913             + "  }\n"
914             + "</script>\n"
915             + "</head><body onload='test()'>\n"
916             + "<form>\n"
917             + "  <input type='number' id='testId' value='1234'>\n"
918             + "  <input type='reset' id='testReset'>\n"
919             + "</form>\n"
920             + "</body></html>";
921 
922         loadPageVerifyTitle2(html);
923     }
924 
925     /**
926      * @throws Exception if the test fails
927      */
928     @Test
929     @Alerts({"1234-1234-1234", "1234-1234-1234",
930                 "5678-1234-1234", "5678-1234-1234",
931                 "5678-2345-2345", "5678-2345-2345"})
932     public void resetByJS() throws Exception {
933         final String html = DOCTYPE_HTML
934             + "<html><head>\n"
935             + "<script>\n"
936             + LOG_TITLE_FUNCTION
937             + "  function test() {\n"
938             + "    var text = document.getElementById('testId');\n"
939             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
940 
941             + "    document.forms[0].reset;\n"
942             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
943 
944             + "    text.value = '5678';\n"
945             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
946 
947             + "    document.forms[0].reset;\n"
948             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
949 
950             + "    text.defaultValue = '2345';\n"
951             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
952 
953             + "    document.forms[0].reset;\n"
954             + "    log(text.value + '-' + text.defaultValue + '-' + text.getAttribute('value'));\n"
955             + "  }\n"
956             + "</script>\n"
957             + "</head><body onload='test()'>\n"
958             + "<form>\n"
959             + "  <input type='number' id='testId' value='1234'>\n"
960             + "</form>\n"
961             + "</body></html>";
962 
963         loadPageVerifyTitle2(html);
964     }
965 
966     /**
967      * @throws Exception if the test fails
968      */
969     @Test
970     @Alerts({"1234-1234-1234-true", "2345-2345-2345-true",
971                 "3456-2345-2345-true", "3456-9876-9876-true",
972                 "3456-44-44-true"})
973     public void value() throws Exception {
974         final String html = DOCTYPE_HTML
975             + "<html><head>\n"
976             + "<script>\n"
977             + LOG_TITLE_FUNCTION
978             + "  function test() {\n"
979             + "    var input = document.getElementById('testId');\n"
980             + "    log(input.value + '-' "
981                             + "+ input.defaultValue + '-' "
982                             + "+ input.getAttribute('value')+ '-' "
983                             + "+ input.checkValidity());\n"
984 
985             + "    input.defaultValue = '2345';\n"
986             + "    log(input.value + '-' "
987                             + "+ input.defaultValue + '-' "
988                             + "+ input.getAttribute('value')+ '-' "
989                             + "+ input.checkValidity());\n"
990 
991             + "    input.value = '3456';\n"
992             + "    log(input.value + '-' "
993                             + "+ input.defaultValue + '-' "
994                             + "+ input.getAttribute('value')+ '-' "
995                             + "+ input.checkValidity());\n"
996 
997             + "    input.setAttribute('value', '9876');\n"
998             + "    log(input.value + '-' "
999                             + "+ input.defaultValue + '-' "
1000                             + "+ input.getAttribute('value')+ '-' "
1001                             + "+ input.checkValidity());\n"
1002 
1003             + "    input.defaultValue = '44';\n"
1004             + "    log(input.value + '-' "
1005                         + "+ input.defaultValue + '-' "
1006                         + "+ input.getAttribute('value')+ '-' "
1007                         + "+ input.checkValidity());\n"
1008             + "  }\n"
1009             + "</script>\n"
1010             + "</head><body onload='test()'>\n"
1011             + "<form>\n"
1012             + "  <input type='number' id='testId' value='1234'>\n"
1013             + "</form>\n"
1014             + "</body></html>";
1015 
1016         loadPageVerifyTitle2(html);
1017     }
1018 
1019 
1020     /**
1021      * @throws Exception if the test fails
1022      */
1023     @Test
1024     @Alerts({"123-123-123-true", "2-2-2-false", "20000-2-2-false", "20000-9-9-false"})
1025     public void valueOutside() throws Exception {
1026         final String html = DOCTYPE_HTML
1027             + "<html><head>\n"
1028             + "<script>\n"
1029             + LOG_TITLE_FUNCTION
1030             + "  function test() {\n"
1031             + "    var input = document.getElementById('testId');\n"
1032             + "    log(input.value + '-' "
1033                             + "+ input.defaultValue + '-' "
1034                             + "+ input.getAttribute('value')+ '-' "
1035                             + "+ input.checkValidity());\n"
1036 
1037             + "    input.defaultValue = '2';\n"
1038             + "    log(input.value + '-' "
1039                             + "+ input.defaultValue + '-' "
1040                             + "+ input.getAttribute('value')+ '-' "
1041                             + "+ input.checkValidity());\n"
1042 
1043             + "    input.value = '20000';\n"
1044             + "    log(input.value + '-' "
1045                             + "+ input.defaultValue + '-' "
1046                             + "+ input.getAttribute('value')+ '-' "
1047                             + "+ input.checkValidity());\n"
1048 
1049             + "    input.setAttribute('value', '9');\n"
1050             + "    log(input.value + '-' "
1051                             + "+ input.defaultValue + '-' "
1052                             + "+ input.getAttribute('value')+ '-' "
1053                             + "+ input.checkValidity());\n"
1054             + "  }\n"
1055             + "</script>\n"
1056             + "</head><body onload='test()'>\n"
1057             + "<form>\n"
1058             + "  <input type='number' id='testId' value='123' min='10' max='1000' >\n"
1059             + "</form>\n"
1060             + "</body></html>";
1061 
1062         loadPageVerifyTitle2(html);
1063     }
1064 
1065     /**
1066      * @throws Exception if the test fails
1067      */
1068     @Test
1069     @Alerts({"12-12-12-true", "12", "12312", "12312-12-12-false"})
1070     public void typeValueOutside() throws Exception {
1071         final String html = DOCTYPE_HTML
1072             + "<html><head>\n"
1073             + "<script>\n"
1074             + "  function test() {\n"
1075             + "    var input = document.getElementById('testId');\n"
1076             + "    document.title = input.value + '-' "
1077                             + "+ input.defaultValue + '-' "
1078                             + "+ input.getAttribute('value')+ '-' "
1079                             + "+ input.checkValidity();\n"
1080             + "  }\n"
1081             + "</script>\n"
1082             + "</head><body onload='test()'>\n"
1083             + "<form>\n"
1084             + "  <input type='number' id='testId' value='12' min='10' max='20' >\n"
1085             + "  <input type='button' id='testBtn' onclick='test()' >\n"
1086             + "</form>\n"
1087             + "</body></html>";
1088 
1089         final WebDriver driver = loadPage2(html);
1090         assertEquals(getExpectedAlerts()[0], driver.getTitle());
1091 
1092         final WebElement t = driver.findElement(By.id("testId"));
1093         t.sendKeys(Keys.HOME);
1094         t.sendKeys("123");
1095         assertEquals(getExpectedAlerts()[1], t.getDomAttribute("value"));
1096         assertEquals(getExpectedAlerts()[2], t.getDomProperty("value"));
1097 
1098         driver.findElement(By.id("testBtn")).click();
1099         assertEquals(getExpectedAlerts()[3], driver.getTitle());
1100     }
1101 
1102     /**
1103      * @throws Exception if the test fails
1104      */
1105     @Test
1106     @Alerts({"2-2-2-false", "2", "42", "42-2-2-false"})
1107     public void typeValueNotReachableByStep() throws Exception {
1108         final String html = DOCTYPE_HTML
1109             + "<html><head>\n"
1110             + "<script>\n"
1111             + "  function test() {\n"
1112             + "    var input = document.getElementById('testId');\n"
1113             + "    document.title = input.value + '-' "
1114                             + "+ input.defaultValue + '-' "
1115                             + "+ input.getAttribute('value')+ '-' "
1116                             + "+ input.checkValidity();\n"
1117             + "  }\n"
1118             + "</script>\n"
1119             + "</head><body onload='test()'>\n"
1120             + "<form>\n"
1121             + "  <input type='number' id='testId' value='2' min='0' max='200' step='51' >\n"
1122             + "  <input type='button' id='testBtn' onclick='test()' >\n"
1123             + "</form>\n"
1124             + "</body></html>";
1125 
1126         final WebDriver driver = loadPage2(html);
1127         assertEquals(getExpectedAlerts()[0], driver.getTitle());
1128 
1129         final WebElement t = driver.findElement(By.id("testId"));
1130         t.sendKeys(Keys.HOME);
1131         t.sendKeys("4");
1132         assertEquals(getExpectedAlerts()[1], t.getDomAttribute("value"));
1133         assertEquals(getExpectedAlerts()[2], t.getDomProperty("value"));
1134 
1135         driver.findElement(By.id("testBtn")).click();
1136         assertEquals(getExpectedAlerts()[3], driver.getTitle());
1137     }
1138 
1139     /**
1140      * @throws Exception if the test fails
1141      */
1142     @Test
1143     @Alerts({"2.1-2.1-2.1-false", "2.1", "42.1", "42.1-2.1-2.1-false"})
1144     public void typeValueNotReachableByStepDouble() throws Exception {
1145         final String html = DOCTYPE_HTML
1146             + "<html><head>\n"
1147             + "<script>\n"
1148             + "  function test() {\n"
1149             + "    var input = document.getElementById('testId');\n"
1150             + "    document.title = input.value + '-' "
1151                             + "+ input.defaultValue + '-' "
1152                             + "+ input.getAttribute('value')+ '-' "
1153                             + "+ input.checkValidity();\n"
1154             + "  }\n"
1155             + "</script>\n"
1156             + "</head><body onload='test()'>\n"
1157             + "<form>\n"
1158             + "  <input type='number' id='testId' value='2.1' min='0' max='200' step='0.5' >\n"
1159             + "  <input type='button' id='testBtn' onclick='test()' >\n"
1160             + "</form>\n"
1161             + "</body></html>";
1162 
1163         final WebDriver driver = loadPage2(html);
1164         assertEquals(getExpectedAlerts()[0], driver.getTitle());
1165 
1166         final WebElement t = driver.findElement(By.id("testId"));
1167         t.sendKeys(Keys.HOME);
1168         t.sendKeys("4");
1169         assertEquals(getExpectedAlerts()[1], t.getDomAttribute("value"));
1170         assertEquals(getExpectedAlerts()[2], t.getDomProperty("value"));
1171 
1172         driver.findElement(By.id("testBtn")).click();
1173         assertEquals(getExpectedAlerts()[3], driver.getTitle());
1174     }
1175 
1176     /**
1177      * @throws Exception if the test fails
1178      */
1179     @Test
1180     @Alerts(DEFAULT = {"--null-true", "4", "4--null-true", "4", "4--null-true"},
1181             FF = {"--null-true", "4", "4--null-true", "", "--null-false"},
1182             FF_ESR = {"--null-true", "4", "4--null-true", "", "--null-false"})
1183     public void typeInvalidChars() throws Exception {
1184         final String html = DOCTYPE_HTML
1185             + "<html><head>\n"
1186             + "<script>\n"
1187             + "  function test() {\n"
1188             + "    var input = document.getElementById('testId');\n"
1189             + "    document.title = input.value + '-' "
1190                             + "+ input.defaultValue + '-' "
1191                             + "+ input.getAttribute('value')+ '-' "
1192                             + "+ input.checkValidity();\n"
1193             + "  }\n"
1194             + "</script>\n"
1195             + "</head><body onload='test()'>\n"
1196             + "<form>\n"
1197             + "  <input type='number' id='testId'>\n"
1198             + "  <input type='button' id='testBtn' onclick='test()' >\n"
1199             + "</form>\n"
1200             + "</body></html>";
1201 
1202         final WebDriver driver = loadPage2(html);
1203         assertEquals(getExpectedAlerts()[0], driver.getTitle());
1204 
1205         final WebElement t = driver.findElement(By.id("testId"));
1206         t.sendKeys(Keys.END, "4");
1207         assertNull(t.getDomAttribute("value"));
1208         assertEquals(getExpectedAlerts()[1], t.getDomProperty("value"));
1209 
1210         driver.findElement(By.id("testBtn")).click();
1211         assertEquals(getExpectedAlerts()[2], driver.getTitle());
1212 
1213         t.sendKeys(Keys.END, "a");
1214         assertNull(t.getDomAttribute("value"));
1215         assertEquals(getExpectedAlerts()[3], t.getDomProperty("value"));
1216 
1217         driver.findElement(By.id("testBtn")).click();
1218         assertEquals(getExpectedAlerts()[4], driver.getTitle());
1219     }
1220 
1221     /**
1222      * @throws Exception if the test fails
1223      */
1224     @Test
1225     @Alerts(DEFAULT = {"120", "120-0-0-true", "", "-0-0-true", "", "-0-0-true"},
1226             FF = {"120", "120-0-0-true", "", "-0-0-true", "", "-0-0-false"},
1227             FF_ESR = {"120", "120-0-0-true", "", "-0-0-true", "", "-0-0-false"})
1228     public void typeCharsAndClear() throws Exception {
1229         final String html = DOCTYPE_HTML
1230                 + "<html>\n"
1231                 + "<head>\n"
1232                 + "<script>\n"
1233                 + "  function test() {\n"
1234                 + "    var input = document.getElementById('inpt');\n"
1235                 + "    document.title = input.value + '-' "
1236                                 + "+ input.defaultValue + '-' "
1237                                 + "+ input.getAttribute('value')+ '-' "
1238                                 + "+ input.checkValidity();\n"
1239                 + "  }\n"
1240                 + "</script>\n"
1241                 + "</head>\n"
1242                 + "<body>\n"
1243                 + "  <input type='number' id='inpt' min='0' max='999' value='0' />\n"
1244                 + "  <button id='check' onclick='test()');'>"
1245                 + "DoIt</button>\n"
1246                 + "</body>\n"
1247                 + "</html>";
1248         final WebDriver driver = loadPage2(html);
1249 
1250         final WebElement input = driver.findElement(By.id("inpt"));
1251         final WebElement check = driver.findElement(By.id("check"));
1252 
1253         input.sendKeys("12");
1254         assertEquals("0", input.getDomAttribute("value"));
1255         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
1256         check.click();
1257         assertEquals(getExpectedAlerts()[1], driver.getTitle());
1258 
1259         input.clear();
1260         assertEquals("0", input.getDomAttribute("value"));
1261         assertEquals(getExpectedAlerts()[2], input.getDomProperty("value"));
1262         check.click();
1263         assertEquals(getExpectedAlerts()[3], driver.getTitle());
1264 
1265         input.sendKeys("abc");
1266         assertEquals("0", input.getDomAttribute("value"));
1267         assertEquals(getExpectedAlerts()[4], input.getDomProperty("value"));
1268         check.click();
1269         assertEquals(getExpectedAlerts()[5], driver.getTitle());
1270     }
1271 
1272 
1273     /**
1274      * @throws Exception if the test fails
1275      */
1276     @Test
1277     @Alerts(DEFAULT = "-0-0-true",
1278             FF = "-0-0-false",
1279             FF_ESR = "-0-0-false")
1280     public void issue321() throws Exception {
1281         final String html = DOCTYPE_HTML
1282                 + "<html>\n"
1283                 + "<head>\n"
1284                 + "<script>\n"
1285                 + LOG_TITLE_FUNCTION
1286                 + "  function test() {\n"
1287                 + "    var input = document.getElementById('inpt');\n"
1288                 + "    log(input.value + '-' "
1289                                 + "+ input.defaultValue + '-' "
1290                                 + "+ input.getAttribute('value')+ '-' "
1291                                 + "+ input.checkValidity());\n"
1292                 + "  }\n"
1293                 + "</script>\n"
1294                 + "</head>\n"
1295                 + "<body>\n"
1296                 + "  <input type='number' id='inpt' min='0' max='999' value='0' />\n"
1297                 + "  <button id='check' onclick='test()');'>"
1298                 + "DoIt</button>\n"
1299                 + "</body>\n"
1300                 + "</html>";
1301         final WebDriver driver = loadPage2(html);
1302 
1303         final WebElement input = driver.findElement(By.id("inpt"));
1304 
1305         input.clear();
1306         input.sendKeys("abc");
1307         ((JavascriptExecutor) driver).executeScript("test();");
1308         verifyTitle2(driver, getExpectedAlerts());
1309     }
1310 
1311     /**
1312      * @throws Exception if the test fails
1313      */
1314     @Test
1315     @Alerts({"13-13-13-true", "15-15-15-false", "17-15-15-false", "17-19-19-false"})
1316     public void valueNotReachableByStep() throws Exception {
1317         final String html = DOCTYPE_HTML
1318             + "<html><head>\n"
1319             + "<script>\n"
1320             + LOG_TITLE_FUNCTION
1321             + "  function test() {\n"
1322             + "    var input = document.getElementById('testId');\n"
1323             + "    log(input.value + '-' "
1324                             + "+ input.defaultValue + '-' "
1325                             + "+ input.getAttribute('value')+ '-' "
1326                             + "+ input.checkValidity());\n"
1327 
1328             + "    input.defaultValue = '15';\n"
1329             + "    log(input.value + '-' "
1330                             + "+ input.defaultValue + '-' "
1331                             + "+ input.getAttribute('value')+ '-' "
1332                             + "+ input.checkValidity());\n"
1333 
1334             + "    input.value = '17';\n"
1335             + "    log(input.value + '-' "
1336                             + "+ input.defaultValue + '-' "
1337                             + "+ input.getAttribute('value')+ '-' "
1338                             + "+ input.checkValidity());\n"
1339 
1340             + "    input.setAttribute('value', '19');\n"
1341             + "    log(input.value + '-' "
1342                             + "+ input.defaultValue + '-' "
1343                             + "+ input.getAttribute('value')+ '-' "
1344                             + "+ input.checkValidity());\n"
1345             + "  }\n"
1346             + "</script>\n"
1347             + "</head><body onload='test()'>\n"
1348             + "<form>\n"
1349             + "  <input type='number' id='testId' value='13' min='10' max='20' step='3' >\n"
1350             + "</form>\n"
1351             + "</body></html>";
1352 
1353         loadPageVerifyTitle2(html);
1354     }
1355 
1356     /**
1357      * @throws Exception if the test fails
1358      */
1359     @Test
1360     @Alerts({"1.3-1.3-1.3-true", "1.5-1.5-1.5-false", "1.7-1.5-1.5-false", "1.7-1.9-1.9-false"})
1361     public void valueNotReachableByStepDouble() throws Exception {
1362         final String html = DOCTYPE_HTML
1363             + "<html><head>\n"
1364             + "<script>\n"
1365             + LOG_TITLE_FUNCTION
1366             + "  function test() {\n"
1367             + "    var input = document.getElementById('testId');\n"
1368             + "    log(input.value + '-' "
1369                             + "+ input.defaultValue + '-' "
1370                             + "+ input.getAttribute('value')+ '-' "
1371                             + "+ input.checkValidity());\n"
1372 
1373             + "    input.defaultValue = '1.5';\n"
1374             + "    log(input.value + '-' "
1375                             + "+ input.defaultValue + '-' "
1376                             + "+ input.getAttribute('value')+ '-' "
1377                             + "+ input.checkValidity());\n"
1378 
1379             + "    input.value = '1.7';\n"
1380             + "    log(input.value + '-' "
1381                             + "+ input.defaultValue + '-' "
1382                             + "+ input.getAttribute('value')+ '-' "
1383                             + "+ input.checkValidity());\n"
1384 
1385             + "    input.setAttribute('value', '1.9');\n"
1386             + "    log(input.value + '-' "
1387                             + "+ input.defaultValue + '-' "
1388                             + "+ input.getAttribute('value')+ '-' "
1389                             + "+ input.checkValidity());\n"
1390             + "  }\n"
1391             + "</script>\n"
1392             + "</head><body onload='test()'>\n"
1393             + "<form>\n"
1394             + "  <input type='number' id='testId' value='1.3' min='1.0' max='2.0' step='0.3' >\n"
1395             + "</form>\n"
1396             + "</body></html>";
1397 
1398         loadPageVerifyTitle2(html);
1399     }
1400 
1401     /**
1402      * @throws Exception if the test fails
1403      */
1404     @Test
1405     @Alerts(DEFAULT = "textLength not available",
1406             FF = "7",
1407             FF_ESR = "7")
1408     public void textLength() throws Exception {
1409         final String html = DOCTYPE_HTML
1410             + "<html><head>\n"
1411             + "<script>\n"
1412             + LOG_TITLE_FUNCTION
1413             + "  function test() {\n"
1414             + "    var text = document.getElementById('testId');\n"
1415             + "    if(text.textLength) {\n"
1416             + "      log(text.textLength);\n"
1417             + "    } else {\n"
1418             + "      log('textLength not available');\n"
1419             + "    }\n"
1420             + "  }\n"
1421             + "</script>\n"
1422             + "</head><body onload='test()'>\n"
1423             + "<form>\n"
1424             + "  <input type='number' id='testId' value='1234567'>\n"
1425             + "</form>\n"
1426             + "</body></html>";
1427 
1428         loadPageVerifyTitle2(html);
1429     }
1430 
1431     /**
1432      * @throws Exception if an error occurs
1433      */
1434     @Test
1435     @Alerts("0")
1436     public void selection() throws Exception {
1437         final String html = DOCTYPE_HTML
1438             + "<html><head>\n"
1439             + "<script>\n"
1440             + LOG_TITLE_FUNCTION
1441             + "  function test() {\n"
1442             + "    var s = getSelection(document.getElementById('inpt'));\n"
1443             + "    if (s != undefined) {\n"
1444             + "      log(s.length);\n"
1445             + "    }\n"
1446             + "  }\n"
1447             + "  function getSelection(element) {\n"
1448             + "    try {\n"
1449             + "      return element.value.substring(element.selectionStart, element.selectionEnd);\n"
1450             + "    } catch(e) { logEx(e); }\n"
1451             + "  }\n"
1452             + "</script></head>\n"
1453             + "<body onload='test()'>\n"
1454             + "  <input type='number' id='inpt'/>\n"
1455             + "</body></html>";
1456 
1457         loadPageVerifyTitle2(html);
1458     }
1459 
1460     /**
1461      * @throws Exception if test fails
1462      */
1463     @Test
1464     @Alerts({"null,null", "null,null", "InvalidStateError/DOMException",
1465              "null,null", "InvalidStateError/DOMException", "null,null"})
1466     public void selection2_1() throws Exception {
1467         selection2(3, 10);
1468     }
1469 
1470     /**
1471      * @throws Exception if test fails
1472      */
1473     @Test
1474     @Alerts({"null,null", "null,null", "InvalidStateError/DOMException",
1475              "null,null", "InvalidStateError/DOMException", "null,null"})
1476     public void selection2_2() throws Exception {
1477         selection2(-3, 15);
1478     }
1479 
1480     /**
1481      * @throws Exception if test fails
1482      */
1483     @Test
1484     @Alerts({"null,null", "null,null", "InvalidStateError/DOMException",
1485              "null,null", "InvalidStateError/DOMException", "null,null"})
1486     public void selection2_3() throws Exception {
1487         selection2(10, 5);
1488     }
1489 
1490     private void selection2(final int selectionStart, final int selectionEnd) throws Exception {
1491         final String html = DOCTYPE_HTML
1492             + "<html>\n"
1493             + "<body>\n"
1494             + "<input id='myTextInput' value='1234567' type='number'>\n"
1495             + "<script>\n"
1496             + LOG_TITLE_FUNCTION
1497             + "  var input = document.getElementById('myTextInput');\n"
1498 
1499             + "  try {\n"
1500             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1501             + "  } catch(e) { logEx(e); }\n"
1502 
1503             + "  input.value = '12345678900';\n"
1504             + "  try {\n"
1505             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1506             + "  } catch(e) { logEx(e); }\n"
1507 
1508             + "  try {\n"
1509             + "    input.selectionStart = " + selectionStart + ";\n"
1510             + "  } catch(e) { logEx(e); }\n"
1511             + "  try {\n"
1512             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1513             + "  } catch(e) { logEx(e); }\n"
1514 
1515             + "  try {\n"
1516             + "    input.selectionEnd = " + selectionEnd + ";\n"
1517             + "  } catch(e) { logEx(e); }\n"
1518             + "  try {\n"
1519             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1520             + "  } catch(e) { logEx(e); }\n"
1521             + "</script>\n"
1522             + "</body>\n"
1523             + "</html>";
1524 
1525         loadPageVerifyTitle2(html);
1526     }
1527 
1528     /**
1529      * @throws Exception if test fails
1530      */
1531     @Test
1532     @Alerts({"null,null", "InvalidStateError/DOMException"})
1533     public void selectionOnUpdate() throws Exception {
1534         final String html = DOCTYPE_HTML
1535             + "<html>\n"
1536             + "<body>\n"
1537             + "<input id='myTextInput' value='1234567' type='number'>\n"
1538             + "<script>\n"
1539             + LOG_TITLE_FUNCTION
1540             + "  var input = document.getElementById('myTextInput');\n"
1541 
1542             + "  try {\n"
1543             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1544 
1545             + "    input.selectionStart = 4;\n"
1546             + "    input.selectionEnd = 5;\n"
1547             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1548             + "    input.value = '1234567890';\n"
1549             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1550 
1551             + "    input.value = '9876';\n"
1552             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1553 
1554             + "    input.selectionStart = 0;\n"
1555             + "    input.selectionEnd = 4;\n"
1556 
1557             + "    input.value = '7';\n"
1558             + "    log(input.selectionStart + ',' + input.selectionEnd);\n"
1559             + "  } catch(e) { logEx(e); }\n"
1560             + "</script>\n"
1561             + "</body>\n"
1562             + "</html>";
1563 
1564         loadPageVerifyTitle2(html);
1565     }
1566 
1567     /**
1568      * @throws Exception if the test fails
1569      */
1570     @Test
1571     public void submitOnEnter() throws Exception {
1572         final String html = DOCTYPE_HTML
1573             + "<html>\n"
1574             + "<body>\n"
1575             + "  <form action='result.html'>\n"
1576             + "    <input id='t' value='1234'/>\n"
1577             + "  </form>\n"
1578             + "</body>\n"
1579             + "</html>";
1580         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
1581 
1582         final WebDriver driver = loadPage2(html);
1583         final WebElement field = driver.findElement(By.id("t"));
1584 
1585         field.sendKeys(Keys.ENTER);
1586         if (useRealBrowser()) {
1587             Thread.sleep(400);
1588         }
1589 
1590         assertEquals(2, getMockWebConnection().getRequestCount());
1591     }
1592 
1593     /**
1594      * @throws Exception if the test fails
1595      */
1596     @Test
1597     public void sendKeysEnterWithoutForm() throws Exception {
1598         final String html = DOCTYPE_HTML
1599             + "<html>\n"
1600             + "<body>\n"
1601             + "  <input id='t' type='number' value='1234'>\n"
1602             + "</body>\n"
1603             + "</html>";
1604 
1605         final WebDriver driver = loadPage2(html);
1606         driver.findElement(By.id("t")).sendKeys("\n");
1607 
1608         assertEquals(1, getMockWebConnection().getRequestCount());
1609     }
1610 
1611     /**
1612      * @throws Exception if the test fails
1613      */
1614     @Test
1615     public void submitWithoutForm() throws Exception {
1616         final String html = DOCTYPE_HTML
1617             + "<html>\n"
1618             + "<body>\n"
1619             + "  <input id='t' type='number' value='1234'>\n"
1620             + "</body>\n"
1621             + "</html>";
1622 
1623         final WebDriver driver = loadPage2(html);
1624         Assertions.assertThrows(UnsupportedOperationException.class,
1625                 () -> driver.findElement(By.id("t")).submit());
1626 
1627         assertEquals(1, getMockWebConnection().getRequestCount());
1628     }
1629 
1630     /**
1631      * @throws Exception if the test fails
1632      */
1633     @Test
1634     @Alerts("--")
1635     public void minMaxStep() throws Exception {
1636         final String html = DOCTYPE_HTML
1637             + "<html>\n"
1638             + "<head>\n"
1639             + "<script>\n"
1640             + LOG_TITLE_FUNCTION
1641             + "  function test() {\n"
1642             + "    var input = document.getElementById('tester');\n"
1643             + "    log(input.min + '-' + input.max + '-' + input.step);\n"
1644             + "  }\n"
1645             + "</script>\n"
1646             + "</head>\n"
1647             + "<body onload='test()'>\n"
1648             + "<form>\n"
1649             + "  <input type='number' id='tester'>\n"
1650             + "</form>\n"
1651             + "</body>\n"
1652             + "</html>";
1653 
1654         loadPageVerifyTitle2(html);
1655     }
1656 
1657     /**
1658      * @throws Exception if the test fails
1659      */
1660     @Test
1661     @Alerts({"10", ""})
1662     public void clearInput() throws Exception {
1663         final String html = DOCTYPE_HTML
1664             + "<html>\n"
1665             + "<body>\n"
1666             + "<form>\n"
1667             + "  <input type='number' id='tester' value='10'>\n"
1668             + "</form>\n"
1669             + "</body>\n"
1670             + "</html>";
1671 
1672         final WebDriver driver = loadPage2(html);
1673         final WebElement element = driver.findElement(By.id("tester"));
1674         assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
1675         assertEquals(getExpectedAlerts()[0], element.getDomProperty("value"));
1676 
1677         element.clear();
1678         assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
1679         assertEquals(getExpectedAlerts()[1], element.getDomProperty("value"));
1680     }
1681 
1682     /**
1683      * @throws Exception if an error occurs
1684      */
1685     @Test
1686     @Alerts("false-true")
1687     public void maxValidation() throws Exception {
1688         final String html = DOCTYPE_HTML
1689             + "<html>\n"
1690             + "<head>\n"
1691             + "<script>\n"
1692             + LOG_TITLE_FUNCTION
1693             + "  function test() {\n"
1694             + "    var foo = document.getElementById('foo');\n"
1695             + "    var bar = document.getElementById('bar');\n"
1696             + "    log(foo.checkValidity() + '-' + bar.checkValidity() );\n"
1697             + "  }\n"
1698             + "</script>\n"
1699             + "</head>\n"
1700             + "<body onload='test()'>\n"
1701             + "  <input type='number' max='10' id='foo' value='12'>\n"
1702             + "  <input type='number' max='10' id='bar' value='8'>\n"
1703             + "</body>\n"
1704             + "</html>";
1705 
1706         loadPageVerifyTitle2(html);
1707     }
1708 
1709     /**
1710      * @throws Exception if an error occurs
1711      */
1712     @Test
1713     @Alerts("false-true")
1714     public void minValidation() throws Exception {
1715         final String html = DOCTYPE_HTML
1716             + "<html>\n"
1717             + "<head>\n"
1718             + "<script>\n"
1719             + LOG_TITLE_FUNCTION
1720             + "  function test() {\n"
1721             + "    var foo = document.getElementById('foo');\n"
1722             + "    var bar = document.getElementById('bar');\n"
1723             + "    log(foo.checkValidity() + '-' + bar.checkValidity() );\n"
1724             + "  }\n"
1725             + "</script>\n"
1726             + "</head>\n"
1727             + "<body onload='test()'>\n"
1728             + "  <input type='number' min='10' id='foo' value='8'>\n"
1729             + "  <input type='number' min='10' id='bar' value='10'>\n"
1730             + "</body>\n"
1731             + "</html>";
1732 
1733         loadPageVerifyTitle2(html);
1734     }
1735 
1736     /**
1737      * @throws Exception if an error occurs
1738      */
1739     @Test
1740     @Alerts({"123456789",
1741              "123456789",
1742              "true",
1743              "false-false-false-false-false-false-false-false-false-true-false",
1744              "true",
1745              "§§URL§§?k=123456789",
1746              "2"})
1747     public void patternValidationInvalid() throws Exception {
1748         validation("<input type='number' pattern='[0-7]{10,40}' id='e1' name='k' value='123456789'>\n",
1749                     "", null);
1750     }
1751 
1752     /**
1753      * @throws Exception if an error occurs
1754      */
1755     @Test
1756     @Alerts({"123456701234567012345670",
1757              "123456701234567012345670",
1758              "true",
1759              "false-false-false-false-false-false-false-false-false-true-false",
1760              "true",
1761              "§§URL§§?k=123456701234567012345670",
1762              "2"})
1763     public void patternValidationValid() throws Exception {
1764         validation("<input type='number' pattern='[0-7]{10,40}' "
1765                 + "id='e1' name='k' value='123456701234567012345670'>\n", "", null);
1766     }
1767 
1768     /**
1769      * @throws Exception if an error occurs
1770      */
1771     @Test
1772     @Alerts({"",
1773              "",
1774              "true",
1775              "false-false-false-false-false-false-false-false-false-true-false",
1776              "true",
1777              "§§URL§§?k=",
1778              "2"})
1779     public void patternValidationEmpty() throws Exception {
1780         validation("<input type='number' pattern='[0-9]{10,40}' id='e1' name='k' value=''>\n", "", null);
1781     }
1782 
1783     /**
1784      * @throws Exception if an error occurs
1785      */
1786     @Test
1787     @Alerts({" ",
1788              "",
1789              "true",
1790              "false-false-false-false-false-false-false-false-false-true-false",
1791              "true",
1792              "§§URL§§?k=", "2"})
1793     public void patternValidationBlank() throws Exception {
1794         validation("<input type='number' pattern='[0-9]{10,40}' id='e1' name='k' value=' '>\n", "", null);
1795     }
1796 
1797     /**
1798      * @throws Exception if an error occurs
1799      */
1800     @Test
1801     @Alerts({"  \t",
1802              "",
1803              "true",
1804              "false-false-false-false-false-false-false-false-false-true-false",
1805              "true",
1806              "§§URL§§?k=",
1807              "2"})
1808     public void patternValidationWhitespace() throws Exception {
1809         validation("<input type='number' pattern='[0-9]{10,40}' id='e1' name='k' value='  \t'>\n", "", null);
1810     }
1811 
1812     /**
1813      * @throws Exception if an error occurs
1814      */
1815     @Test
1816     @Alerts({" 210 ",
1817              "",
1818              "true",
1819              "false-false-false-false-false-false-false-false-false-true-false",
1820              "true",
1821              "§§URL§§?k=",
1822              "2"})
1823     public void patternValidationTrimInitial() throws Exception {
1824         validation("<input type='number' pattern='[ 012]{3,10}' id='e1' name='k' value=' 210 '>\n", "", null);
1825     }
1826 
1827     /**
1828      * @throws Exception if an error occurs
1829      */
1830     @Test
1831     @Alerts(DEFAULT = {"null",
1832                        "210",
1833                        "true",
1834                        "false-false-false-false-false-false-false-false-false-true-false",
1835                        "true",
1836                        "§§URL§§?k=210", "2"},
1837             FF = {"null",
1838                   "",
1839                   "false",
1840                   "true-false-false-false-false-false-false-false-false-false-false",
1841                   "true",
1842                   "§§URL§§", "1"},
1843             FF_ESR = {"null",
1844                       "",
1845                       "false",
1846                       "true-false-false-false-false-false-false-false-false-false-false",
1847                       "true",
1848                       "§§URL§§", "1"})
1849     @HtmlUnitNYI(FF = {"null",
1850                        " 210 ",
1851                        "false",
1852                        "false-false-false-false-false-false-false-false-false-true-false",
1853                        "true",
1854                        "§§URL§§", "1"},
1855                  FF_ESR = {"null",
1856                            " 210 ",
1857                            "false",
1858                            "false-false-false-false-false-false-false-false-false-true-false",
1859                            "true",
1860                            "§§URL§§", "1"})
1861     public void patternValidationTrimType() throws Exception {
1862         validation("<input type='number' pattern='[ 012]{3,10}' id='e1' name='k'>\n", "", " 210 ");
1863     }
1864 
1865     /**
1866      * @throws Exception if an error occurs
1867      */
1868     @Test
1869     @Alerts({"null",
1870              "1234",
1871              "true",
1872              "false-false-false-false-false-false-false-false-false-true-false",
1873              "true",
1874              "§§URL§§?k=1234", "2"})
1875     public void minLengthValidationInvalid() throws Exception {
1876         validation("<input type='number' minlength='5' id='e1' name='k'>\n", "", "1234");
1877     }
1878 
1879     /**
1880      * @throws Exception if an error occurs
1881      */
1882     @Test
1883     @Alerts({"12",
1884              "12",
1885              "true",
1886              "false-false-false-false-false-false-false-false-false-true-false",
1887              "true",
1888              "§§URL§§?k=12",
1889              "2"})
1890     public void minLengthValidationInvalidInitial() throws Exception {
1891         validation("<input type='number' minlength='5' id='e1' name='k' value='12'>\n", "", null);
1892     }
1893 
1894     /**
1895      * @throws Exception if an error occurs
1896      */
1897     @Test
1898     @Alerts({"null",
1899              "",
1900              "true",
1901              "false-false-false-false-false-false-false-false-false-true-false",
1902              "true",
1903              "§§URL§§?k=",
1904              "2"})
1905     public void minLengthValidationInvalidNoInitial() throws Exception {
1906         validation("<input type='number' minlength='5' id='e1' name='k'>\n", "", null);
1907     }
1908 
1909     /**
1910      * @throws Exception if an error occurs
1911      */
1912     @Test
1913     @Alerts({"null",
1914              "123456789",
1915              "true",
1916              "false-false-false-false-false-false-false-false-false-true-false",
1917              "true",
1918              "§§URL§§?k=123456789",
1919              "2"})
1920     public void minLengthValidationValid() throws Exception {
1921         validation("<input type='number' minlength='5' id='e1' name='k'>\n", "", "123456789");
1922     }
1923 
1924     /**
1925      * @throws Exception if an error occurs
1926      */
1927     @Test
1928     @Alerts({"null",
1929              "1234",
1930              "true",
1931              "false-false-false-false-false-false-false-false-false-true-false",
1932              "true",
1933              "§§URL§§?k=1234", "2"})
1934     public void maxLengthValidationValid() throws Exception {
1935         validation("<input type='number' maxlength='5' id='e1' name='k'>\n", "", "1234");
1936     }
1937 
1938     /**
1939      * @throws Exception if an error occurs
1940      */
1941     @Test
1942     @Alerts({"null",
1943              "123456789",
1944              "true",
1945              "false-false-false-false-false-false-false-false-false-true-false",
1946              "true",
1947              "§§URL§§?k=123456789",
1948              "2"})
1949     public void maxLengthValidationInvalid() throws Exception {
1950         validation("<input type='number' maxlength='5' id='e1' name='k'>\n", "", "123456789");
1951     }
1952 
1953     /**
1954      * @throws Exception if an error occurs
1955      */
1956     @Test
1957     @Alerts({"123456789",
1958              "123456789",
1959              "true",
1960              "false-false-false-false-false-false-false-false-false-true-false",
1961              "true",
1962              "§§URL§§?k=123456789",
1963              "2"})
1964     public void maxLengthValidationInvalidInitial() throws Exception {
1965         validation("<input type='number' maxlength='5' id='e1' name='k' value='123456789'>\n", "", null);
1966     }
1967 
1968     /**
1969      * @throws Exception if an error occurs
1970      */
1971     @Test
1972     @Alerts({"true", "false", "true", "false", "true"})
1973     public void willValidate() throws Exception {
1974         final String html = DOCTYPE_HTML
1975                 + "<html><head>\n"
1976                 + "  <script>\n"
1977                 + LOG_TITLE_FUNCTION
1978                 + "    function test() {\n"
1979                 + "      log(document.getElementById('o1').willValidate);\n"
1980                 + "      log(document.getElementById('o2').willValidate);\n"
1981                 + "      log(document.getElementById('o3').willValidate);\n"
1982                 + "      log(document.getElementById('o4').willValidate);\n"
1983                 + "      log(document.getElementById('o5').willValidate);\n"
1984                 + "    }\n"
1985                 + "  </script>\n"
1986                 + "</head>\n"
1987                 + "<body onload='test()'>\n"
1988                 + "  <form>\n"
1989                 + "    <input type='number' id='o1'>\n"
1990                 + "    <input type='number' id='o2' disabled>\n"
1991                 + "    <input type='number' id='o3' hidden>\n"
1992                 + "    <input type='number' id='o4' readonly>\n"
1993                 + "    <input type='number' id='o5' style='display: none'>\n"
1994                 + "  </form>\n"
1995                 + "</body></html>";
1996 
1997         loadPageVerifyTitle2(html);
1998     }
1999 
2000     /**
2001      * @throws Exception if an error occurs
2002      */
2003     @Test
2004     @Alerts({"null",
2005              "",
2006              "true",
2007              "false-false-false-false-false-false-false-false-false-true-false",
2008              "true",
2009              "§§URL§§?k=", "2"})
2010     public void validationEmpty() throws Exception {
2011         validation("<input type='number' id='e1' name='k'>\n", "", null);
2012     }
2013 
2014     /**
2015      * @throws Exception if an error occurs
2016      */
2017     @Test
2018     @Alerts({"null",
2019              "",
2020              "false",
2021              "false-true-false-false-false-false-false-false-false-false-false",
2022              "true",
2023              "§§URL§§", "1"})
2024     public void validationCustomValidity() throws Exception {
2025         validation("<input type='number' id='e1' name='k'>\n", "elem.setCustomValidity('Invalid');", null);
2026     }
2027 
2028     /**
2029      * @throws Exception if an error occurs
2030      */
2031     @Test
2032     @Alerts({"null",
2033              "",
2034              "false",
2035              "false-true-false-false-false-false-false-false-false-false-false",
2036              "true",
2037              "§§URL§§", "1"})
2038     public void validationBlankCustomValidity() throws Exception {
2039         validation("<input type='number' id='e1' name='k'>\n", "elem.setCustomValidity(' ');\n", null);
2040     }
2041 
2042     /**
2043      * @throws Exception if an error occurs
2044      */
2045     @Test
2046     @Alerts({"null",
2047              "",
2048              "true",
2049              "false-false-false-false-false-false-false-false-false-true-false",
2050              "true",
2051              "§§URL§§?k=",
2052              "2"})
2053     public void validationResetCustomValidity() throws Exception {
2054         validation("<input type='number' id='e1' name='k'>\n",
2055                 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');", null);
2056     }
2057 
2058     /**
2059      * @throws Exception if an error occurs
2060      */
2061     @Test
2062     @Alerts({"null",
2063              "",
2064              "false",
2065              "false-false-false-false-false-false-false-false-false-false-true",
2066              "true",
2067              "§§URL§§", "1"})
2068     public void validationRequired() throws Exception {
2069         validation("<input type='number' id='e1' name='k' required>\n", "", null);
2070     }
2071 
2072     /**
2073      * @throws Exception if an error occurs
2074      */
2075     @Test
2076     @Alerts({"null",
2077              "",
2078              "true",
2079              "false-false-false-false-false-false-false-false-false-true-false",
2080              "true",
2081              "§§URL§§?k=42",
2082              "2"})
2083     public void validationRequiredValueSet() throws Exception {
2084         validation("<input type='number' id='e1' name='k' required>\n", "elem.value='42';", null);
2085     }
2086 
2087     /**
2088      * @throws Exception if an error occurs
2089      */
2090     @Test
2091     @Alerts({"null",
2092              "",
2093              "true",
2094              "false-false-false-false-false-false-false-false-false-true-false",
2095              "true",
2096              "§§URL§§?k=567",
2097              "2"})
2098     public void validationPattern() throws Exception {
2099         validation("<input type='number' id='e1' name='k' pattern='[012]{3}'>\n", "elem.value='567';", null);
2100     }
2101 
2102     private void validation(final String htmlPart, final String jsPart, final String sendKeys) throws Exception {
2103         final String html = DOCTYPE_HTML
2104                 + "<html><head>\n"
2105                 + "  <script>\n"
2106                 + LOG_TITLE_FUNCTION
2107                 + "    function logValidityState(s) {\n"
2108                 + "      log(s.badInput"
2109                         + "+ '-' + s.customError"
2110                         + "+ '-' + s.patternMismatch"
2111                         + "+ '-' + s.rangeOverflow"
2112                         + "+ '-' + s.rangeUnderflow"
2113                         + "+ '-' + s.stepMismatch"
2114                         + "+ '-' + s.tooLong"
2115                         + "+ '-' + s.tooShort"
2116                         + " + '-' + s.typeMismatch"
2117                         + " + '-' + s.valid"
2118                         + " + '-' + s.valueMissing);\n"
2119                 + "    }\n"
2120                 + "    function test() {\n"
2121                 + "      var elem = document.getElementById('e1');\n"
2122                 + jsPart
2123                 + "      log(elem.checkValidity());\n"
2124                 + "      logValidityState(elem.validity);\n"
2125                 + "      log(elem.willValidate);\n"
2126                 + "    }\n"
2127                 + "  </script>\n"
2128                 + "</head>\n"
2129                 + "<body>\n"
2130                 + "  <form>\n"
2131                 + htmlPart
2132                 + "    <button id='myTest' type='button' onclick='test()'>Test</button>\n"
2133                 + "    <button id='myButton' type='submit'>Submit</button>\n"
2134                 + "  </form>\n"
2135                 + "</body></html>";
2136 
2137         final String secondContent = DOCTYPE_HTML
2138                 + "<html><head><title>second</title></head><body>\n"
2139                 + "  <p>hello world</p>\n"
2140                 + "</body></html>";
2141 
2142         getMockWebConnection().setResponse(URL_SECOND, secondContent);
2143         expandExpectedAlertsVariables(URL_FIRST);
2144 
2145         final WebDriver driver = loadPage2(html, URL_FIRST);
2146 
2147         final WebElement foo = driver.findElement(By.id("e1"));
2148         if (sendKeys != null) {
2149             foo.sendKeys(sendKeys);
2150         }
2151         assertEquals(getExpectedAlerts()[0], "" + foo.getDomAttribute("value"));
2152         assertEquals(getExpectedAlerts()[1], foo.getDomProperty("value"));
2153 
2154         driver.findElement(By.id("myTest")).click();
2155         verifyTitle2(driver, getExpectedAlerts()[2], getExpectedAlerts()[3], getExpectedAlerts()[4]);
2156 
2157         driver.findElement(By.id("myButton")).click();
2158         if (useRealBrowser()) {
2159             Thread.sleep(400);
2160         }
2161         assertEquals(getExpectedAlerts()[5], getMockWebConnection().getLastWebRequest().getUrl());
2162         assertEquals(Integer.parseInt(getExpectedAlerts()[6]), getMockWebConnection().getRequestCount());
2163     }
2164 }