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