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