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.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.junit.jupiter.api.Test;
20  import org.openqa.selenium.By;
21  import org.openqa.selenium.WebDriver;
22  import org.openqa.selenium.WebElement;
23  
24  /**
25   * Tests for {@link HtmlCheckBoxInput}.
26   *
27   * @author Ahmed Ashour
28   * @author Ronald Brill
29   * @author Marc Guillemot
30   * @author Frank Danek
31   */
32  public class HtmlCheckBoxInput2Test extends WebDriverTestCase {
33  
34      /**
35       * @throws Exception if the test fails
36       */
37      @Test
38      @Alerts({"true", "true", "true"})
39      public void checked_appendChild_docFragment() throws Exception {
40          performTest(true, true, false, true, false);
41      }
42  
43      /**
44       * @throws Exception if the test fails
45       */
46      @Test
47      @Alerts({"false", "false", "false"})
48      public void notchecked_appendChild_docFragment() throws Exception {
49          performTest(false, true, false, true, false);
50      }
51  
52      /**
53       * @throws Exception if the test fails
54       */
55      @Test
56      @Alerts({"true", "true", "true"})
57      public void checked_insertBefore_docFragment() throws Exception {
58          performTest(true, false, false, true, false);
59      }
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      @Alerts({"false", "false", "false"})
66      public void notchecked_insertBefore_docFragment() throws Exception {
67          performTest(false, false, false, true, false);
68      }
69  
70      /**
71       * @throws Exception if the test fails
72       */
73      @Test
74      @Alerts({"true", "true", "true"})
75      public void checked_appendChild_fromHtml_docFragment() throws Exception {
76          performTest(true, true, true, true, false);
77      }
78  
79      /**
80       * @throws Exception if the test fails
81       */
82      @Test
83      @Alerts({"false", "false", "false"})
84      public void notchecked_appendChild_fromHtml_docFragment() throws Exception {
85          performTest(false, true, true, true, false);
86      }
87  
88      /**
89       * @throws Exception if the test fails
90       */
91      @Test
92      @Alerts({"true", "true", "true"})
93      public void checked_insertBefore_fromHtml_docFragment() throws Exception {
94          performTest(true, false, true, true, false);
95      }
96  
97      /**
98       * @throws Exception if the test fails
99       */
100     @Test
101     @Alerts({"false", "false", "false"})
102     public void notchecked_insertBefore_fromHtml_docFragment() throws Exception {
103         performTest(false, false, true, true, false);
104     }
105 
106     /**
107      * @throws Exception if the test fails
108      */
109     @Test
110     @Alerts({"true", "true", "true"})
111     public void checked_appendChild_docFragment_cloneNode() throws Exception {
112         performTest(true, true, false, true, true);
113     }
114 
115     /**
116      * @throws Exception if the test fails
117      */
118     @Test
119     @Alerts({"false", "false", "false"})
120     public void notchecked_appendChild_docFragment_cloneNode() throws Exception {
121         performTest(false, true, false, true, true);
122     }
123 
124     /**
125      * @throws Exception if the test fails
126      */
127     @Test
128     @Alerts({"true", "true", "true"})
129     public void checked_insertBefore_docFragment_cloneNode() throws Exception {
130         performTest(true, false, false, true, true);
131     }
132 
133     /**
134      * @throws Exception if the test fails
135      */
136     @Test
137     @Alerts({"false", "false", "false"})
138     public void notchecked_insertBefore_docFragment_cloneNode() throws Exception {
139         performTest(false, false, false, true, true);
140     }
141 
142     /**
143      * @throws Exception if the test fails
144      */
145     @Test
146     @Alerts({"true", "true", "true"})
147     public void checked_appendChild_fromHtml_docFragment_cloneNode() throws Exception {
148         performTest(true, true, true, true, true);
149     }
150 
151     /**
152      * @throws Exception if the test fails
153      */
154     @Test
155     @Alerts({"false", "false", "false"})
156     public void notchecked_appendChild_fromHtml_docFragment_cloneNode() throws Exception {
157         performTest(false, true, true, true, true);
158     }
159 
160     /**
161      * @throws Exception if the test fails
162      */
163     @Test
164     @Alerts({"true", "true", "true"})
165     public void checked_insertBefore_fromHtml_docFragment_cloneNode() throws Exception {
166         performTest(true, false, true, true, true);
167     }
168 
169     /**
170      * @throws Exception if the test fails
171      */
172     @Test
173     @Alerts({"false", "false", "false"})
174     public void notchecked_insertBefore_fromHtml_docFragment_cloneNode() throws Exception {
175         performTest(false, false, true, true, true);
176     }
177 
178     /**
179      * @throws Exception if the test fails
180      */
181     @Test
182     @Alerts({"true", "true", "true", "true", "true", "true"})
183     public void checked_appendChild() throws Exception {
184         performTest(true, true, false, false, false);
185     }
186 
187     /**
188      * @throws Exception if the test fails
189      */
190     @Test
191     @Alerts({"false", "false", "false", "true", "true", "true"})
192     public void notchecked_appendChild() throws Exception {
193         performTest(false, true, false, false, false);
194     }
195 
196     /**
197      * @throws Exception if the test fails
198      */
199     @Test
200     @Alerts({"true", "true", "true", "true", "true", "true"})
201     public void checked_insertBefore() throws Exception {
202         performTest(true, false, false, false, false);
203     }
204 
205     /**
206      * @throws Exception if the test fails
207      */
208     @Test
209     @Alerts({"false", "false", "false", "true", "true", "true"})
210     public void notchecked_insertBefore() throws Exception {
211         performTest(false, false, false, false, false);
212     }
213 
214     /**
215      * @throws Exception if the test fails
216      */
217     @Test
218     @Alerts({"true", "true", "true", "true", "true", "true"})
219     public void checked_appendChild_fromHtml() throws Exception {
220         performTest(true, true, true, false, false);
221     }
222 
223     /**
224      * @throws Exception if the test fails
225      */
226     @Test
227     @Alerts({"false", "false", "false", "true", "true", "true"})
228     public void notchecked_appendChild_fromHtml() throws Exception {
229         performTest(false, true, true, false, false);
230     }
231 
232     /**
233      * @throws Exception if the test fails
234      */
235     @Test
236     @Alerts({"true", "true", "true", "true", "true", "true"})
237     public void checked_insertBefore_fromHtml() throws Exception {
238         performTest(true, false, true, false, false);
239     }
240 
241     /**
242      * @throws Exception if the test fails
243      */
244     @Test
245     @Alerts({"false", "false", "false", "true", "true", "true"})
246     public void notchecked_insertBefore_fromHtml() throws Exception {
247         performTest(false, false, true, false, false);
248     }
249 
250     /**
251      * @throws Exception if the test fails
252      */
253     @Test
254     @Alerts({"true", "true", "true", "true", "true", "true"})
255     public void checked_appendChild_cloneNode() throws Exception {
256         performTest(true, true, false, false, true);
257     }
258 
259     /**
260      * @throws Exception if the test fails
261      */
262     @Test
263     @Alerts({"false", "false", "false", "true", "true", "true"})
264     public void notchecked_appendChild_cloneNode() throws Exception {
265         performTest(false, true, false, false, true);
266     }
267 
268     /**
269      * @throws Exception if the test fails
270      */
271     @Test
272     @Alerts({"true", "true", "true", "true", "true", "true"})
273     public void checked_insertBefore_cloneNode() throws Exception {
274         performTest(true, false, false, false, true);
275     }
276 
277     /**
278      * @throws Exception if the test fails
279      */
280     @Test
281     @Alerts({"false", "false", "false", "true", "true", "true"})
282     public void notchecked_insertBefore_cloneNode() throws Exception {
283         performTest(false, false, false, false, true);
284     }
285 
286     /**
287      * @throws Exception if the test fails
288      */
289     @Test
290     @Alerts({"true", "true", "true", "true", "true", "true"})
291     public void checked_appendChild_fromHtml_cloneNode() throws Exception {
292         performTest(true, true, true, false, true);
293     }
294 
295     /**
296      * @throws Exception if the test fails
297      */
298     @Test
299     @Alerts({"false", "false", "false", "true", "true", "true"})
300     public void notchecked_appendChild_fromHtml_cloneNode() throws Exception {
301         performTest(false, true, true, false, true);
302     }
303 
304     /**
305      * @throws Exception if the test fails
306      */
307     @Test
308     @Alerts({"true", "true", "true", "true", "true", "true"})
309     public void checked_insertBefore_fromHtml_cloneNode() throws Exception {
310         performTest(true, false, true, false, true);
311     }
312 
313     /**
314      * @throws Exception if the test fails
315      */
316     @Test
317     @Alerts({"false", "false", "false", "true", "true", "true"})
318     public void notchecked_insertBefore_fromHtml_cloneNode() throws Exception {
319         performTest(false, false, true, false, true);
320     }
321 
322     private void performTest(final boolean checked,
323             final boolean appendChild,
324             final boolean fromHtml,
325             final boolean useFragment,
326             boolean cloneNode) throws Exception {
327         String html = DOCTYPE_HTML
328             + "<html>\n"
329             + "<head>\n"
330             + "  <script>\n"
331             + LOG_TITLE_FUNCTION
332             + "    function test() {\n";
333         if (fromHtml) {
334             html = html
335                 + "      var builder = document.createElement('div');\n"
336                 + "      builder.innerHTML = '<input type=\"checkbox\"";
337             if (checked) {
338                 html = html + " checked";
339             }
340             html = html + ">';\n"
341                 + "      var input = builder.firstChild;\n";
342         }
343         else {
344             html = html
345                 + "      var input = document.createElement('input');\n"
346                 + "      input.type = 'checkbox';\n";
347             if (checked) {
348                 html = html + "      input.checked = true;\n";
349             }
350         }
351 
352         if (cloneNode && !useFragment) {
353             html = html
354                     + "      input=input.cloneNode(true);\n";
355             cloneNode = false;
356         }
357         html = html
358             + "      log(input.checked);\n"
359 
360             + "      var parent=document.getElementById('myDiv');\n"
361             + "      var after=document.getElementById('divAfter');\n";
362         if (useFragment) {
363             html = html
364                     + "      var appendix=document.createDocumentFragment();\n"
365                     + "      appendix.appendChild(input);\n"
366                     + "      log(input.checked);\n";
367         }
368         else {
369             html = html
370                     + "      var appendix=input;\n";
371         }
372         if (appendChild) {
373             if (cloneNode) {
374                 html = html + "      parent.appendChild(appendix.cloneNode(true));\n";
375             }
376             else {
377                 html = html + "      parent.appendChild(appendix);\n";
378             }
379         }
380         else {
381             if (cloneNode) {
382                 html = html + "      parent.insertBefore(appendix.cloneNode(true), after);\n";
383             }
384             else {
385                 html = html + "      parent.insertBefore(appendix, after);\n";
386             }
387         }
388         html = html
389             + "      input = parent.getElementsByTagName('input')[0];\n"
390             + "      log(input.checked);\n";
391         if (!useFragment) {
392             html = html
393                 + "      parent.removeChild(input);\n"
394                 + "      log(input.checked);\n"
395                 + "\n"
396                 + "      input.defaultChecked = true;\n"
397                 + "      log(input.checked);\n"
398                 + "      parent.appendChild(input);\n"
399                 + "      log(input.checked);\n"
400                 + "      parent.removeChild(input);\n"
401                 + "      log(input.checked);\n";
402         }
403         html = html
404             + "    }\n"
405             + "  </script>\n"
406             + "</head><body onload='test()'>\n"
407             + "  <form><div id='myDiv'><div id='divAfter'></div></div></form>\n"
408             + "</body></html>";
409 
410         loadPageVerifyTitle2(html);
411     }
412 
413     /**
414      * @throws Exception if the test fails
415      */
416     @Test
417     @Alerts({"true-true", "true-true", "false-false", "false-false", "true-true", "false-false"})
418     public void defaultChecked() throws Exception {
419         final String html = DOCTYPE_HTML
420             + "<html>\n"
421             + "<head>\n"
422             + "  <script>\n"
423             + LOG_TITLE_FUNCTION
424             + "    function test() {\n"
425             + "      chkbox = document.getElementById('chkboxChecked');\n"
426             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
427             + "      chkbox.defaultChecked = true;\n"
428             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
429             + "      chkbox.defaultChecked = false;\n"
430             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
431 
432             + "      chkbox = document.getElementById('chkboxNotChecked');\n"
433             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
434             + "      chkbox.defaultChecked = true;\n"
435             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
436             + "      chkbox.defaultChecked = false;\n"
437             + "      log(chkbox.checked + '-' + chkbox.defaultChecked);\n"
438             + "    }\n"
439             + "  </script>\n"
440             + "</head><body onload='test()'>\n"
441             + "  <form>\n"
442             + "    <input type='checkbox' id='chkboxChecked' checked>\n"
443             + "    <input type='checkbox' id='chkboxNotChecked'>\n"
444             + "  </form>\n"
445             + "</body></html>";
446 
447         loadPageVerifyTitle2(html);
448     }
449 
450     /**
451      * @throws Exception if the test fails
452      */
453     @Test
454     @Alerts({"foo", "change"})
455     public void onchangeFires() throws Exception {
456         final String html = DOCTYPE_HTML
457             + "<html><head><title>foo</title>\n"
458             + "<script>\n"
459             + LOG_TEXTAREA_FUNCTION
460             + "</script>\n"
461             + "</head><body>\n"
462             + "<form>\n"
463             + "  <input type='checkbox' id='chkbox' onchange='log(\"foo\");log(event.type);'>\n"
464             + "</form>\n"
465             + LOG_TEXTAREA
466             + "</body></html>";
467 
468         final WebDriver driver = loadPage2(html);
469         driver.findElement(By.id("chkbox")).click();
470 
471         verifyTextArea2(driver, getExpectedAlerts());
472     }
473 
474     /**
475      * @throws Exception if the test fails
476      */
477     @Test
478     @Alerts({"onchange change", "onblur blur"})
479     public void onchangeFires2() throws Exception {
480         final String html = DOCTYPE_HTML
481             + "<html><head><title>foo</title>\n"
482             + "<script>\n"
483             + LOG_TEXTAREA_FUNCTION
484             + "</script>\n"
485             + "</head><body>\n"
486             + "<form>\n"
487             + "<input type='checkbox' id='chkbox'"
488             + "  onChange='log(\"onchange \" + event.type);'"
489             + "  onBlur='log(\"onblur \" + event.type);'"
490             + ">\n"
491             + "<input type='checkbox' id='chkbox2'>\n"
492             + "</form>\n"
493             + LOG_TEXTAREA
494             + "</body></html>";
495 
496         final WebDriver driver = loadPage2(html);
497         driver.findElement(By.id("chkbox")).click();
498         driver.findElement(By.id("chkbox2")).click();
499 
500         verifyTextArea2(driver, getExpectedAlerts());
501     }
502 
503     /**
504      * @throws Exception if the test fails
505      */
506     @Test
507     @Alerts("Second")
508     public void setChecked() throws Exception {
509         final String firstHtml = DOCTYPE_HTML
510             + "<html><head><title>First</title></head><body>\n"
511             + "<form>\n"
512             + "<input id='myCheckbox' type='checkbox' onchange=\"window.location.href='" + URL_SECOND + "'\">\n"
513             + "</form>\n"
514             + "</body></html>";
515         final String secondHtml = DOCTYPE_HTML
516             + "<html><head><title>Second</title></head><body></body></html>";
517 
518         getMockWebConnection().setDefaultResponse(secondHtml);
519         final WebDriver driver = loadPage2(firstHtml);
520 
521         driver.findElement(By.id("myCheckbox")).click();
522         assertTitle(driver, getExpectedAlerts()[0]);
523     }
524 
525     /**
526      * @throws Exception if the test fails
527      */
528     @Test
529     @Alerts("Second")
530     public void setChecked2() throws Exception {
531         final String firstHtml = DOCTYPE_HTML
532             + "<html><head><title>First</title></head><body>\n"
533             + "<form>\n"
534             + "<input id='myCheckbox' type='checkbox' onchange=\"window.location.href='" + URL_SECOND + "'\">\n"
535             + "<input id='myInput' type='text'>\n"
536             + "</form>\n"
537             + "</body></html>";
538         final String secondHtml = DOCTYPE_HTML
539             + "<html><head><title>Second</title></head><body></body></html>";
540 
541         getMockWebConnection().setDefaultResponse(secondHtml);
542         final WebDriver driver = loadPage2(firstHtml);
543 
544         driver.findElement(By.id("myCheckbox")).click();
545         assertTitle(driver, getExpectedAlerts()[0]);
546     }
547 
548     /**
549      * @throws Exception if an error occurs
550      */
551     @Test
552     public void preventDefault() throws Exception {
553         final String html = DOCTYPE_HTML
554             + "<html><head><script>\n"
555             + "  function handler(e) {\n"
556             + "    if (e)\n"
557             + "      e.preventDefault();\n"
558             + "    else\n"
559             + "      return false;\n"
560             + "  }\n"
561             + "  function init() {\n"
562             + "    document.getElementById('checkbox1').onclick = handler;\n"
563             + "  }\n"
564             + "</script></head>\n"
565             + "<body onload='init()'>\n"
566             + "<input type='checkbox' id='checkbox1'/>\n"
567             + "</body></html>";
568 
569         final WebDriver driver = loadPage2(html);
570         final WebElement checkbox = driver.findElement(By.id("checkbox1"));
571         checkbox.click();
572         assertFalse(checkbox.isSelected());
573     }
574 
575     /**
576      * Verifies that a HtmlCheckBox is unchecked by default.
577      * The onClick tests make this assumption.
578      * @throws Exception if the test fails
579      */
580     @Test
581     public void defaultState() throws Exception {
582         final String html = DOCTYPE_HTML
583             + "<html><head><title>foo</title></head><body>\n"
584             + "<form id='form1'>\n"
585             + "  <input type='checkbox' name='checkbox' id='checkbox'>Check me</input>\n"
586             + "</form></body></html>";
587         final WebDriver driver = loadPage2(html);
588         final WebElement checkbox = driver.findElement(By.id("checkbox"));
589         assertFalse(checkbox.isSelected());
590     }
591 
592     /**
593      * @throws Exception if the test fails
594      */
595     @Test
596     @Alerts({"on-", "on-", "on-", "on-"})
597     public void defaultValues() throws Exception {
598         final String html = DOCTYPE_HTML
599             + "<html><head>\n"
600             + "<script>\n"
601             + LOG_TITLE_FUNCTION
602             + "  function test() {\n"
603             + "    var input = document.getElementById('chkbox1');\n"
604             + "    log(input.value + '-' + input.defaultValue);\n"
605 
606             + "    input = document.getElementById('chkbox2');\n"
607             + "    log(input.value + '-' + input.defaultValue);\n"
608 
609             + "    input = document.createElement('input');\n"
610             + "    input.type = 'checkbox';\n"
611             + "    log(input.value + '-' + input.defaultValue);\n"
612 
613             + "    var builder = document.createElement('div');\n"
614             + "    builder.innerHTML = '<input type=\"checkbox\">';\n"
615             + "    input = builder.firstChild;\n"
616             + "    log(input.value + '-' + input.defaultValue);\n"
617             + "  }\n"
618             + "</script>\n"
619             + "</head><body onload='test()'>\n"
620             + "<form>\n"
621             + "  <input type='checkbox' id='chkbox1'>\n"
622             + "  <input type='checkbox' id='chkbox2' checked='true'>\n"
623             + "</form>\n"
624             + "</body></html>";
625 
626         loadPageVerifyTitle2(html);
627     }
628 
629     /**
630      * @throws Exception if the test fails
631      */
632     @Test
633     @Alerts({"on-", "on-", "on-", "on-"})
634     public void defaultValuesAfterClone() throws Exception {
635         final String html = DOCTYPE_HTML
636             + "<html><head>\n"
637             + "<script>\n"
638             + LOG_TITLE_FUNCTION
639             + "  function test() {\n"
640             + "    var input = document.getElementById('chkbox1');\n"
641             + "    input = input.cloneNode(false);\n"
642             + "    log(input.value + '-' + input.defaultValue);\n"
643 
644             + "    input = document.getElementById('chkbox2');\n"
645             + "    input = input.cloneNode(false);\n"
646             + "    log(input.value + '-' + input.defaultValue);\n"
647 
648             + "    input = document.createElement('input');\n"
649             + "    input.type = 'checkbox';\n"
650             + "    input = input.cloneNode(false);\n"
651             + "    log(input.value + '-' + input.defaultValue);\n"
652 
653             + "    var builder = document.createElement('div');\n"
654             + "    builder.innerHTML = '<input type=\"checkbox\">';\n"
655             + "    input = builder.firstChild;\n"
656             + "    input = input.cloneNode(false);\n"
657             + "    log(input.value + '-' + input.defaultValue);\n"
658             + "  }\n"
659             + "</script>\n"
660             + "</head><body onload='test()'>\n"
661             + "<form>\n"
662             + "  <input type='checkbox' id='chkbox1'>\n"
663             + "  <input type='checkbox' id='chkbox2' checked='true'>\n"
664             + "</form>\n"
665             + "</body></html>";
666 
667         loadPageVerifyTitle2(html);
668     }
669 
670     /**
671      * @throws Exception if the test fails
672      */
673     @Test
674     @Alerts({"initial-initial", "initial-initial", "newValue-newValue", "newValue-newValue",
675                 "newDefault-newDefault", "newDefault-newDefault"})
676     public void resetByClick() throws Exception {
677         final String html = DOCTYPE_HTML
678             + "<html><head>\n"
679             + "<script>\n"
680             + LOG_TITLE_FUNCTION
681             + "  function test() {\n"
682             + "    var checkbox = document.getElementById('testId');\n"
683             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
684 
685             + "    document.getElementById('testReset').click;\n"
686             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
687 
688             + "    checkbox.value = 'newValue';\n"
689             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
690 
691             + "    document.getElementById('testReset').click;\n"
692             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
693 
694             + "    checkbox.defaultValue = 'newDefault';\n"
695             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
696 
697             + "    document.forms[0].reset;\n"
698             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
699             + "  }\n"
700             + "</script>\n"
701             + "</head><body onload='test()'>\n"
702             + "<form>\n"
703             + "  <input type='checkbox' id='testId' name='radar' value='initial'>\n"
704             + "  <input type='reset' id='testReset'>\n"
705             + "</form>\n"
706             + "</body></html>";
707 
708         loadPageVerifyTitle2(html);
709     }
710 
711     /**
712      * @throws Exception if the test fails
713      */
714     @Test
715     @Alerts({"initial-initial", "initial-initial", "newValue-newValue", "newValue-newValue",
716                 "newDefault-newDefault", "newDefault-newDefault"})
717     public void resetByJS() throws Exception {
718         final String html = DOCTYPE_HTML
719             + "<html><head>\n"
720             + "<script>\n"
721             + LOG_TITLE_FUNCTION
722             + "  function test() {\n"
723             + "    var checkbox = document.getElementById('testId');\n"
724             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
725 
726             + "    document.forms[0].reset;\n"
727             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
728 
729             + "    checkbox.value = 'newValue';\n"
730             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
731 
732             + "    document.forms[0].reset;\n"
733             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
734 
735             + "    checkbox.defaultValue = 'newDefault';\n"
736             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
737 
738             + "    document.forms[0].reset;\n"
739             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
740             + "  }\n"
741             + "</script>\n"
742             + "</head><body onload='test()'>\n"
743             + "<form>\n"
744             + "  <input type='checkbox' id='testId' name='radar' value='initial'>\n"
745             + "</form>\n"
746             + "</body></html>";
747 
748         loadPageVerifyTitle2(html);
749     }
750 
751     /**
752      * @throws Exception if the test fails
753      */
754     @Test
755     @Alerts({"initial-initial", "default-default", "newValue-newValue", "newDefault-newDefault"})
756     public void defaultValue() throws Exception {
757         final String html = DOCTYPE_HTML
758             + "<html><head>\n"
759             + "<script>\n"
760             + LOG_TITLE_FUNCTION
761             + "  function test() {\n"
762             + "    var checkbox = document.getElementById('testId');\n"
763             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
764 
765             + "    checkbox.defaultValue = 'default';\n"
766             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
767 
768             + "    checkbox.value = 'newValue';\n"
769             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
770             + "    checkbox.defaultValue = 'newDefault';\n"
771             + "    log(checkbox.value + '-' + checkbox.defaultValue);\n"
772             + "  }\n"
773             + "</script>\n"
774             + "</head><body onload='test()'>\n"
775             + "<form>\n"
776             + "  <input type='checkbox' id='testId' name='radar' value='initial'>\n"
777             + "</form>\n"
778             + "</body></html>";
779 
780         loadPageVerifyTitle2(html);
781     }
782 
783     /**
784      * Call to JS function click() should trigger the onchange handler but neither the onfocus handler
785      * nor the mousedown/up handlers.
786      * @throws Exception if the test fails
787      */
788     @Test
789     @Alerts("changed")
790     public void clickShouldTriggerOnchange() throws Exception {
791         final String html = DOCTYPE_HTML
792                 + "<html><head>\n"
793                 + "<script>\n"
794                 + LOG_TITLE_FUNCTION
795                 + "  function test() {\n"
796                 + "    var elt = document.getElementById('it');\n"
797                 + "    elt.click();\n"
798                 + "    document.getElementById('next').focus();\n"
799                 + "  }\n"
800                 + "</script>\n"
801                 + "</head><body onload='test()'>\n"
802                 + "<form>\n"
803                 + "  <input type='checkbox' id='it' onchange='log(\"changed\")'"
804                 + "    onmousedown='log(\"down\")' onmouseup='log(\"up\")' onfocus='log(\"focused\")'>Check me\n"
805                 + "  <input type='text' id='next'>\n"
806                 + "</form>\n"
807                 + "</body></html>";
808         loadPageVerifyTitle2(html);
809     }
810 
811     /**
812      * @throws Exception if the test fails
813      */
814     @Test
815     @Alerts({"true", "null", "false", "", "false", "yes"})
816     public void checkedAttribute() throws Exception {
817         final String html = DOCTYPE_HTML
818             + "<html><head>\n"
819             + "<script>\n"
820             + LOG_TITLE_FUNCTION
821             + "  function test() {\n"
822             + "    var checkbox = document.getElementById('c1');\n"
823             + "    log(checkbox.checked);\n"
824             + "    log(checkbox.getAttribute('checked'));\n"
825 
826             + "    checkbox = document.getElementById('c2');\n"
827             + "    log(checkbox.checked);\n"
828             + "    log(checkbox.getAttribute('checked'));\n"
829 
830             + "    checkbox = document.getElementById('c3');\n"
831             + "    log(checkbox.checked);\n"
832             + "    log(checkbox.getAttribute('checked'));\n"
833             + "  }\n"
834             + "</script>\n"
835             + "</head><body>\n"
836             + "<form>\n"
837             + "  <input type='checkbox' id='c1' name='radar' value='initial'>\n"
838             + "  <input type='checkbox' id='c2' name='radar' value='initial' checked>\n"
839             + "  <input type='checkbox' id='c3' name='radar' value='initial' checked='yes'>\n"
840             + "</form>\n"
841             + "  <button id='clickMe' onClick='test()'>do it</button>\n"
842             + "</body></html>";
843 
844         final WebDriver driver = loadPage2(html);
845         driver.findElement(By.id("c1")).click();
846         driver.findElement(By.id("c2")).click();
847         driver.findElement(By.id("c3")).click();
848 
849         driver.findElement(By.id("clickMe")).click();
850         verifyTitle2(driver, getExpectedAlerts());
851     }
852 
853     /**
854      * @throws Exception if the test fails
855      */
856     @Test
857     @Alerts({"false", "null", "true", "null", "false", "null", "true", "", "false", "", "true", "",
858                 "true", "yes", "false", "yes", "true", "yes"})
859     public void checkedAttributeJS() throws Exception {
860         final String html = DOCTYPE_HTML
861             + "<html><head>\n"
862             + "<script>\n"
863             + LOG_TITLE_FUNCTION
864             + "  function test() {\n"
865             + "    var checkbox = document.getElementById('c1');\n"
866             + "    log(checkbox.checked);\n"
867             + "    log(checkbox.getAttribute('checked'));\n"
868 
869             + "    checkbox.checked = true;\n"
870             + "    log(checkbox.checked);\n"
871             + "    log(checkbox.getAttribute('checked'));\n"
872 
873             + "    checkbox.checked = false;\n"
874             + "    log(checkbox.checked);\n"
875             + "    log(checkbox.getAttribute('checked'));\n"
876 
877             + "    checkbox = document.getElementById('c2');\n"
878             + "    log(checkbox.checked);\n"
879             + "    log(checkbox.getAttribute('checked'));\n"
880 
881             + "    checkbox.checked = false;\n"
882             + "    log(checkbox.checked);\n"
883             + "    log(checkbox.getAttribute('checked'));\n"
884 
885             + "    checkbox.checked = true;\n"
886             + "    log(checkbox.checked);\n"
887             + "    log(checkbox.getAttribute('checked'));\n"
888 
889             + "    checkbox = document.getElementById('c3');\n"
890             + "    log(checkbox.checked);\n"
891             + "    log(checkbox.getAttribute('checked'));\n"
892 
893             + "    checkbox.checked = false;\n"
894             + "    log(checkbox.checked);\n"
895             + "    log(checkbox.getAttribute('checked'));\n"
896 
897             + "    checkbox.checked = true;\n"
898             + "    log(checkbox.checked);\n"
899             + "    log(checkbox.getAttribute('checked'));\n"
900             + "  }\n"
901             + "</script>\n"
902             + "</head><body onload='test()'>\n"
903             + "<form>\n"
904             + "  <input type='checkbox' id='c1' name='radar' value='initial'>\n"
905             + "  <input type='checkbox' id='c2' name='radar' value='initial' checked>\n"
906             + "  <input type='checkbox' id='c3' name='radar' value='initial' checked='yes'>\n"
907             + "</form>\n"
908             + "</body></html>";
909 
910         loadPageVerifyTitle2(html);
911     }
912 
913     /**
914      * @throws Exception if the test fails
915      */
916     @Test
917     @Alerts({"false", "null", "false", "null", "true", "", "true", "",
918                 "true", "yes", "true", "yes"})
919     public void defaultCheckedAttribute() throws Exception {
920         final String html = DOCTYPE_HTML
921             + "<html><head>\n"
922             + "<script>\n"
923             + "  function test() {\n"
924             + LOG_TITLE_FUNCTION
925             + "    var checkbox = document.getElementById('c1');\n"
926             + "    log(checkbox.defaultChecked);\n"
927             + "    log(checkbox.getAttribute('checked'));\n"
928 
929             + "    checkbox.checked = true;\n"
930             + "    log(checkbox.defaultChecked);\n"
931             + "    log(checkbox.getAttribute('checked'));\n"
932 
933             + "    checkbox = document.getElementById('c2');\n"
934             + "    log(checkbox.defaultChecked);\n"
935             + "    log(checkbox.getAttribute('checked'));\n"
936 
937             + "    checkbox.checked = false;\n"
938             + "    log(checkbox.defaultChecked);\n"
939             + "    log(checkbox.getAttribute('checked'));\n"
940 
941             + "    checkbox = document.getElementById('c3');\n"
942             + "    log(checkbox.defaultChecked);\n"
943             + "    log(checkbox.getAttribute('checked'));\n"
944 
945             + "    checkbox.checked = false;\n"
946             + "    log(checkbox.defaultChecked);\n"
947             + "    log(checkbox.getAttribute('checked'));\n"
948             + "  }\n"
949             + "</script>\n"
950             + "</head><body onload='test()'>\n"
951             + "<form>\n"
952             + "  <input type='checkbox' id='c1' name='radar' value='initial'>\n"
953             + "  <input type='checkbox' id='c2' name='radar' value='initial' checked>\n"
954             + "  <input type='checkbox' id='c3' name='radar' value='initial' checked='yes'>\n"
955             + "</form>\n"
956             + "</body></html>";
957 
958         loadPageVerifyTitle2(html);
959     }
960 
961     /**
962      * @throws Exception if the test fails
963      */
964     @Test
965     @Alerts("--")
966     public void minMaxStep() throws Exception {
967         final String html = DOCTYPE_HTML
968             + "<html>\n"
969             + "<head>\n"
970             + "<script>\n"
971             + LOG_TITLE_FUNCTION
972             + "  function test() {\n"
973             + "    var input = document.getElementById('tester');\n"
974             + "    log(input.min + '-' + input.max + '-' + input.step);\n"
975             + "  }\n"
976             + "</script>\n"
977             + "</head>\n"
978             + "<body onload='test()'>\n"
979             + "<form>\n"
980             + "  <input type='checkbox' id='tester'>\n"
981             + "</form>\n"
982             + "</body>\n"
983             + "</html>";
984 
985         loadPageVerifyTitle2(html);
986     }
987 
988     /**
989      * @throws Exception if an error occurs
990      */
991     @Test
992     @Alerts({"true", "false", "true", "false", "true"})
993     public void willValidate() throws Exception {
994         final String html = DOCTYPE_HTML
995                 + "<html><head>\n"
996                 + "  <script>\n"
997                 + LOG_TITLE_FUNCTION
998                 + "    function test() {\n"
999                 + "      log(document.getElementById('o1').willValidate);\n"
1000                 + "      log(document.getElementById('o2').willValidate);\n"
1001                 + "      log(document.getElementById('o3').willValidate);\n"
1002                 + "      log(document.getElementById('o4').willValidate);\n"
1003                 + "      log(document.getElementById('o5').willValidate);\n"
1004                 + "    }\n"
1005                 + "  </script>\n"
1006                 + "</head>\n"
1007                 + "<body onload='test()'>\n"
1008                 + "  <form>\n"
1009                 + "    <input type='checkbox' id='o1'>\n"
1010                 + "    <input type='checkbox' id='o2' disabled>\n"
1011                 + "    <input type='checkbox' id='o3' hidden>\n"
1012                 + "    <input type='checkbox' id='o4' readonly>\n"
1013                 + "    <input type='checkbox' id='o5' style='display: none'>\n"
1014                 + "  </form>\n"
1015                 + "</body></html>";
1016 
1017         loadPageVerifyTitle2(html);
1018     }
1019 
1020     /**
1021      * @throws Exception if an error occurs
1022      */
1023     @Test
1024     @Alerts({"true",
1025              "false-false-false-false-false-false-false-false-false-true-false",
1026              "true"})
1027     public void validationEmpty() throws Exception {
1028         validation("<input type='checkbox' id='e1'>\n", "");
1029     }
1030 
1031     /**
1032      * @throws Exception if an error occurs
1033      */
1034     @Test
1035     @Alerts({"false",
1036              "false-true-false-false-false-false-false-false-false-false-false",
1037              "true"})
1038     public void validationCustomValidity() throws Exception {
1039         validation("<input type='checkbox' id='e1'>\n", "elem.setCustomValidity('Invalid');");
1040     }
1041 
1042     /**
1043      * @throws Exception if an error occurs
1044      */
1045     @Test
1046     @Alerts({"false",
1047              "false-true-false-false-false-false-false-false-false-false-false",
1048              "true"})
1049     public void validationBlankCustomValidity() throws Exception {
1050         validation("<input type='checkbox' id='e1'>\n", "elem.setCustomValidity(' ');\n");
1051     }
1052 
1053     /**
1054      * @throws Exception if an error occurs
1055      */
1056     @Test
1057     @Alerts({"true",
1058              "false-false-false-false-false-false-false-false-false-true-false",
1059              "true"})
1060     public void validationResetCustomValidity() throws Exception {
1061         validation("<input type='checkbox' id='e1'>\n",
1062                 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');");
1063     }
1064 
1065     /**
1066      * @throws Exception if an error occurs
1067      */
1068     @Test
1069     @Alerts({"false",
1070              "false-false-false-false-false-false-false-false-false-false-true",
1071              "true"})
1072     public void validationRequired() throws Exception {
1073         validation("<input type='checkbox' id='e1' required>\n", "");
1074     }
1075 
1076     /**
1077      * @throws Exception if an error occurs
1078      */
1079     @Test
1080     @Alerts({"true",
1081              "false-false-false-false-false-false-false-false-false-true-false",
1082              "true"})
1083     public void validationRequiredChecked() throws Exception {
1084         validation("<input type='checkbox' id='e1' required checked>\n", "");
1085     }
1086 
1087     /**
1088      * @throws Exception if an error occurs
1089      */
1090     @Test
1091     @Alerts({"true",
1092              "false-false-false-false-false-false-false-false-false-true-false",
1093              "true"})
1094     public void validationRequiredClicked() throws Exception {
1095         validation("<input type='checkbox' id='e1' required>\n", "elem.click();");
1096     }
1097 
1098     /**
1099      * @throws Exception if an error occurs
1100      */
1101     @Test
1102     @Alerts({"false",
1103              "false-false-false-false-false-false-false-false-false-false-true",
1104              "true"})
1105     public void validationRequiredClickUncheck() throws Exception {
1106         validation("<input type='checkbox' id='e1' required checked>\n", "elem.click();");
1107     }
1108 
1109     private void validation(final String htmlPart, final String jsPart) throws Exception {
1110         final String html = DOCTYPE_HTML
1111                 + "<html><head>\n"
1112                 + "  <script>\n"
1113                 + LOG_TITLE_FUNCTION
1114                 + "    function logValidityState(s) {\n"
1115                 + "      log(s.badInput"
1116                         + "+ '-' + s.customError"
1117                         + "+ '-' + s.patternMismatch"
1118                         + "+ '-' + s.rangeOverflow"
1119                         + "+ '-' + s.rangeUnderflow"
1120                         + "+ '-' + s.stepMismatch"
1121                         + "+ '-' + s.tooLong"
1122                         + "+ '-' + s.tooShort"
1123                         + " + '-' + s.typeMismatch"
1124                         + " + '-' + s.valid"
1125                         + " + '-' + s.valueMissing);\n"
1126                 + "    }\n"
1127                 + "    function test() {\n"
1128                 + "      var elem = document.getElementById('e1');\n"
1129                 + jsPart
1130                 + "      log(elem.checkValidity());\n"
1131                 + "      logValidityState(elem.validity);\n"
1132                 + "      log(elem.willValidate);\n"
1133                 + "    }\n"
1134                 + "  </script>\n"
1135                 + "</head>\n"
1136                 + "<body onload='test()'>\n"
1137                 + "  <form>\n"
1138                 + htmlPart
1139                 + "  </form>\n"
1140                 + "</body></html>";
1141 
1142         loadPageVerifyTitle2(html);
1143     }
1144 }