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