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.htmlunit.util.MimeType;
20  import org.junit.jupiter.api.Test;
21  import org.openqa.selenium.By;
22  import org.openqa.selenium.WebDriver;
23  import org.openqa.selenium.WebElement;
24  
25  /**
26   * Tests for {@link HtmlRadioButtonInput}.
27   *
28   * @author Ahmed Ashour
29   * @author Marc Guillemot
30   * @author Benoit Heinrich
31   * @author Ronald Brill
32   * @author Frank Danek
33   */
34  public class HtmlRadioButtonInput2Test extends WebDriverTestCase {
35  
36      /**
37       * @throws Exception if the test fails
38       */
39      @Test
40      @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
41      public void checked_appendChild_docFragment() throws Exception {
42          performTest(true, true, false, true, false);
43      }
44  
45      /**
46       * @throws Exception if the test fails
47       */
48      @Test
49      @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
50      public void notchecked_appendChild_docFragment() throws Exception {
51          performTest(false, true, false, true, false);
52      }
53  
54      /**
55       * @throws Exception if the test fails
56       */
57      @Test
58      @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
59      public void checked_insertBefore_docFragment() throws Exception {
60          performTest(true, false, false, true, false);
61      }
62  
63      /**
64       * @throws Exception if the test fails
65       */
66      @Test
67      @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
68      public void notchecked_insertBefore_docFragment() throws Exception {
69          performTest(false, false, false, true, false);
70      }
71  
72      /**
73       * Verifies the behavior of 'checked' property on being attached to a page.
74       * @throws Exception if the test fails
75       */
76      @Test
77      @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
78      public void checked_appendChild_fromHtml_docFragment() throws Exception {
79          performTest(true, true, true, true, false);
80      }
81  
82      /**
83       * @throws Exception if the test fails
84       */
85      @Test
86      @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
87      public void notchecked_appendChild_fromHtml_docFragment() throws Exception {
88          performTest(false, true, true, true, false);
89      }
90  
91      /**
92       * @throws Exception if the test fails
93       */
94      @Test
95      @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
96      public void checked_insertBefore_fromHtml_docFragment() throws Exception {
97          performTest(true, false, true, true, false);
98      }
99  
100     /**
101      * @throws Exception if the test fails
102      */
103     @Test
104     @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
105     public void notchecked_insertBefore_fromHtml_docFragment() throws Exception {
106         performTest(false, false, true, true, false);
107     }
108 
109     /**
110      * Verifies the behavior of 'checked' property on being attached to a page.
111      * @throws Exception if the test fails
112      */
113     @Test
114     @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
115     public void checked_appendChild_docFragment_cloneNode() throws Exception {
116         performTest(true, true, false, true, true);
117     }
118 
119     /**
120      * @throws Exception if the test fails
121      */
122     @Test
123     @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
124     public void notchecked_appendChild_docFragment_cloneNode() throws Exception {
125         performTest(false, true, false, true, true);
126     }
127 
128     /**
129      * @throws Exception if the test fails
130      */
131     @Test
132     @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
133     public void checked_insertBefore_docFragment_cloneNode() throws Exception {
134         performTest(true, false, false, true, true);
135     }
136 
137     /**
138      * @throws Exception if the test fails
139      */
140     @Test
141     @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
142     public void notchecked_insertBefore_docFragment_cloneNode() throws Exception {
143         performTest(false, false, false, true, true);
144     }
145 
146     /**
147      * Verifies the behavior of 'checked' property on being attached to a page.
148      * @throws Exception if the test fails
149      */
150     @Test
151     @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
152     public void checked_appendChild_fromHtml_docFragment_cloneNode() throws Exception {
153         performTest(true, true, true, true, true);
154     }
155 
156     /**
157      * @throws Exception if the test fails
158      */
159     @Test
160     @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
161     public void notchecked_appendChild_fromHtml_docFragment_cloneNode() throws Exception {
162         performTest(false, true, true, true, true);
163     }
164 
165     /**
166      * @throws Exception if the test fails
167      */
168     @Test
169     @Alerts({"true", "true-true", "true-false", "true-false", "true-false", "true-false", "true-false"})
170     public void checked_insertBefore_fromHtml_docFragment_cloneNode() throws Exception {
171         performTest(true, false, true, true, true);
172     }
173 
174     /**
175      * @throws Exception if the test fails
176      */
177     @Test
178     @Alerts({"false", "false-true", "false-true", "false-true", "true-true", "true-false", "true-false"})
179     public void notchecked_insertBefore_fromHtml_docFragment_cloneNode() throws Exception {
180         performTest(false, false, true, true, true);
181     }
182 
183     /**
184      * @throws Exception if the test fails
185      */
186     @Test
187     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
188     public void checked_appendChild() throws Exception {
189         performTest(true, true, false, false, false);
190     }
191 
192     /**
193      * @throws Exception if the test fails
194      */
195     @Test
196     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
197     public void notchecked_appendChild() throws Exception {
198         performTest(false, true, false, false, false);
199     }
200 
201     /**
202      * @throws Exception if the test fails
203      */
204     @Test
205     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
206     public void checked_insertBefore() throws Exception {
207         performTest(true, false, false, false, false);
208     }
209 
210     /**
211      * @throws Exception if the test fails
212      */
213     @Test
214     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
215     public void notchecked_insertBefore() throws Exception {
216         performTest(false, false, false, false, false);
217     }
218 
219     /**
220      * Verifies the behavior of 'checked' property on being attached to a page.
221      * @throws Exception if the test fails
222      */
223     @Test
224     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
225     public void checked_appendChild_fromHtml() throws Exception {
226         performTest(true, true, true, false, false);
227     }
228 
229     /**
230      * @throws Exception if the test fails
231      */
232     @Test
233     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
234     public void notchecked_appendChild_fromHtml() throws Exception {
235         performTest(false, true, true, false, false);
236     }
237 
238     /**
239      * @throws Exception if the test fails
240      */
241     @Test
242     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
243     public void checked_insertBefore_fromHtml() throws Exception {
244         performTest(true, false, true, false, false);
245     }
246 
247     /**
248      * @throws Exception if the test fails
249      */
250     @Test
251     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
252     public void notchecked_insertBefore_fromHtml() throws Exception {
253         performTest(false, false, true, false, false);
254     }
255 
256     /**
257      * Verifies the behavior of 'checked' property on being attached to a page.
258      * @throws Exception if the test fails
259      */
260     @Test
261     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
262     public void checked_appendChild_cloneNode() throws Exception {
263         performTest(true, true, false, false, true);
264     }
265 
266     /**
267      * @throws Exception if the test fails
268      */
269     @Test
270     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
271     public void notchecked_appendChild_cloneNode() throws Exception {
272         performTest(false, true, false, false, true);
273     }
274 
275     /**
276      * @throws Exception if the test fails
277      */
278     @Test
279     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
280     public void checked_insertBefore_cloneNode() throws Exception {
281         performTest(true, false, false, false, true);
282     }
283 
284     /**
285      * @throws Exception if the test fails
286      */
287     @Test
288     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
289     public void notchecked_insertBefore_cloneNode() throws Exception {
290         performTest(false, false, false, false, true);
291     }
292 
293     /**
294      * Verifies the behavior of 'checked' property on being attached to a page.
295      * @throws Exception if the test fails
296      */
297     @Test
298     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
299     public void checked_appendChild_fromHtml_cloneNode() throws Exception {
300         performTest(true, true, true, false, true);
301     }
302 
303     /**
304      * @throws Exception if the test fails
305      */
306     @Test
307     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
308     public void notchecked_appendChild_fromHtml_cloneNode() throws Exception {
309         performTest(false, true, true, false, true);
310     }
311 
312     /**
313      * @throws Exception if the test fails
314      */
315     @Test
316     @Alerts({"true", "true-false", "true-false", "true-false", "true-false", "true-false"})
317     public void checked_insertBefore_fromHtml_cloneNode() throws Exception {
318         performTest(true, false, true, false, true);
319     }
320 
321     /**
322      * @throws Exception if the test fails
323      */
324     @Test
325     @Alerts({"false", "false-true", "false-true", "true-true", "true-false", "true-false"})
326     public void notchecked_insertBefore_fromHtml_cloneNode() throws Exception {
327         performTest(false, false, true, false, true);
328     }
329 
330     /**
331      * @param checked whether the created {@code input} is checked or not
332      * @param appendChild use {@code .appendChild} or {@code .insertBefore}
333      * @param fromHtml create the {@code input} by {@code .innerHTML} or by {@code document.createElement()}
334      * @param useFragment is {@code appendix} is a new {@code DocumentFragment} or the {@code input}
335      * @param cloneNode use {@code .cloneNode()}
336      */
337     private void performTest(final boolean checked,
338             final boolean appendChild,
339             final boolean fromHtml,
340             final boolean useFragment,
341             boolean cloneNode) throws Exception {
342         String html = DOCTYPE_HTML
343             + "<html>\n"
344             + "<head>\n"
345             + "  <script>\n"
346             + LOG_TITLE_FUNCTION
347             + "    function test() {\n"
348             + "      var existing = document.getElementById('rad1');\n";
349         if (fromHtml) {
350             html += ""
351                 + "      var builder = document.createElement('div');\n"
352                 + "      builder.innerHTML = '<input type=\"radio\" id=\"rad2\" name=\"radar\"";
353             if (checked) {
354                 html += " checked";
355             }
356             html += ">';\n"
357                 + "      var input = builder.firstChild;\n";
358         }
359         else {
360             html += ""
361                 + "      var input = document.createElement('input');\n"
362                 + "      input.type = 'radio';\n"
363                 + "      input.id = 'rad2';\n"
364                 + "      input.name = 'radar';\n";
365             if (checked) {
366                 html += "      input.checked = true;\n";
367             }
368         }
369 
370         if (cloneNode && !useFragment) {
371             html += "      input = input.cloneNode(true);\n";
372             cloneNode = false;
373         }
374         html += ""
375             + "      log(input.checked);\n"
376 
377             + "      var parent = document.getElementById('myDiv');\n"
378             + "      var after = document.getElementById('divAfter');\n";
379         if (useFragment) {
380             html += ""
381                     + "      var appendix = document.createDocumentFragment();\n"
382                     + "      appendix.appendChild(input);\n"
383                     + "      log(input.checked + '-' + existing.checked);\n";
384         }
385         else {
386             html += "      var appendix = input;\n";
387         }
388         if (appendChild) {
389             if (cloneNode) {
390                 html += "      parent.appendChild(appendix.cloneNode(true));\n";
391             }
392             else {
393                 html += "      parent.appendChild(appendix);\n";
394             }
395         }
396         else {
397             if (cloneNode) {
398                 html += "      parent.insertBefore(appendix.cloneNode(true), after);\n";
399             }
400             else {
401                 html += "      parent.insertBefore(appendix, after);\n";
402             }
403         }
404         html += ""
405             + "      input = document.getElementById('rad2');\n"
406             + "      log(input.checked + '-' + existing.checked);\n"
407             + "      parent.removeChild(input);\n"
408             + "      log(input.checked + '-' + existing.checked);\n"
409             + "\n"
410             + "      input.defaultChecked = true;\n"
411             + "      log(input.checked + '-' + existing.checked);\n"
412             + "      parent.appendChild(input);\n"
413             + "      log(input.checked + '-' + existing.checked);\n"
414             + "      parent.removeChild(input);\n"
415             + "      log(input.checked + '-' + existing.checked);\n"
416             + "    }\n"
417             + "  </script>\n"
418             + "</head><body onload='test()'>\n"
419             + "  <form><div id='myDiv'>\n"
420             + "    <input type='radio' id='rad1' name='radar' checked>\n"
421             + "  <div id='divAfter'></div></div></form>\n"
422             + "</body></html>";
423 
424         loadPageVerifyTitle2(html);
425     }
426 
427     /**
428      * @throws Exception if the test fails
429      */
430     @Test
431     @Alerts({"true-true", "false-false", "true-true", "false-false", "false-false", "false-false"})
432     public void defaultChecked() throws Exception {
433         final String html = DOCTYPE_HTML
434             + "<html>\n"
435             + "<head>\n"
436             + "  <script>\n"
437             + LOG_TITLE_FUNCTION
438             + "    function test() {\n"
439             + "      radio = document.getElementById('rad1');\n"
440             + "      radio2 = document.getElementById('rad2');\n"
441             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
442             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
443 
444             + "      radio.defaultChecked = true;\n"
445             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
446             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
447 
448             + "      radio.defaultChecked = false;\n"
449             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
450             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
451             + "    }\n"
452             + "  </script>\n"
453             + "</head><body onload='test()'>\n"
454             + "  <form>\n"
455             + "    <input type='radio' id='rad1' name='radar' checked>\n"
456             + "    <input type='radio' id='rad2' name='radar'>\n"
457             + "  </form>\n"
458             + "</body></html>";
459 
460         loadPageVerifyTitle2(html);
461     }
462 
463     /**
464      * @throws Exception if the test fails
465      */
466     @Test
467     @Alerts({"false-false", "false-false", "true-true", "false-false", "false-false", "false-false"})
468     public void defaultChecked_notchecked() throws Exception {
469         final String html = DOCTYPE_HTML
470             + "<html>\n"
471             + "<head>\n"
472             + "  <script>\n"
473             + LOG_TITLE_FUNCTION
474             + "    function test() {\n"
475             + "      radio = document.getElementById('rad1');\n"
476             + "      radio2 = document.getElementById('rad2');\n"
477             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
478             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
479 
480             + "      radio.defaultChecked = true;\n"
481             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
482             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
483 
484             + "      radio.defaultChecked = false;\n"
485             + "      log(radio.checked + '-' + radio.defaultChecked);\n"
486             + "      log(radio2.checked + '-' + radio2.defaultChecked);\n"
487             + "    }\n"
488             + "  </script>\n"
489             + "</head><body onload='test()'>\n"
490             + "  <form>\n"
491             + "    <input type='radio' id='rad1' name='radar'>\n"
492             + "    <input type='radio' id='rad2' name='radar'>\n"
493             + "  </form>\n"
494             + "</body></html>";
495 
496         loadPageVerifyTitle2(html);
497     }
498 
499     /**
500      * Regression test for bug #1033.
501      * As of 26.02.10, reading responseXML with xhtml namespace
502      * was causing ClassCastException for IE simulation when it contained a checked radio button.
503      * @throws Exception if the test fails.
504      */
505     @Test
506     @Alerts({"send request", "response read"})
507     public void checkedOnXmlResponse() throws Exception {
508         final String html = DOCTYPE_HTML
509             + "<html><body>\n"
510             + "<script>\n"
511             + LOG_TITLE_FUNCTION
512             + "  log('send request');\n"
513             + "  var xhr = new XMLHttpRequest();\n"
514             + "  xhr.open('GET', 'foo.xml', false);\n"
515             + "  xhr.send('');\n"
516             + "  var x = xhr.responseXML;\n" // this is what caused the exception
517             + "  log('response read');\n"
518             + "</script>\n"
519             + "</body></html>";
520 
521         final String xml
522             = "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
523             + "<body>\n"
524             + "<input type='radio' name='radio' checked='checked'/>\n"
525             + "</body>\n"
526             + "</html>";
527 
528         getMockWebConnection().setDefaultResponse(xml, MimeType.TEXT_XML);
529         loadPageVerifyTitle2(html);
530     }
531 
532     /**
533      * @throws Exception if the test fails
534      */
535     @Test
536     @Alerts({"foo", "change"})
537     public void onchangeFires() throws Exception {
538         final String html = DOCTYPE_HTML
539             + "<html><head><title>foo</title>\n"
540             + "<script>\n"
541             + LOG_TEXTAREA_FUNCTION
542             + "</script>\n"
543             + "</head><body>\n"
544             + "<form>\n"
545             + "<input type='radio' name='radioGroup' id='radio'"
546             + " onchange='log(\"foo\");log(event.type);'>Check me</input>\n"
547             + "</form>\n"
548             + LOG_TEXTAREA
549             + "</body></html>";
550 
551         final WebDriver driver = loadPage2(html);
552         driver.findElement(By.id("radio")).click();
553 
554         verifyTextArea2(driver, getExpectedAlerts());
555     }
556 
557     /**
558      * @throws Exception if the test fails
559      */
560     @Test
561     @Alerts({"foo", "change", "boo", "blur"})
562     public void onchangeFires2() throws Exception {
563         final String html = DOCTYPE_HTML
564             + "<html><head><title>foo</title>\n"
565             + "<script>\n"
566             + LOG_TEXTAREA_FUNCTION
567             + "</script>\n"
568             + "</head><body>\n"
569             + "<form>\n"
570             + "<input type='radio' name='radioGroup' id='radio1'"
571                         + " onChange='log(\"foo\");log(event.type);'"
572                         + " onBlur='log(\"boo\");log(event.type);'"
573             + ">Check Me</input>\n"
574             + "<input type='radio' name='radioGroup' id='radio2'>Or Check Me</input>\n"
575             + "</form>\n"
576             + LOG_TEXTAREA
577             + "</body></html>";
578 
579         final WebDriver driver = loadPage2(html);
580         driver.findElement(By.id("radio1")).click();
581         driver.findElement(By.id("radio2")).click();
582 
583         verifyTextArea2(driver, getExpectedAlerts());
584     }
585 
586     /**
587      * @throws Exception if the test fails
588      */
589     @Test
590     @Alerts("Second")
591     public void setChecked() throws Exception {
592         final String firstHtml = DOCTYPE_HTML
593             + "<html><head><title>First</title></head><body>\n"
594             + "<form>\n"
595             + "<input type='radio' name='radioGroup' id='radio'"
596             + " onchange=\"window.location.href='" + URL_SECOND + "'\">\n"
597             + "</form>\n"
598             + "</body></html>";
599         final String secondHtml = DOCTYPE_HTML
600             + "<html><head><title>Second</title></head><body></body></html>";
601 
602         getMockWebConnection().setDefaultResponse(secondHtml);
603         final WebDriver driver = loadPage2(firstHtml);
604 
605         driver.findElement(By.id("radio")).click();
606         assertTitle(driver, getExpectedAlerts()[0]);
607     }
608 
609     /**
610      * @throws Exception if the test fails
611      */
612     @Test
613     @Alerts("Second")
614     public void setChecked2() throws Exception {
615         final String firstHtml = DOCTYPE_HTML
616             + "<html><head><title>First</title></head><body>\n"
617             + "<form>\n"
618             + "<input type='radio' name='radioGroup' id='radio'"
619             + " onchange=\"window.location.href='" + URL_SECOND + "'\">\n"
620             + "<input id='myInput' type='text'>\n"
621             + "</form>\n"
622             + "</body></html>";
623         final String secondHtml = DOCTYPE_HTML
624             + "<html><head><title>Second</title></head><body></body></html>";
625 
626         getMockWebConnection().setDefaultResponse(secondHtml);
627         final WebDriver driver = loadPage2(firstHtml);
628 
629         driver.findElement(By.id("radio")).click();
630         assertTitle(driver, getExpectedAlerts()[0]);
631     }
632 
633     /**
634      * @throws Exception if an error occurs
635      */
636     @Test
637     public void preventDefault() throws Exception {
638         final String html = DOCTYPE_HTML
639             + "<html><head><script>\n"
640             + "  function handler(e) {\n"
641             + "    if (e)\n"
642             + "      e.preventDefault();\n"
643             + "    else\n"
644             + "      return false;\n"
645             + "  }\n"
646             + "  function init() {\n"
647             + "    document.getElementById('radio1').onclick = handler;\n"
648             + "  }\n"
649             + "</script></head>\n"
650             + "<body onload='init()'>\n"
651             + "  <input type='radio' id='radio1' name='radio1' />\n"
652             + "</body></html>";
653 
654         final WebDriver driver = loadPage2(html);
655         final WebElement radio = driver.findElement(By.id("radio1"));
656         radio.click();
657         assertFalse(radio.isSelected());
658     }
659 
660     /**
661      * Verifies that a HtmlRadioButton is unchecked by default.
662      * The onClick tests make this assumption.
663      * @throws Exception if the test fails
664      */
665     @Test
666     public void defaultState() throws Exception {
667         final String html = DOCTYPE_HTML
668             + "<html><head><title>foo</title></head><body>\n"
669             + "<form id='form1'>\n"
670             + "  <input type='radio' name='radio' id='radio'>Check me</input>\n"
671             + "</form></body></html>";
672         final WebDriver driver = loadPage2(html);
673         final WebElement radio = driver.findElement(By.id("radio"));
674         assertFalse(radio.isSelected());
675     }
676 
677     /**
678      * @throws Exception if the test fails
679      */
680     @Test
681     @Alerts({"on-", "on-", "on-", "on-"})
682     public void defaultValues() throws Exception {
683         final String html = DOCTYPE_HTML
684             + "<html><head>\n"
685             + "<script>\n"
686             + LOG_TITLE_FUNCTION
687             + "  function test() {\n"
688             + "    var input = document.getElementById('radio1');\n"
689             + "    log(input.value + '-' + input.defaultValue);\n"
690 
691             + "    input = document.getElementById('radio2');\n"
692             + "    log(input.value + '-' + input.defaultValue);\n"
693 
694             + "    input = document.createElement('input');\n"
695             + "    input.type = 'radio';\n"
696             + "    log(input.value + '-' + input.defaultValue);\n"
697 
698             + "    var builder = document.createElement('div');\n"
699             + "    builder.innerHTML = '<input type=\"radio\">';\n"
700             + "    input = builder.firstChild;\n"
701             + "    log(input.value + '-' + input.defaultValue);\n"
702             + "  }\n"
703             + "</script>\n"
704             + "</head><body onload='test()'>\n"
705             + "<form>\n"
706             + "  <input type='radio' id='radio1'>\n"
707             + "  <input type='radio' id='radio2' checked='true'>\n"
708             + "</form>\n"
709             + "</body></html>";
710 
711         loadPageVerifyTitle2(html);
712     }
713 
714     /**
715      * @throws Exception if the test fails
716      */
717     @Test
718     @Alerts({"on-", "on-", "on-", "on-"})
719     public void defaultValuesAfterClone() throws Exception {
720         final String html = DOCTYPE_HTML
721             + "<html><head>\n"
722             + "<script>\n"
723             + LOG_TITLE_FUNCTION
724             + "  function test() {\n"
725             + "    var input = document.getElementById('radio1');\n"
726             + "    input = input.cloneNode(false);\n"
727             + "    log(input.value + '-' + input.defaultValue);\n"
728 
729             + "    input = document.getElementById('radio2');\n"
730             + "    input = input.cloneNode(false);\n"
731             + "    log(input.value + '-' + input.defaultValue);\n"
732 
733             + "    input = document.createElement('input');\n"
734             + "    input.type = 'radio';\n"
735             + "    input = input.cloneNode(false);\n"
736             + "    log(input.value + '-' + input.defaultValue);\n"
737 
738             + "    var builder = document.createElement('div');\n"
739             + "    builder.innerHTML = '<input type=\"radio\">';\n"
740             + "    input = builder.firstChild;\n"
741             + "    input = input.cloneNode(false);\n"
742             + "    log(input.value + '-' + input.defaultValue);\n"
743             + "  }\n"
744             + "</script>\n"
745             + "</head><body onload='test()'>\n"
746             + "<form>\n"
747             + "  <input type='radio' id='radio1'>\n"
748             + "  <input type='radio' id='radio2' checked='true'>\n"
749             + "</form>\n"
750             + "</body></html>";
751 
752         loadPageVerifyTitle2(html);
753     }
754 
755     /**
756      * @throws Exception if the test fails
757      */
758     @Test
759     @Alerts({"initial-initial", "initial-initial", "newValue-newValue", "newValue-newValue",
760                 "newDefault-newDefault", "newDefault-newDefault"})
761     public void resetByClick() throws Exception {
762         final String html = DOCTYPE_HTML
763             + "<html><head>\n"
764             + "<script>\n"
765             + LOG_TITLE_FUNCTION
766             + "  function test() {\n"
767             + "    var radio = document.getElementById('testId');\n"
768             + "    log(radio.value + '-' + radio.defaultValue);\n"
769 
770             + "    document.getElementById('testReset').click;\n"
771             + "    log(radio.value + '-' + radio.defaultValue);\n"
772 
773             + "    radio.value = 'newValue';\n"
774             + "    log(radio.value + '-' + radio.defaultValue);\n"
775 
776             + "    document.getElementById('testReset').click;\n"
777             + "    log(radio.value + '-' + radio.defaultValue);\n"
778 
779             + "    radio.defaultValue = 'newDefault';\n"
780             + "    log(radio.value + '-' + radio.defaultValue);\n"
781 
782             + "    document.forms[0].reset;\n"
783             + "    log(radio.value + '-' + radio.defaultValue);\n"
784             + "  }\n"
785             + "</script>\n"
786             + "</head><body onload='test()'>\n"
787             + "<form>\n"
788             + "  <input type='radio' id='testId' name='radar' value='initial'>\n"
789             + "  <input type='reset' id='testReset'>\n"
790             + "</form>\n"
791             + "</body></html>";
792 
793         loadPageVerifyTitle2(html);
794     }
795 
796     /**
797      * @throws Exception if the test fails
798      */
799     @Test
800     @Alerts({"initial-initial", "initial-initial", "newValue-newValue", "newValue-newValue",
801                 "newDefault-newDefault", "newDefault-newDefault"})
802     public void resetByJS() throws Exception {
803         final String html = DOCTYPE_HTML
804             + "<html><head>\n"
805             + "<script>\n"
806             + LOG_TITLE_FUNCTION
807             + "  function test() {\n"
808             + "    var radio = document.getElementById('testId');\n"
809             + "    log(radio.value + '-' + radio.defaultValue);\n"
810 
811             + "    document.forms[0].reset;\n"
812             + "    log(radio.value + '-' + radio.defaultValue);\n"
813 
814             + "    radio.value = 'newValue';\n"
815             + "    log(radio.value + '-' + radio.defaultValue);\n"
816 
817             + "    document.forms[0].reset;\n"
818             + "    log(radio.value + '-' + radio.defaultValue);\n"
819 
820             + "    radio.defaultValue = 'newDefault';\n"
821             + "    log(radio.value + '-' + radio.defaultValue);\n"
822 
823             + "    document.forms[0].reset;\n"
824             + "    log(radio.value + '-' + radio.defaultValue);\n"
825             + "  }\n"
826             + "</script>\n"
827             + "</head><body onload='test()'>\n"
828             + "<form>\n"
829             + "  <input type='radio' id='testId' name='radar' value='initial'>\n"
830             + "</form>\n"
831             + "</body></html>";
832 
833         loadPageVerifyTitle2(html);
834     }
835 
836     /**
837      * @throws Exception if the test fails
838      */
839     @Test
840     @Alerts({"initial-initial", "default-default", "newValue-newValue", "newDefault-newDefault"})
841     public void defaultValue() throws Exception {
842         final String html = DOCTYPE_HTML
843             + "<html><head>\n"
844             + "<script>\n"
845             + LOG_TITLE_FUNCTION
846             + "  function test() {\n"
847             + "    var radio = document.getElementById('testId');\n"
848             + "    log(radio.value + '-' + radio.defaultValue);\n"
849 
850             + "    radio.defaultValue = 'default';\n"
851             + "    log(radio.value + '-' + radio.defaultValue);\n"
852 
853             + "    radio.value = 'newValue';\n"
854             + "    log(radio.value + '-' + radio.defaultValue);\n"
855             + "    radio.defaultValue = 'newDefault';\n"
856             + "    log(radio.value + '-' + radio.defaultValue);\n"
857             + "  }\n"
858             + "</script>\n"
859             + "</head><body onload='test()'>\n"
860             + "<form>\n"
861             + "  <input type='radio' id='testId' name='radar' value='initial'>\n"
862             + "</form>\n"
863             + "</body></html>";
864 
865         loadPageVerifyTitle2(html);
866     }
867 
868     /**
869      * Call to JS function click() should trigger the onchange handler but neither the onfocus handler
870      * nor the mousedown/up handlers.
871      * @throws Exception if the test fails
872      */
873     @Test
874     @Alerts("changed")
875     public void clickShouldTriggerOnchange() throws Exception {
876         final String html = DOCTYPE_HTML
877                 + "<html><head>\n"
878                 + "<script>\n"
879                 + LOG_TITLE_FUNCTION
880                 + "  function test() {\n"
881                 + "    var elt = document.getElementById('it');\n"
882                 + "    elt.click();\n"
883                 + "    document.getElementById('next').focus();\n"
884                 + "  }\n"
885                 + "</script>\n"
886                 + "</head>\n"
887                 + "<body onload='test()'>\n"
888                 + "<form>\n"
889                 + "  <input type='radio' id='it' onchange='log(\"changed\")'"
890                 + "    onmousedown='log(\"down\")' onmouseup='log(\"up\")' onfocus='log(\"focused\")'>Check me\n"
891                 + "  <input type='text' id='next'>\n"
892                 + "</form>\n"
893                 + "</body></html>";
894         loadPageVerifyTitle2(html);
895     }
896 
897     /**
898      * Test <code>input.checked</code> if the radio <code>&lt;input&gt;</code> do not have distinct 'value'.
899      * @throws Exception if the test fails
900      */
901     @Test
902     @Alerts({"false,false", "true,false", "false,true"})
903     public void radioInputChecked() throws Exception {
904         final String html = DOCTYPE_HTML
905             + "<html><head>\n"
906             + "</head>\n"
907             + "<body>\n"
908             + "<form name='myForm'>\n"
909             + "  <input type='radio' name='myRadio'>\n"
910             + "  <input type='radio' name='myRadio'>\n"
911             + "</form>\n"
912             + "<script>\n"
913             + LOG_TITLE_FUNCTION
914             + "  var r1 = document.forms.myForm.myRadio[0];\n"
915             + "  var r2 = document.forms.myForm.myRadio[1];\n"
916             + "  log(r1.checked + ',' + r2.checked);\n"
917             + "  r1.checked = true;\n"
918             + "  log(r1.checked + ',' + r2.checked);\n"
919             + "  r2.checked = true;\n"
920             + "  log(r1.checked + ',' + r2.checked);\n"
921             + "</script>\n"
922             + "</body></html>";
923 
924         loadPageVerifyTitle2(html);
925     }
926 
927     /**
928      * @throws Exception if the test fails
929      */
930     @Test
931     @Alerts({"true", "null", "true", "", "true", "yes"})
932     public void checkedAttribute() throws Exception {
933         final String html = DOCTYPE_HTML
934             + "<html><head>\n"
935             + "<script>\n"
936             + LOG_TITLE_FUNCTION
937             + "  function test() {\n"
938             + "    var checkbox = document.getElementById('r1');\n"
939             + "    log(checkbox.checked);\n"
940             + "    log(checkbox.getAttribute('checked'));\n"
941 
942             + "    checkbox = document.getElementById('r2');\n"
943             + "    log(checkbox.checked);\n"
944             + "    log(checkbox.getAttribute('checked'));\n"
945 
946             + "    checkbox = document.getElementById('r3');\n"
947             + "    log(checkbox.checked);\n"
948             + "    log(checkbox.getAttribute('checked'));\n"
949             + "  }\n"
950             + "</script>\n"
951             + "</head><body'>\n"
952             + "<form name='myForm'>\n"
953             + "  <input type='radio' id='r1' name='myRadio'>\n"
954             + "  <input type='radio' name='myRadio'>\n"
955             + "</form>\n"
956             + "<form name='myForm'>\n"
957             + "  <input type='radio' id='r2' name='myRadio' checked>\n"
958             + "  <input type='radio' name='myRadio'>\n"
959             + "</form>\n"
960             + "<form name='myForm'>\n"
961             + "  <input type='radio' id='r3' name='myRadio' checked='yes'>\n"
962             + "  <input type='radio' name='myRadio'>\n"
963             + "</form>\n"
964             + "  <button id='clickMe' onClick='test()'>do it</button>\n"
965             + "</body></html>";
966 
967         final WebDriver driver = loadPage2(html);
968         driver.findElement(By.id("r1")).click();
969         driver.findElement(By.id("r2")).click();
970         driver.findElement(By.id("r3")).click();
971 
972         driver.findElement(By.id("clickMe")).click();
973         verifyTitle2(driver, getExpectedAlerts());
974     }
975 
976     /**
977      * @throws Exception if the test fails
978      */
979     @Test
980     @Alerts({"false", "null", "true", "null", "false", "null", "true", "", "false", "",
981              "true", "", "true", "yes", "false", "yes", "true", "yes"})
982     public void checkedAttributeJS() throws Exception {
983         final String html = DOCTYPE_HTML
984             + "<html><head>\n"
985             + "<script>\n"
986             + LOG_TITLE_FUNCTION
987             + "  function test() {\n"
988             + "    var checkbox = document.getElementById('r1');\n"
989             + "    log(checkbox.checked);\n"
990             + "    log(checkbox.getAttribute('checked'));\n"
991 
992             + "    checkbox.checked = true;\n"
993             + "    log(checkbox.checked);\n"
994             + "    log(checkbox.getAttribute('checked'));\n"
995 
996             + "    checkbox.checked = false;\n"
997             + "    log(checkbox.checked);\n"
998             + "    log(checkbox.getAttribute('checked'));\n"
999 
1000             + "    checkbox = document.getElementById('r2');\n"
1001             + "    log(checkbox.checked);\n"
1002             + "    log(checkbox.getAttribute('checked'));\n"
1003 
1004             + "    checkbox.checked = false;\n"
1005             + "    log(checkbox.checked);\n"
1006             + "    log(checkbox.getAttribute('checked'));\n"
1007 
1008             + "    checkbox.checked = true;\n"
1009             + "    log(checkbox.checked);\n"
1010             + "    log(checkbox.getAttribute('checked'));\n"
1011 
1012             + "    checkbox = document.getElementById('r3');\n"
1013             + "    log(checkbox.checked);\n"
1014             + "    log(checkbox.getAttribute('checked'));\n"
1015 
1016             + "    checkbox.checked = false;\n"
1017             + "    log(checkbox.checked);\n"
1018             + "    log(checkbox.getAttribute('checked'));\n"
1019 
1020             + "    checkbox.checked = true;\n"
1021             + "    log(checkbox.checked);\n"
1022             + "    log(checkbox.getAttribute('checked'));\n"
1023             + "  }\n"
1024             + "</script>\n"
1025             + "</head><body onload='test()'>\n"
1026             + "<form name='myForm'>\n"
1027             + "  <input type='radio' id='r1' name='myRadio'>\n"
1028             + "  <input type='radio' name='myRadio'>\n"
1029             + "</form>\n"
1030             + "<form name='myForm'>\n"
1031             + "  <input type='radio' id='r2' name='myRadio' checked>\n"
1032             + "  <input type='radio' name='myRadio'>\n"
1033             + "</form>\n"
1034             + "<form name='myForm'>\n"
1035             + "  <input type='radio' id='r3' name='myRadio' checked='yes'>\n"
1036             + "  <input type='radio' name='myRadio'>\n"
1037             + "</form>\n"
1038             + "</body></html>";
1039 
1040         loadPageVerifyTitle2(html);
1041     }
1042 
1043     /**
1044      * @throws Exception if the test fails
1045      */
1046     @Test
1047     @Alerts({"false", "null", "false", "null", "true", "", "true", "",
1048              "true", "yes", "true", "yes"})
1049     public void defaultCheckedAttribute() throws Exception {
1050         final String html = DOCTYPE_HTML
1051             + "<html><head>\n"
1052             + "<script>\n"
1053             + LOG_TITLE_FUNCTION
1054             + "  function test() {\n"
1055             + "    var checkbox = document.getElementById('r1');\n"
1056             + "    log(checkbox.defaultChecked);\n"
1057             + "    log(checkbox.getAttribute('checked'));\n"
1058 
1059             + "    checkbox.checked = true;\n"
1060             + "    log(checkbox.defaultChecked);\n"
1061             + "    log(checkbox.getAttribute('checked'));\n"
1062 
1063             + "    checkbox = document.getElementById('r2');\n"
1064             + "    log(checkbox.defaultChecked);\n"
1065             + "    log(checkbox.getAttribute('checked'));\n"
1066 
1067             + "    checkbox.checked = false;\n"
1068             + "    log(checkbox.defaultChecked);\n"
1069             + "    log(checkbox.getAttribute('checked'));\n"
1070 
1071             + "    checkbox = document.getElementById('r3');\n"
1072             + "    log(checkbox.defaultChecked);\n"
1073             + "    log(checkbox.getAttribute('checked'));\n"
1074 
1075             + "    checkbox.checked = false;\n"
1076             + "    log(checkbox.defaultChecked);\n"
1077             + "    log(checkbox.getAttribute('checked'));\n"
1078             + "  }\n"
1079             + "</script>\n"
1080             + "</head><body onload='test()'>\n"
1081             + "<form name='myForm'>\n"
1082             + "  <input type='radio' id='r1' name='myRadio'>\n"
1083             + "  <input type='radio' name='myRadio'>\n"
1084             + "</form>\n"
1085             + "<form name='myForm'>\n"
1086             + "  <input type='radio' id='r2' name='myRadio' checked>\n"
1087             + "  <input type='radio' name='myRadio'>\n"
1088             + "</form>\n"
1089             + "<form name='myForm'>\n"
1090             + "  <input type='radio' id='r3' name='myRadio' checked='yes'>\n"
1091             + "  <input type='radio' name='myRadio'>\n"
1092             + "</form>\n"
1093             + "</body></html>";
1094 
1095         loadPageVerifyTitle2(html);
1096     }
1097 
1098     /**
1099      * @throws Exception if the test fails
1100      */
1101     @Test
1102     public void setCheckedOutsideForm() throws Exception {
1103         final String html = DOCTYPE_HTML
1104             + "<html><head>\n"
1105             + "</head>\n"
1106             + "<body>\n"
1107             + "<input type='radio' id='radio1' name='myRadio'>\n"
1108             + "<input type='radio' id='radio2' name='myRadio'>\n"
1109             + "<form name='myForm'>\n"
1110             + "  <input type='radio' id='radio3' name='myRadio'>\n"
1111             + "  <input type='radio' id='radio4' name='myRadio'>\n"
1112             + "</form>\n"
1113             + "</body></html>";
1114 
1115         final WebDriver driver = loadPage2(html);
1116 
1117         final WebElement radio1 = driver.findElement(By.id("radio1"));
1118         final WebElement radio2 = driver.findElement(By.id("radio2"));
1119         final WebElement radio3 = driver.findElement(By.id("radio3"));
1120         final WebElement radio4 = driver.findElement(By.id("radio4"));
1121 
1122         assertFalse(radio1.isSelected());
1123         assertFalse(radio2.isSelected());
1124         assertFalse(radio3.isSelected());
1125         assertFalse(radio4.isSelected());
1126 
1127         radio1.click();
1128 
1129         assertTrue(radio1.isSelected());
1130         assertFalse(radio2.isSelected());
1131         assertFalse(radio3.isSelected());
1132         assertFalse(radio4.isSelected());
1133 
1134         radio2.click();
1135 
1136         assertFalse(radio1.isSelected());
1137         assertTrue(radio2.isSelected());
1138         assertFalse(radio3.isSelected());
1139         assertFalse(radio4.isSelected());
1140 
1141         radio3.click();
1142 
1143         assertFalse(radio1.isSelected());
1144         assertTrue(radio2.isSelected());
1145         assertTrue(radio3.isSelected());
1146         assertFalse(radio4.isSelected());
1147 
1148         radio4.click();
1149 
1150         assertFalse(radio1.isSelected());
1151         assertTrue(radio2.isSelected());
1152         assertFalse(radio3.isSelected());
1153         assertTrue(radio4.isSelected());
1154     }
1155 
1156     /**
1157      * @throws Exception if the test fails
1158      */
1159     @Test
1160     @Alerts("--")
1161     public void minMaxStep() throws Exception {
1162         final String html = DOCTYPE_HTML
1163             + "<html>\n"
1164             + "<head>\n"
1165             + "<script>\n"
1166             + LOG_TITLE_FUNCTION
1167             + "  function test() {\n"
1168             + "    var input = document.getElementById('tester');\n"
1169             + "    log(input.min + '-' + input.max + '-' + input.step);\n"
1170             + "  }\n"
1171             + "</script>\n"
1172             + "</head>\n"
1173             + "<body onload='test()'>\n"
1174             + "<form>\n"
1175             + "  <input type='radio' id='tester'>\n"
1176             + "</form>\n"
1177             + "</body>\n"
1178             + "</html>";
1179 
1180         loadPageVerifyTitle2(html);
1181     }
1182 
1183     /**
1184      * @throws Exception if an error occurs
1185      */
1186     @Test
1187     @Alerts({"true", "false", "true", "false", "true"})
1188     public void willValidate() throws Exception {
1189         final String html = DOCTYPE_HTML
1190                 + "<html><head>\n"
1191                 + "  <script>\n"
1192                 + LOG_TITLE_FUNCTION
1193                 + "    function test() {\n"
1194                 + "      log(document.getElementById('o1').willValidate);\n"
1195                 + "      log(document.getElementById('o2').willValidate);\n"
1196                 + "      log(document.getElementById('o3').willValidate);\n"
1197                 + "      log(document.getElementById('o4').willValidate);\n"
1198                 + "      log(document.getElementById('o5').willValidate);\n"
1199                 + "    }\n"
1200                 + "  </script>\n"
1201                 + "</head>\n"
1202                 + "<body onload='test()'>\n"
1203                 + "  <form>\n"
1204                 + "    <input type='radio' id='o1'>\n"
1205                 + "    <input type='radio' id='o2' disabled>\n"
1206                 + "    <input type='radio' id='o3' hidden>\n"
1207                 + "    <input type='radio' id='o4' readonly>\n"
1208                 + "    <input type='radio' id='o5' style='display: none'>\n"
1209                 + "  </form>\n"
1210                 + "</body></html>";
1211 
1212         loadPageVerifyTitle2(html);
1213     }
1214 
1215     /**
1216      * @throws Exception if an error occurs
1217      */
1218     @Test
1219     @Alerts({"true",
1220              "false-false-false-false-false-false-false-false-false-true-false",
1221              "true"})
1222     public void validationEmpty() throws Exception {
1223         validation("<input type='radio' id='e1'>\n", "");
1224     }
1225 
1226     /**
1227      * @throws Exception if an error occurs
1228      */
1229     @Test
1230     @Alerts({"false",
1231              "false-true-false-false-false-false-false-false-false-false-false",
1232              "true"})
1233     public void validationCustomValidity() throws Exception {
1234         validation("<input type='radio' id='e1'>\n", "elem.setCustomValidity('Invalid');");
1235     }
1236 
1237     /**
1238      * @throws Exception if an error occurs
1239      */
1240     @Test
1241     @Alerts({"false",
1242              "false-true-false-false-false-false-false-false-false-false-false",
1243              "true"})
1244     public void validationBlankCustomValidity() throws Exception {
1245         validation("<input type='radio' id='e1'>\n", "elem.setCustomValidity(' ');\n");
1246     }
1247 
1248     /**
1249      * @throws Exception if an error occurs
1250      */
1251     @Test
1252     @Alerts({"true",
1253              "false-false-false-false-false-false-false-false-false-true-false",
1254              "true"})
1255     public void validationResetCustomValidity() throws Exception {
1256         validation("<input type='radio' id='e1'>\n",
1257                 "elem.setCustomValidity('Invalid');elem.setCustomValidity('');");
1258     }
1259 
1260     /**
1261      * @throws Exception if an error occurs
1262      */
1263     @Test
1264     @Alerts({"true",
1265              "false-false-false-false-false-false-false-false-false-true-false",
1266              "true"})
1267     public void validationRequired() throws Exception {
1268         validation("<input type='radio' id='e1' required>\n", "");
1269     }
1270 
1271     /**
1272      * @throws Exception if an error occurs
1273      */
1274     @Test
1275     @Alerts({"false",
1276              "false-false-false-false-false-false-false-false-false-false-true",
1277              "true"})
1278     public void validationRequiredWithName() throws Exception {
1279         validation("<input type='radio' id='e1' name='r1' required>\n", "");
1280     }
1281 
1282     /**
1283      * @throws Exception if an error occurs
1284      */
1285     @Test
1286     @Alerts({"true",
1287              "false-false-false-false-false-false-false-false-false-true-false",
1288              "true"})
1289     public void validationRequiredChecked() throws Exception {
1290         validation("<input type='radio' id='e1' required checked>\n", "");
1291     }
1292 
1293     /**
1294      * @throws Exception if an error occurs
1295      */
1296     @Test
1297     @Alerts({"true",
1298              "false-false-false-false-false-false-false-false-false-true-false",
1299              "true"})
1300     public void validationRequiredCheckedWithName() throws Exception {
1301         validation("<input type='radio' id='e1' name='r1' required checked>\n", "");
1302     }
1303 
1304     /**
1305      * @throws Exception if an error occurs
1306      */
1307     @Test
1308     @Alerts({"true",
1309              "false-false-false-false-false-false-false-false-false-true-false",
1310              "true"})
1311     public void validationRequiredClicked() throws Exception {
1312         validation("<input type='radio' id='e1' required>\n", "elem.click();");
1313     }
1314 
1315     /**
1316      * @throws Exception if an error occurs
1317      */
1318     @Test
1319     @Alerts({"true",
1320              "false-false-false-false-false-false-false-false-false-true-false",
1321              "true"})
1322     public void validationRequiredClickedWithName() throws Exception {
1323         validation("<input type='radio' id='e1' name='r1' required>\n", "elem.click();");
1324     }
1325 
1326     /**
1327      * @throws Exception if an error occurs
1328      */
1329     @Test
1330     @Alerts({"true",
1331              "false-false-false-false-false-false-false-false-false-true-false",
1332              "true"})
1333     public void validationRequiredClickUncheck() throws Exception {
1334         validation("<input type='radio' id='e1' name='test' required checked>\n"
1335                 + "<input type='radio' id='e2' name='test'>\n", "document.getElementById('e2').click();");
1336     }
1337 
1338     /**
1339      * @throws Exception if an error occurs
1340      */
1341     @Test
1342     @Alerts({"true",
1343              "false-false-false-false-false-false-false-false-false-true-false",
1344              "true"})
1345     public void validationRequiredClickUncheck2() throws Exception {
1346         validation("<input type='radio' id='e1' name='test' required>\n"
1347                 + "<input type='radio' id='e2' name='test'>\n", "document.getElementById('e2').click();");
1348     }
1349 
1350     /**
1351      * @throws Exception if an error occurs
1352      */
1353     @Test
1354     @Alerts({"true",
1355              "false-false-false-false-false-false-false-false-false-true-false",
1356              "true"})
1357     public void validationRequiredOther() throws Exception {
1358         validation("<input type='radio' id='e1' name='test' required>\n"
1359                 + "<input type='radio' id='e2' name='test' checked>\n", "");
1360     }
1361 
1362     private void validation(final String htmlPart, final String jsPart) throws Exception {
1363         final String html = DOCTYPE_HTML
1364                 + "<html><head>\n"
1365                 + "  <script>\n"
1366                 + LOG_TITLE_FUNCTION
1367                 + "    function logValidityState(s) {\n"
1368                 + "      log(s.badInput"
1369                         + "+ '-' + s.customError"
1370                         + "+ '-' + s.patternMismatch"
1371                         + "+ '-' + s.rangeOverflow"
1372                         + "+ '-' + s.rangeUnderflow"
1373                         + "+ '-' + s.stepMismatch"
1374                         + "+ '-' + s.tooLong"
1375                         + "+ '-' + s.tooShort"
1376                         + " + '-' + s.typeMismatch"
1377                         + " + '-' + s.valid"
1378                         + " + '-' + s.valueMissing);\n"
1379                 + "    }\n"
1380                 + "    function test() {\n"
1381                 + "      var elem = document.getElementById('e1');\n"
1382                 + jsPart
1383                 + "      log(elem.checkValidity());\n"
1384                 + "      logValidityState(elem.validity);\n"
1385                 + "      log(elem.willValidate);\n"
1386                 + "    }\n"
1387                 + "  </script>\n"
1388                 + "</head>\n"
1389                 + "<body onload='test()'>\n"
1390                 + "  <form>\n"
1391                 + htmlPart
1392                 + "  </form>\n"
1393                 + "</body></html>";
1394 
1395         loadPageVerifyTitle2(html);
1396     }
1397 }