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.htmlunit.junit.annotation.TestedBrowser.FF;
18  import static org.htmlunit.junit.annotation.TestedBrowser.FF_ESR;
19  
20  import org.htmlunit.WebDriverTestCase;
21  import org.htmlunit.junit.BrowserRunner;
22  import org.htmlunit.junit.annotation.Alerts;
23  import org.htmlunit.junit.annotation.NotYetImplemented;
24  import org.junit.Test;
25  import org.junit.runner.RunWith;
26  import org.openqa.selenium.By;
27  import org.openqa.selenium.WebDriver;
28  import org.openqa.selenium.WebElement;
29  import org.openqa.selenium.htmlunit.HtmlUnitDriver;
30  
31  /**
32   * Tests for {@link HtmlWeekInput}.
33   *
34   * @author Ronald Brill
35   * @author Anton Demydenko
36   */
37  @RunWith(BrowserRunner.class)
38  public class HtmlWeekInputTest extends WebDriverTestCase {
39  
40      /**
41       * @throws Exception if the test fails
42       */
43      @Test
44      @Alerts({"--null", "--null", "--null"})
45      public void defaultValues() throws Exception {
46          final String html = DOCTYPE_HTML
47              + "<html><head>\n"
48              + "<script>\n"
49              + LOG_TITLE_FUNCTION
50              + "  function test() {\n"
51              + "    var input = document.getElementById('text1');\n"
52              + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
53  
54              + "    try {\n"
55              + "      input = document.createElement('input');\n"
56              + "      input.type = 'week';\n"
57              + "      log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
58              + "    } catch(e)  { logEx(e); }\n"
59  
60              + "    var builder = document.createElement('div');\n"
61              + "    builder.innerHTML = '<input type=\"week\">';\n"
62              + "    input = builder.firstChild;\n"
63              + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
64              + "  }\n"
65              + "</script>\n"
66              + "</head><body onload='test()'>\n"
67              + "<form>\n"
68              + "  <input type='week' id='text1'>\n"
69              + "</form>\n"
70              + "</body></html>";
71  
72          loadPageVerifyTitle2(html);
73      }
74  
75      /**
76       * @throws Exception if the test fails
77       */
78      @Test
79      @Alerts({"--null", "--null", "--null"})
80      public void defaultValuesAfterClone() throws Exception {
81          final String html = DOCTYPE_HTML
82              + "<html><head>\n"
83              + "<script>\n"
84              + LOG_TITLE_FUNCTION
85              + "  function test() {\n"
86              + "    var input = document.getElementById('text1');\n"
87              + "    input = input.cloneNode(false);\n"
88              + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
89  
90              + "    try {\n"
91              + "      input = document.createElement('input');\n"
92              + "      input.type = 'week';\n"
93              + "      input = input.cloneNode(false);\n"
94              + "      log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
95              + "    } catch(e)  { logEx(e); }\n"
96  
97              + "    var builder = document.createElement('div');\n"
98              + "    builder.innerHTML = '<input type=\"week\">';\n"
99              + "    input = builder.firstChild;\n"
100             + "    input = input.cloneNode(false);\n"
101             + "    log(input.value + '-' + input.defaultValue + '-' + input.getAttribute('value'));\n"
102             + "  }\n"
103             + "</script>\n"
104             + "</head><body onload='test()'>\n"
105             + "<form>\n"
106             + "  <input type='week' id='text1'>\n"
107             + "</form>\n"
108             + "</body></html>";
109 
110         loadPageVerifyTitle2(html);
111     }
112 
113     /**
114      * @throws Exception if the test fails
115      */
116     @Test
117     @Alerts(DEFAULT = "36",
118             CHROME = "",
119             EDGE = "")
120     @NotYetImplemented({FF, FF_ESR})
121     public void typing() throws Exception {
122         final String htmlContent = DOCTYPE_HTML
123             + "<html><head><title>foo</title></head><body>\n"
124             + "<form id='form1'>\n"
125             + "  <input type='week' id='foo'>\n"
126             + "</form></body></html>";
127 
128         final WebDriver driver = loadPage2(htmlContent);
129 
130         final WebElement input = driver.findElement(By.id("foo"));
131 
132         input.sendKeys("36");
133         assertNull(input.getDomAttribute("value"));
134         assertEquals(getExpectedAlerts()[0], input.getDomProperty("value"));
135     }
136 
137     /**
138      * Verifies getVisibleText().
139      * @throws Exception if the test fails
140      */
141     @Test
142     @Alerts("")
143     public void getVisibleText() throws Exception {
144         final String htmlContent = DOCTYPE_HTML
145             + "<html>\n"
146             + "<head></head>\n"
147             + "<body>\n"
148             + "<form id='form1'>\n"
149             + "  <input type='week' name='tester' id='tester' value='2018-W20' min='2018-W18' max='2018-W26'>\n"
150             + "</form>\n"
151             + "</body></html>";
152 
153         final WebDriver driver = loadPage2(htmlContent);
154         final String text = driver.findElement(By.id("tester")).getText();
155         assertEquals(getExpectedAlerts()[0], text);
156 
157         if (driver instanceof HtmlUnitDriver) {
158             final HtmlPage page = (HtmlPage) getEnclosedPage();
159             assertEquals(getExpectedAlerts()[0], page.getBody().getVisibleText());
160         }
161     }
162 
163     /**
164      * Verifies clear().
165      * @throws Exception if the test fails
166      */
167     @Test
168     @Alerts({"2018-W20", ""})
169     public void clearInput() throws Exception {
170         final String htmlContent = DOCTYPE_HTML
171                 + "<html>\n"
172                 + "<head></head>\n"
173                 + "<body>\n"
174                 + "<form id='form1'>\n"
175                 + "  <input type='week' name='tester' id='tester' value='2018-W20'>\n"
176                 + "</form>\n"
177                 + "</body></html>";
178 
179         final WebDriver driver = loadPage2(htmlContent);
180         final WebElement element = driver.findElement(By.id("tester"));
181 
182         assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
183         assertEquals(getExpectedAlerts()[0], element.getDomProperty("value"));
184 
185         element.clear();
186         assertEquals(getExpectedAlerts()[0], element.getDomAttribute("value"));
187         assertEquals(getExpectedAlerts()[1], element.getDomProperty("value"));
188     }
189 
190     /**
191      * @throws Exception if the test fails
192      */
193     @Test
194     @Alerts("--")
195     public void minMaxStep() throws Exception {
196         final String html = DOCTYPE_HTML
197             + "<html>\n"
198             + "<head>\n"
199             + "<script>\n"
200             + LOG_TITLE_FUNCTION
201             + "  function test() {\n"
202             + "    var input = document.getElementById('tester');\n"
203             + "    log(input.min + '-' + input.max + '-' + input.step);\n"
204             + "  }\n"
205             + "</script>\n"
206             + "</head>\n"
207             + "<body onload='test()'>\n"
208             + "<form>\n"
209             + "  <input type='week' id='tester'>\n"
210             + "</form>\n"
211             + "</body>\n"
212             + "</html>";
213 
214         loadPageVerifyTitle2(html);
215     }
216 
217     /**
218      * @throws Exception if an error occurs
219      */
220     @Test
221     @Alerts(DEFAULT = "true-true",
222             CHROME = "false-true",
223             EDGE = "false-true")
224     public void maxValidation() throws Exception {
225         final String html = DOCTYPE_HTML
226             + "<html>\n"
227             + "<head>\n"
228             + "<script>\n"
229             + LOG_TITLE_FUNCTION
230             + "  function test() {\n"
231             + "    var foo = document.getElementById('foo');\n"
232             + "    var bar = document.getElementById('bar');\n"
233             + "    log(foo.checkValidity() + '-' + bar.checkValidity() );\n"
234             + "  }\n"
235             + "</script>\n"
236             + "</head>\n"
237             + "<body onload='test()'>\n"
238             + "  <input type='week' max='2018-W10' id='foo' value='2018-W11'>\n"
239             + "  <input type='week' max='2018-W10' id='bar' value='2018-W10'>\n"
240             + "</body>\n"
241             + "</html>";
242 
243         loadPageVerifyTitle2(html);
244     }
245 
246     /**
247      * @throws Exception if an error occurs
248      */
249     @Test
250     @Alerts(DEFAULT = "true-true",
251             CHROME = "false-true",
252             EDGE = "false-true")
253     public void minValidation() throws Exception {
254         final String html = DOCTYPE_HTML
255             + "<html>\n"
256             + "<head>\n"
257             + "<script>\n"
258             + LOG_TITLE_FUNCTION
259             + "  function test() {\n"
260             + "    var foo = document.getElementById('foo');\n"
261             + "    var bar = document.getElementById('bar');\n"
262             + "    log(foo.checkValidity() + '-' + bar.checkValidity() );\n"
263             + "  }\n"
264             + "</script>\n"
265             + "</head>\n"
266             + "<body onload='test()'>\n"
267             + "  <input type='week' min='2018-W10' id='foo' value='2018-W09'>\n"
268             + "  <input type='week' min='2018-W10' id='bar' value='2018-W10'>\n"
269             + "</body>\n"
270             + "</html>";
271 
272         loadPageVerifyTitle2(html);
273     }
274 
275     /**
276      * @throws Exception if an error occurs
277      */
278     @Test
279     @Alerts({"true", "false", "true", "false", "true"})
280     public void willValidate() throws Exception {
281         final String html = DOCTYPE_HTML
282                 + "<html><head>\n"
283                 + "  <script>\n"
284                 + LOG_TITLE_FUNCTION
285                 + "    function test() {\n"
286                 + "      log(document.getElementById('o1').willValidate);\n"
287                 + "      log(document.getElementById('o2').willValidate);\n"
288                 + "      log(document.getElementById('o3').willValidate);\n"
289                 + "      log(document.getElementById('o4').willValidate);\n"
290                 + "      log(document.getElementById('o5').willValidate);\n"
291                 + "    }\n"
292                 + "  </script>\n"
293                 + "</head>\n"
294                 + "<body onload='test()'>\n"
295                 + "  <form>\n"
296                 + "    <input type='week' id='o1'>\n"
297                 + "    <input type='week' id='o2' disabled>\n"
298                 + "    <input type='week' id='o3' hidden>\n"
299                 + "    <input type='week' id='o4' readonly>\n"
300                 + "    <input type='week' id='o5' style='display: none'>\n"
301                 + "  </form>\n"
302                 + "</body></html>";
303 
304         loadPageVerifyTitle2(html);
305     }
306 
307     /**
308      * @throws Exception if an error occurs
309      */
310     @Test
311     @Alerts({"true",
312              "false-false-false-false-false-false-false-false-false-true-false",
313              "true"})
314     public void validationEmpty() throws Exception {
315         validation("<input type='week' id='e1'>\n", "");
316     }
317 
318     /**
319      * @throws Exception if an error occurs
320      */
321     @Test
322     @Alerts({"false",
323              "false-true-false-false-false-false-false-false-false-false-false",
324              "true"})
325     public void validationCustomValidity() throws Exception {
326         validation("<input type='week' id='e1'>\n", "elem.setCustomValidity('Invalid');");
327     }
328 
329     /**
330      * @throws Exception if an error occurs
331      */
332     @Test
333     @Alerts({"false",
334              "false-true-false-false-false-false-false-false-false-false-false",
335              "true"})
336     public void validationBlankCustomValidity() throws Exception {
337         validation("<input type='week' id='e1'>\n", "elem.setCustomValidity(' ');\n");
338     }
339 
340     /**
341      * @throws Exception if an error occurs
342      */
343     @Test
344     @Alerts({"true",
345              "false-false-false-false-false-false-false-false-false-true-false",
346              "true"})
347     public void validationResetCustomValidity() throws Exception {
348         validation("<input type='week' id='e1'>\n",
349                 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');");
350     }
351 
352     /**
353      * @throws Exception if an error occurs
354      */
355     @Test
356     @Alerts({"false",
357              "false-false-false-false-false-false-false-false-false-false-true",
358              "true"})
359     public void validationRequired() throws Exception {
360         validation("<input type='week' id='e1' required>\n", "");
361     }
362 
363     /**
364      * @throws Exception if an error occurs
365      */
366     @Test
367     @Alerts({"true",
368              "false-false-false-false-false-false-false-false-false-true-false",
369              "true"})
370     public void validationRequiredValueSet() throws Exception {
371         validation("<input type='week' id='e1' required>\n", "elem.value='2018-W20';");
372     }
373 
374     private void validation(final String htmlPart, final String jsPart) throws Exception {
375         final String html = DOCTYPE_HTML
376                 + "<html><head>\n"
377                 + "  <script>\n"
378                 + LOG_TITLE_FUNCTION
379                 + "    function logValidityState(s) {\n"
380                 + "      log(s.badInput"
381                         + "+ '-' + s.customError"
382                         + "+ '-' + s.patternMismatch"
383                         + "+ '-' + s.rangeOverflow"
384                         + "+ '-' + s.rangeUnderflow"
385                         + "+ '-' + s.stepMismatch"
386                         + "+ '-' + s.tooLong"
387                         + "+ '-' + s.tooShort"
388                         + " + '-' + s.typeMismatch"
389                         + " + '-' + s.valid"
390                         + " + '-' + s.valueMissing);\n"
391                 + "    }\n"
392                 + "    function test() {\n"
393                 + "      var elem = document.getElementById('e1');\n"
394                 + jsPart
395                 + "      log(elem.checkValidity());\n"
396                 + "      logValidityState(elem.validity);\n"
397                 + "      log(elem.willValidate);\n"
398                 + "    }\n"
399                 + "  </script>\n"
400                 + "</head>\n"
401                 + "<body onload='test()'>\n"
402                 + "  <form>\n"
403                 + htmlPart
404                 + "  </form>\n"
405                 + "</body></html>";
406 
407         loadPageVerifyTitle2(html);
408     }
409 }