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 org.htmlunit.SimpleWebTestCase;
18  import org.htmlunit.javascript.host.event.KeyboardEvent;
19  import org.htmlunit.junit.BrowserRunner;
20  import org.htmlunit.junit.annotation.Alerts;
21  import org.junit.Test;
22  import org.junit.runner.RunWith;
23  
24  /**
25   * Tests for {@link HtmlNumberInput}.
26   *
27   * @author Ronald Brill
28   * @author Anton Demydenko
29   * @author Michael Lueck
30   */
31  @RunWith(BrowserRunner.class)
32  public class HtmlNumberInput2Test extends SimpleWebTestCase {
33  
34      /**
35       * Verifies that asNormalizedText() returns the value string.
36       * @throws Exception if the test fails
37       */
38      @Test
39      @Alerts("123")
40      public void asNormalizedText() throws Exception {
41          final String html = DOCTYPE_HTML
42              + "<html>\n"
43              + "<head></head>\n"
44              + "<body>\n"
45              + "<form id='form1'>\n"
46              + "  <input type='number' name='tester' id='tester' value='123'>\n"
47              + "</form>\n"
48              + "</body></html>";
49  
50          final HtmlPage page = loadPage(html);
51          assertEquals(getExpectedAlerts()[0], page.getBody().asNormalizedText());
52      }
53  
54      /**
55       * @throws Exception if the test fails
56       */
57      @Test
58      public void typingAndClone() throws Exception {
59          final String htmlContent = DOCTYPE_HTML
60              + "<html>\n"
61              + "<head></head>\n"
62              + "<body>\n"
63              + "<form id='form1'>\n"
64              + "  <input type='number' id='foo'>\n"
65              + "</form>\n"
66              + "</body></html>";
67  
68          final HtmlPage page = loadPage(htmlContent);
69  
70          HtmlNumberInput input = (HtmlNumberInput) page.getElementById("foo");
71          input = (HtmlNumberInput) input.cloneNode(true);
72          input.type("4711");
73          assertEquals("", input.getValueAttribute());
74          assertEquals("4711", input.getValue());
75      }
76  
77      /**
78       * @throws Exception if the test fails
79       */
80      @Test
81      public void typingAndReset() throws Exception {
82          final String htmlContent = DOCTYPE_HTML
83              + "<html>\n"
84              + "<head></head>\n"
85              + "<body>\n"
86              + "<form id='form1'>\n"
87              + "  <input type='number' id='foo'>\n"
88              + "</form>\n"
89              + "</body></html>";
90  
91          final HtmlPage page = loadPage(htmlContent);
92  
93          final HtmlNumberInput input = (HtmlNumberInput) page.getElementById("foo");
94  
95          input.type("4711");
96          input.reset();
97          input.type("0815");
98  
99          assertEquals("", input.getValueAttribute());
100         assertEquals("0815", input.getValue());
101     }
102 
103     /**
104      * @throws Exception if the test fails
105      */
106     @Test
107     public void typingAndSetValueAttribute() throws Exception {
108         final String htmlContent = DOCTYPE_HTML
109             + "<html>\n"
110             + "<head></head>\n"
111             + "<body>\n"
112             + "<form id='form1'>\n"
113             + "  <input type='number' id='foo'>\n"
114             + "</form>\n"
115             + "</body></html>";
116 
117         final HtmlPage page = loadPage(htmlContent);
118 
119         final HtmlNumberInput input = (HtmlNumberInput) page.getElementById("foo");
120 
121         input.type("4711");
122         input.setValueAttribute("");
123         input.type("0815");
124 
125         assertEquals("", input.getValueAttribute());
126         assertEquals("47110815", input.getValue());
127     }
128 
129     /**
130      * @throws Exception if the test fails
131      */
132     @Test
133     public void typingAndSetValue() throws Exception {
134         final String htmlContent = DOCTYPE_HTML
135             + "<html>\n"
136             + "<head></head>\n"
137             + "<body>\n"
138             + "<form id='form1'>\n"
139             + "  <input type='number' id='foo'>\n"
140             + "</form>\n"
141             + "</body></html>";
142 
143         final HtmlPage page = loadPage(htmlContent);
144 
145         final HtmlNumberInput input = (HtmlNumberInput) page.getElementById("foo");
146 
147         input.type("4711");
148         input.setValue("");
149         input.type("0815");
150 
151         assertEquals("", input.getValueAttribute());
152         assertEquals("0815", input.getValue());
153     }
154 
155     /**
156      * @throws Exception if the test fails
157      */
158     @Test
159     public void minValidation() throws Exception {
160         final String htmlContent = DOCTYPE_HTML
161                 + "<html>\n"
162                 + "<head></head>\n"
163                 + "<body>\n"
164                 + "<form id='form1'>\n"
165                 + "  <input type='number' id='first' min='10'>\n"
166                 + "  <input type='number' id='second'>\n"
167                 + "  <input type='number' id='third' min='foo'>\n"
168                 + "</form>\n"
169                 + "</body></html>";
170 
171         final HtmlPage page = loadPage(htmlContent);
172 
173         final HtmlNumberInput first = (HtmlNumberInput) page.getElementById("first");
174         final HtmlNumberInput second = (HtmlNumberInput) page.getElementById("second");
175         final HtmlNumberInput third = (HtmlNumberInput) page.getElementById("third");
176 
177         // empty
178         assertTrue(first.isValid());
179         // lesser
180         first.setValue("9");
181         assertFalse(first.isValid());
182         // equal
183         first.setValue("10");
184         assertTrue(first.isValid());
185         // bigger
186         first.setValue("11");
187         assertTrue(first.isValid());
188 
189         second.setValue("10");
190         assertTrue(second.isValid());
191         third.setValue("10");
192         assertTrue(third.isValid());
193     }
194 
195     /**
196      * @throws Exception if the test fails
197      */
198     @Test
199     public void minValidationWithDecimalStepping() throws Exception {
200         final String htmlContent = DOCTYPE_HTML
201                 + "<html>\n"
202                 + "<head></head>\n"
203                 + "<body>\n"
204                 + "<form id='form1'>\n"
205                 + "  <input type='number' id='first' min='0.5' step='0.1'>\n"
206                 + "</form>\n"
207                 + "</body></html>";
208 
209         final HtmlPage page = loadPage(htmlContent);
210 
211         final HtmlNumberInput first = (HtmlNumberInput) page.getElementById("first");
212 
213         // empty
214         assertTrue(first.isValid());
215         // lesser
216         first.setValue("0.4");
217         assertFalse(first.isValid());
218         // equal
219         first.setValue("0.5");
220         assertTrue(first.isValid());
221         // bigger
222         first.setValue("0.6");
223         assertTrue(first.isValid());
224         // even bigger
225         first.setValue("1.6");
226         assertTrue(first.isValid());
227         // and even bigger again
228         first.setValue("2.1");
229         assertTrue(first.isValid());
230         // a lot bigger
231         first.setValue("10.8");
232         assertTrue(first.isValid());
233         // a lot bigger and insignificant decimal zeros
234         first.setValue("123456789.90");
235         assertTrue(first.isValid());
236 
237         //incorrect step
238         // a little bit different but still wroing
239         first.setValue("0.50000000000001");
240         assertFalse(first.isValid());
241         // still only little addition bit wrong nontheless
242         first.setValue("0.51");
243         assertFalse(first.isValid());
244         // even bigger
245         first.setValue("1.51");
246         assertFalse(first.isValid());
247         // and even bigger again
248         first.setValue("2.15");
249         assertFalse(first.isValid());
250         // a lot bigger
251         first.setValue("10.10001");
252         assertFalse(first.isValid());
253         // a lot bigger
254         first.setValue("123456789.1000001");
255         assertFalse(first.isValid());
256     }
257 
258     /**
259      * @throws Exception if the test fails
260      */
261     @Test
262     public void maxValidation() throws Exception {
263         final String htmlContent = DOCTYPE_HTML
264                 + "<html>\n"
265                 + "<head></head>\n"
266                 + "<body>\n"
267                 + "<form id='form1'>\n"
268                 + "  <input type='number' id='first' max='10'>\n"
269                 + "  <input type='number' id='second'>\n"
270                 + "  <input type='number' id='third' max='foo'>\n"
271                 + "</form>\n"
272                 + "</body></html>";
273 
274         final HtmlPage page = loadPage(htmlContent);
275 
276         final HtmlNumberInput first = (HtmlNumberInput) page.getElementById("first");
277         final HtmlNumberInput second = (HtmlNumberInput) page.getElementById("second");
278         final HtmlNumberInput third = (HtmlNumberInput) page.getElementById("third");
279 
280         // empty
281         assertTrue(first.isValid());
282         // lesser
283         first.setValue("8");
284         assertTrue(first.isValid());
285         // equal
286         first.setValue("10");
287         assertTrue(first.isValid());
288         // bigger
289         first.setValue("11");
290         assertFalse(first.isValid());
291 
292         second.setValue("10");
293         assertTrue(second.isValid());
294         third.setValue("10");
295         assertTrue(third.isValid());
296     }
297 
298     /**
299      * How could this test be migrated to WebDriver? How to select the field's content?
300      * @throws Exception if an error occurs
301      */
302     @Test
303     public void typeWhileSelected() throws Exception {
304         final String html = DOCTYPE_HTML
305             + "<html><head></head><body>\n"
306             + "<input type='number' id='myInput' value='123456789012345'><br>\n"
307             + "</body></html>";
308         final HtmlPage page = loadPage(html);
309         final HtmlNumberInput input = page.getHtmlElementById("myInput");
310         input.select();
311         input.type("9876543333210");
312         assertEquals("123456789012345", input.getValueAttribute());
313         assertEquals("9876543333210", input.getValue());
314     }
315 
316     /**
317      * @throws Exception if the test fails
318      */
319     @Test
320     public void typeLeftArrow() throws Exception {
321         final String html = DOCTYPE_HTML + "<html><head></head><body><input type='number' id='t'/></body></html>";
322         final HtmlPage page = loadPage(html);
323         final HtmlNumberInput t = page.getHtmlElementById("t");
324         t.type('2');
325         t.type('4');
326         t.type('6');
327         assertEquals("", t.getValueAttribute());
328         assertEquals("246", t.getValue());
329         t.type(KeyboardEvent.DOM_VK_LEFT);
330         assertEquals("", t.getValueAttribute());
331         assertEquals("246", t.getValue());
332         t.type('0');
333         assertEquals("", t.getValueAttribute());
334         assertEquals("2406", t.getValue());
335         t.type(KeyboardEvent.DOM_VK_SPACE);
336         assertEquals("", t.getValueAttribute());
337         assertEquals("240 6", t.getValue());
338     }
339 
340     /**
341      * @throws Exception if the test fails
342      */
343     @Test
344     public void typeDelKey() throws Exception {
345         final String html = DOCTYPE_HTML + "<html><head></head><body><input type='number' id='t'/></body></html>";
346         final HtmlPage page = loadPage(html);
347         final HtmlNumberInput t = page.getHtmlElementById("t");
348         t.type('2');
349         t.type('4');
350         t.type('7');
351         assertEquals("", t.getValueAttribute());
352         assertEquals("247", t.getValue());
353         t.type(KeyboardEvent.DOM_VK_LEFT);
354         t.type(KeyboardEvent.DOM_VK_LEFT);
355         assertEquals("", t.getValueAttribute());
356         assertEquals("247", t.getValue());
357         t.type(KeyboardEvent.DOM_VK_DELETE);
358         assertEquals("", t.getValueAttribute());
359         assertEquals("27", t.getValue());
360     }
361 
362     /**
363      * @throws Exception
364      *         if the test fails
365      */
366     @Test
367     @Alerts({"true", "true", "true", "", "1234567"})
368     public void maxLengthValidation() throws Exception {
369         final String htmlContent = DOCTYPE_HTML
370             + "<html>\n"
371             + "<head></head>\n"
372             + "<body>\n"
373             + "<form id='form1'>\n"
374             + "  <input type='number' id='foo' maxLength='6'>\n"
375             + "</form>\n"
376             + "</body></html>";
377 
378         final HtmlPage page = loadPage(htmlContent);
379 
380         // minlength and maxlength ignored by number input
381         final HtmlInput input = (HtmlInput) page.getElementById("foo");
382         assertEquals(getExpectedAlerts()[0], Boolean.toString(input.isValid()));
383         input.type("12345");
384         assertEquals(getExpectedAlerts()[1], Boolean.toString(input.isValid()));
385         input.type("67");
386         assertEquals(getExpectedAlerts()[2], Boolean.toString(input.isValid()));
387         assertEquals(getExpectedAlerts()[3], input.getValueAttribute());
388         assertEquals(getExpectedAlerts()[4], input.getValue());
389     }
390 
391     /**
392      * @throws Exception
393      *         if the test fails
394      */
395     @Test
396     @Alerts({"true", "true", "true", "", "12345"})
397     public void minLengthValidation() throws Exception {
398         final String htmlContent = DOCTYPE_HTML
399             + "<html>\n"
400             + "<head></head>\n"
401             + "<body>\n"
402             + "<form id='form1'>\n"
403             + "  <input type='number' id='foo' minLength='3'>\n"
404             + "</form>\n"
405             + "</body></html>";
406 
407         final HtmlPage page = loadPage(htmlContent);
408 
409         // minlength and maxlength ignored by number input
410         final HtmlInput input = (HtmlInput) page.getElementById("foo");
411         assertEquals(getExpectedAlerts()[0], Boolean.toString(input.isValid()));
412         input.type("12");
413         assertEquals(getExpectedAlerts()[1], Boolean.toString(input.isValid()));
414         input.type("345");
415         assertEquals(getExpectedAlerts()[2], Boolean.toString(input.isValid()));
416         assertEquals(getExpectedAlerts()[3], input.getValueAttribute());
417         assertEquals(getExpectedAlerts()[4], input.getValue());
418     }
419 }