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.javascript.host.html;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.junit.jupiter.api.Test;
20  import org.openqa.selenium.By;
21  import org.openqa.selenium.WebDriver;
22  import org.openqa.selenium.WebElement;
23  
24  /**
25   * Tests for {@link HTMLLabelElement}.
26   *
27   * @author Ahmed Ashour
28   * @author Daniel Gredler
29   * @author Marc Guillemot
30   * @author Frank Danek
31   * @author Ronald Brill
32   */
33  public class HTMLLabelElementTest extends WebDriverTestCase {
34  
35      /**
36       * @throws Exception if the test fails
37       */
38      @Test
39      @Alerts("")
40      public void htmlForNone() throws Exception {
41          final String html = DOCTYPE_HTML
42              + "<html>\n"
43              + "  <head>\n"
44              + "    <script>\n"
45              + LOG_TITLE_FUNCTION
46              + "      function doTest() {\n"
47              + "        log(document.getElementById('label1').htmlFor);\n"
48              + "      }\n"
49              + "    </script>\n"
50              + "  </head>\n"
51              + "  <body onload='doTest()'>\n"
52              + "    <label id='label1'>Item</label>\n"
53              + "    <input type='text' id='text1'>\n"
54              + "  </body>\n"
55              + "</html>";
56  
57          loadPageVerifyTitle2(html);
58      }
59  
60      /**
61       * @throws Exception if the test fails
62       */
63      @Test
64      @Alerts("")
65      public void htmlForEmpty() throws Exception {
66          final String html = DOCTYPE_HTML
67              + "<html>\n"
68              + "  <head>\n"
69              + "    <script>\n"
70              + LOG_TITLE_FUNCTION
71              + "      function doTest() {\n"
72              + "        log(document.getElementById('label1').htmlFor);\n"
73              + "      }\n"
74              + "    </script>\n"
75              + "  </head>\n"
76              + "  <body onload='doTest()'>\n"
77              + "    <label id='label1' for=''>Item</label>\n"
78              + "    <input type='text' id='text1'>\n"
79              + "  </body>\n"
80              + "</html>";
81  
82          loadPageVerifyTitle2(html);
83      }
84  
85      /**
86       * @throws Exception if the test fails
87       */
88      @Test
89      @Alerts("unknown")
90      public void htmlForUnknown() throws Exception {
91          final String html = DOCTYPE_HTML
92              + "<html>\n"
93              + "  <head>\n"
94              + "    <script>\n"
95              + LOG_TITLE_FUNCTION
96              + "      function doTest() {\n"
97              + "        log(document.getElementById('label1').htmlFor);\n"
98              + "      }\n"
99              + "    </script>\n"
100             + "  </head>\n"
101             + "  <body onload='doTest()'>\n"
102             + "    <label id='label1' for='unknown'>Item</label>\n"
103             + "    <input type='text' id='text1'>\n"
104             + "  </body>\n"
105             + "</html>";
106 
107         loadPageVerifyTitle2(html);
108     }
109 
110     /**
111      * @throws Exception if the test fails
112      */
113     @Test
114     @Alerts("text1")
115     public void htmlForKnown() throws Exception {
116         final String html = DOCTYPE_HTML
117             + "<html>\n"
118             + "  <head>\n"
119             + "    <script>\n"
120             + LOG_TITLE_FUNCTION
121             + "      function doTest() {\n"
122             + "        log(document.getElementById('label1').htmlFor);\n"
123             + "      }\n"
124             + "    </script>\n"
125             + "  </head>\n"
126             + "  <body onload='doTest()'>\n"
127             + "    <label id='label1' for='text1'>Item</label>\n"
128             + "    <input type='text' id='text1'>\n"
129             + "  </body>\n"
130             + "</html>";
131 
132         loadPageVerifyTitle2(html);
133     }
134 
135     /**
136      * @throws Exception if the test fails
137      */
138     @Test
139     @Alerts({"unknown", "null", "null"})
140     public void htmlForSetToUnknown() throws Exception {
141         final String html = DOCTYPE_HTML
142             + "<html>\n"
143             + "  <head>\n"
144             + "    <script>\n"
145             + LOG_TITLE_FUNCTION
146             + "      function doTest() {\n"
147             + "        try {\n"
148             + "          document.getElementById('label1').htmlFor = 'unknown';\n"
149             + "        } catch(e) {"
150             + "          logEx(e);\n"
151             + "        }\n"
152             + "        log(document.getElementById('label1').htmlFor);\n"
153             + "        log(document.getElementById('label1').control);\n"
154             + "        log(document.getElementById('label1').form);\n"
155             + "      }\n"
156             + "    </script>\n"
157             + "  </head>\n"
158             + "  <body onload='doTest()'>\n"
159             + "    <label id='label1'>Item</label>\n"
160             + "    <form id='form1'>\n"
161             + "      <input type='text' id='text1'>\n"
162             + "    </form>\n"
163             + "  </body>\n"
164             + "</html>";
165 
166         loadPageVerifyTitle2(html);
167     }
168 
169     /**
170      * @throws Exception if the test fails
171      */
172     @Test
173     @Alerts({"div1", "null", "null"})
174     public void htmlForSetToNotLabelable() throws Exception {
175         final String html = DOCTYPE_HTML
176             + "<html>\n"
177             + "  <head>\n"
178             + "    <script>\n"
179             + LOG_TITLE_FUNCTION
180             + "      function doTest() {\n"
181             + "        try {\n"
182             + "          document.getElementById('label1').htmlFor = 'div1';\n"
183             + "        } catch(e) {"
184             + "          logEx(e);\n"
185             + "        }\n"
186             + "        log(document.getElementById('label1').htmlFor);\n"
187             + "        log(document.getElementById('label1').control);\n"
188             + "        log(document.getElementById('label1').form);\n"
189             + "      }\n"
190             + "    </script>\n"
191             + "  </head>\n"
192             + "  <body onload='doTest()'>\n"
193             + "    <label id='label1'>Item</label>\n"
194             + "    <form id='form1'>\n"
195             + "      <div id='div1'></div>\n"
196             + "    </form>\n"
197             + "  </body>\n"
198             + "</html>";
199 
200         loadPageVerifyTitle2(html);
201     }
202 
203     /**
204      * @throws Exception if the test fails
205      */
206     @Test
207     @Alerts({"text1", "[object HTMLInputElement]", "[object HTMLFormElement]"})
208     public void htmlForSetToLabelable() throws Exception {
209         final String html = DOCTYPE_HTML
210             + "<html>\n"
211             + "  <head>\n"
212             + "    <script>\n"
213             + LOG_TITLE_FUNCTION
214             + "      function doTest() {\n"
215             + "        try {\n"
216             + "          document.getElementById('label1').htmlFor = 'text1';\n"
217             + "        } catch(e) {"
218             + "          logEx(e);\n"
219             + "        }\n"
220             + "        log(document.getElementById('label1').htmlFor);\n"
221             + "        log(document.getElementById('label1').control);\n"
222             + "        log(document.getElementById('label1').form);\n"
223             + "      }\n"
224             + "    </script>\n"
225             + "  </head>\n"
226             + "  <body onload='doTest()'>\n"
227             + "    <label id='label1'>Item</label>\n"
228             + "    <form id='form1'>\n"
229             + "      <input type='text' id='text1'>\n"
230             + "    </form>\n"
231             + "  </body>\n"
232             + "</html>";
233 
234         loadPageVerifyTitle2(html);
235     }
236 
237     /**
238      * @throws Exception if the test fails
239      */
240     @Test
241     @Alerts("null")
242     public void controlNone() throws Exception {
243         final String html =
244               "  <label id='label1'>Item</label>\n"
245             + "  <input type='text' id='text1'>\n";
246 
247         loadPageVerifyTitle2(generateControlPage(html));
248     }
249 
250     /**
251      * @throws Exception if the test fails
252      */
253     @Test
254     @Alerts("null")
255     public void controlForEmpty() throws Exception {
256         final String html =
257               "  <label id='label1' for=''>Item</label>\n"
258             + "  <input type='text' id='text1'>\n";
259 
260         loadPageVerifyTitle2(generateControlPage(html));
261     }
262 
263     /**
264      * @throws Exception if the test fails
265      */
266     @Test
267     @Alerts("null")
268     public void controlForUnknown() throws Exception {
269         final String html =
270               "  <label id='label1' for='unknown'>Item</label>\n"
271             + "  <input type='text' id='text1'>\n";
272 
273         loadPageVerifyTitle2(generateControlPage(html));
274     }
275 
276     /**
277      * @throws Exception if the test fails
278      */
279     @Test
280     @Alerts("null")
281     public void controlForNotLabelable() throws Exception {
282         final String html =
283               "  <label id='label1' for='div1'>Item</label>\n"
284             + "  <div id='div1'></div>\n";
285 
286         loadPageVerifyTitle2(generateControlPage(html));
287     }
288 
289     /**
290      * @throws Exception if the test fails
291      */
292     @Test
293     @Alerts("[object HTMLButtonElement]:button1")
294     public void controlForButton() throws Exception {
295         final String html =
296               "  <label id='label1' for='button1'>Item</label>\n"
297             + "  <button id='button1'></button>\n";
298 
299         loadPageVerifyTitle2(generateControlPage(html));
300     }
301 
302     /**
303      * @throws Exception if the test fails
304      */
305     @Test
306     @Alerts("[object HTMLInputElement]:text1")
307     public void controlForInput() throws Exception {
308         final String html =
309               "  <label id='label1' for='text1'>Item</label>\n"
310             + "  <input type='text' id='text1'>\n";
311 
312         loadPageVerifyTitle2(generateControlPage(html));
313     }
314 
315     /**
316      * @throws Exception if the test fails
317      */
318     @Test
319     @Alerts("null")
320     public void controlForInputHidden() throws Exception {
321         final String html =
322               "  <label id='label1' for='hidden1'>Item</label>\n"
323             + "  <input type='hidden' id='hidden1'>\n";
324 
325         loadPageVerifyTitle2(generateControlPage(html));
326     }
327 
328     /**
329      * @throws Exception if the test fails
330      */
331     @Test
332     @Alerts("[object HTMLMeterElement]:meter1")
333     public void controlForMeter() throws Exception {
334         final String html =
335               "  <label id='label1' for='meter1'>Item</label>\n"
336             + "  <meter id='meter1'></meter>\n";
337 
338         loadPageVerifyTitle2(generateControlPage(html));
339     }
340 
341     /**
342      * @throws Exception if the test fails
343      */
344     @Test
345     @Alerts("[object HTMLOutputElement]:output1")
346     public void controlForOutput() throws Exception {
347         final String html =
348               "  <label id='label1' for='output1'>Item</label>\n"
349             + "  <output id='output1'></output>\n";
350 
351         loadPageVerifyTitle2(generateControlPage(html));
352     }
353 
354     /**
355      * @throws Exception if the test fails
356      */
357     @Test
358     @Alerts("[object HTMLProgressElement]:progress1")
359     public void controlForProgress() throws Exception {
360         final String html =
361               "  <label id='label1' for='progress1'>Item</label>\n"
362             + "  <progress id='progress1'></progress>\n";
363 
364         loadPageVerifyTitle2(generateControlPage(html));
365     }
366 
367     /**
368      * @throws Exception if the test fails
369      */
370     @Test
371     @Alerts("[object HTMLSelectElement]:select1")
372     public void controlForSelect() throws Exception {
373         final String html =
374               "  <label id='label1' for='select1'>Item</label>\n"
375             + "  <select id='select1'><option>Option</option></select>\n";
376 
377         loadPageVerifyTitle2(generateControlPage(html));
378     }
379 
380     /**
381      * @throws Exception if the test fails
382      */
383     @Test
384     @Alerts("[object HTMLTextAreaElement]:text1")
385     public void controlForTextArea() throws Exception {
386         final String html =
387               "  <label id='label1' for='text1'>Item</label>\n"
388             + "  <textarea id='text1'></textarea>\n";
389 
390         loadPageVerifyTitle2(generateControlPage(html));
391     }
392 
393     /**
394      * @throws Exception if the test fails
395      */
396     @Test
397     @Alerts("null")
398     public void controlNestedNotLabelable() throws Exception {
399         final String html =
400               "  <label id='label1'>Item\n"
401             + "    <div id='div1'></div>\n"
402             + "  </label>\n";
403 
404         loadPageVerifyTitle2(generateControlPage(html));
405     }
406 
407     /**
408      * @throws Exception if the test fails
409      */
410     @Test
411     @Alerts("[object HTMLButtonElement]:button1")
412     public void controlNestedButton() throws Exception {
413         final String html =
414               "  <label id='label1'>Item\n"
415             + "    <button id='button1'></button>\n"
416             + "    <button id='button2'></button>\n"
417             + "  </label>\n";
418 
419         loadPageVerifyTitle2(generateControlPage(html));
420     }
421 
422     /**
423      * @throws Exception if the test fails
424      */
425     @Test
426     @Alerts("[object HTMLInputElement]:text1")
427     public void controlNestedInput() throws Exception {
428         final String html =
429               "  <label id='label1'>Item\n"
430             + "    <input type='text' id='text1'>\n"
431             + "    <input type='text' id='text2'>\n"
432             + "  </label>\n";
433 
434         loadPageVerifyTitle2(generateControlPage(html));
435     }
436 
437     /**
438      * @throws Exception if the test fails
439      */
440     @Test
441     @Alerts("null")
442     public void controlNestedInputHidden() throws Exception {
443         final String html =
444               "  <label id='label1'>Item\n"
445             + "    <input type='hidden' id='hidden1'>\n"
446             + "    <input type='hidden' id='hidden2'>\n"
447             + "  </label>\n";
448 
449         loadPageVerifyTitle2(generateControlPage(html));
450     }
451 
452     /**
453      * @throws Exception if the test fails
454      */
455     @Test
456     @Alerts("[object HTMLMeterElement]:meter1")
457     public void controlNestedMeter() throws Exception {
458         final String html =
459               "  <label id='label1'>Item\n"
460             + "    <meter id='meter1'></meter>\n"
461             + "    <meter id='meter2'></meter>\n"
462             + "  </label>\n";
463 
464         loadPageVerifyTitle2(generateControlPage(html));
465     }
466 
467     /**
468      * @throws Exception if the test fails
469      */
470     @Test
471     @Alerts("[object HTMLOutputElement]:output1")
472     public void controlNestedOutput() throws Exception {
473         final String html =
474               "  <label id='label1'>Item\n"
475             + "    <output id='output1'></output>\n"
476             + "    <output id='output2'></output>\n"
477             + "  </label>\n";
478 
479         loadPageVerifyTitle2(generateControlPage(html));
480     }
481 
482     /**
483      * @throws Exception if the test fails
484      */
485     @Test
486     @Alerts("[object HTMLProgressElement]:progress1")
487     public void controlNestedProgress() throws Exception {
488         final String html =
489               "  <label id='label1'>Item\n"
490             + "    <progress id='progress1'></progress>\n"
491             + "    <progress id='progress2'></progress>\n"
492             + "  </label>\n";
493 
494         loadPageVerifyTitle2(generateControlPage(html));
495     }
496 
497     /**
498      * @throws Exception if the test fails
499      */
500     @Test
501     @Alerts("[object HTMLSelectElement]:select1")
502     public void controlNestedSelect() throws Exception {
503         final String html =
504               "  <label id='label1'>Item\n"
505             + "    <select id='select1'><option>Option</option></select>\n"
506             + "    <select id='select2'><option>Option</option></select>\n"
507             + "  </label>\n";
508 
509         loadPageVerifyTitle2(generateControlPage(html));
510     }
511 
512     /**
513      * @throws Exception if the test fails
514      */
515     @Test
516     @Alerts("[object HTMLTextAreaElement]:text1")
517     public void controlNestedTextArea() throws Exception {
518         final String html =
519               "  <label id='label1'>Item\n"
520             + "    <textarea id='text1'></textarea>\n"
521             + "    <textarea id='text2'></textarea>\n"
522             + "  </label>\n";
523 
524         loadPageVerifyTitle2(generateControlPage(html));
525     }
526 
527     /**
528      * @throws Exception if the test fails
529      */
530     @Test
531     @Alerts("[object HTMLInputElement]:text2")
532     public void controlForVersusNested() throws Exception {
533         final String html =
534               "  <label id='label1' for='text2'>Item\n"
535             + "    <input type='text' id='text1'>\n"
536             + "  </label>\n"
537             + "  <input type='text' id='text2'>\n";
538 
539         loadPageVerifyTitle2(generateControlPage(html));
540     }
541 
542     /**
543      * @throws Exception if the test fails
544      */
545     @Test
546     @Alerts("null")
547     public void controlForUnknownVersusNested() throws Exception {
548         final String html =
549               "  <label id='label1' for='unknown'>Item\n"
550             + "    <input type='text' id='text1'>\n"
551             + "  </label>\n"
552             + "  <input type='text' id='text2'>\n";
553 
554         loadPageVerifyTitle2(generateControlPage(html));
555     }
556 
557     /**
558      * @throws Exception if the test fails
559      */
560     @Test
561     @Alerts("null")
562     public void controlForNotLabelableVersusNested() throws Exception {
563         final String html =
564               "  <label id='label1' for='div1'>Item\n"
565             + "    <input type='text' id='text1'>\n"
566             + "  </label>\n"
567             + "  <div id='div1'></div>\n";
568 
569         loadPageVerifyTitle2(generateControlPage(html));
570     }
571 
572     private static String generateControlPage(final String snippet) {
573         return DOCTYPE_HTML
574             + "<html>\n"
575             + "  <head>\n"
576             + "    <script>\n"
577             + LOG_TITLE_FUNCTION
578             + "      function dump(e) {\n"
579             + "        log(e + (e ? ':' + e.id : ''));\n"
580             + "      }\n"
581             + "    </script>\n"
582             + "  </head>\n"
583             + "  <body onload='dump(document.getElementById(\"label1\").control)'>\n"
584             + snippet
585             + "  </body>\n"
586             + "</html>";
587     }
588 
589     /**
590      * @throws Exception if the test fails
591      */
592     @Test
593     @Alerts("null")
594     public void controlSet() throws Exception {
595         final String html = DOCTYPE_HTML
596             + "<html>\n"
597             + "  <head>\n"
598             + "    <script>\n"
599             + LOG_TITLE_FUNCTION
600             + "      function doTest() {\n"
601             + "        try {\n"
602             + "          document.getElementById('label1').control = document.getElementById('text1');\n"
603             + "        } catch(e) {"
604             + "          logEx(e);\n"
605             + "        }\n"
606             + "        log(document.getElementById('label1').control);\n"
607             + "      }\n"
608             + "    </script>\n"
609             + "  </head>\n"
610             + "  <body onload='doTest()'>\n"
611             + "    <label id='label1'>Item</label>\n"
612             + "    <input type='text' id='text1'>\n"
613             + "  </body>\n"
614             + "</html>";
615 
616         loadPageVerifyTitle2(html);
617     }
618 
619     /**
620      * @throws Exception if the test fails
621      */
622     @Test
623     @Alerts("null")
624     public void formNoForm() throws Exception {
625         final String html
626             = "  <label id='label1'>Item</label>\n"
627             + "  <input type='text' id='text1'>\n";
628 
629         loadPageVerifyTitle2(generateFormPage(html));
630     }
631 
632     /**
633      * @throws Exception if the test fails
634      */
635     @Test
636     @Alerts("null")
637     public void formOutsideForm() throws Exception {
638         final String html
639             = "  <label id='label1'>Item</label>\n"
640             + "  <form id='form1'>\n"
641             + "    <input type='text' id='text1'>\n"
642             + "  </form>\n";
643 
644         loadPageVerifyTitle2(generateFormPage(html));
645     }
646 
647     /**
648      * @throws Exception if the test fails
649      */
650     @Test
651     @Alerts("null")
652     public void formInsideForm() throws Exception {
653         final String html
654             = "  <form id='form1'>\n"
655             + "    <label id='label1'>Item</label>\n"
656             + "    <input type='text' id='text1'>\n"
657             + "  </form>\n";
658 
659         loadPageVerifyTitle2(generateFormPage(html));
660     }
661 
662     /**
663      * @throws Exception if the test fails
664      */
665     @Test
666     @Alerts("null")
667     public void formForLabelableOutsideForm() throws Exception {
668         final String html
669             = "  <label id='label1' for='text1'>Item</label>\n"
670             + "  <input type='text' id='text1'>\n"
671             + "  <form id='form1'>\n"
672             + "    <input type='text' id='text2'>\n"
673             + "  </form>\n";
674 
675         loadPageVerifyTitle2(generateFormPage(html));
676     }
677 
678     /**
679      * @throws Exception if the test fails
680      */
681     @Test
682     @Alerts("null")
683     public void formForNotLabelableInsideForm() throws Exception {
684         final String html
685             = "  <label id='label1' for='div1'>Item</label>\n"
686             + "  <form id='form1'>\n"
687             + "    <div id='div1'></div>\n"
688             + "  </form>\n";
689 
690         loadPageVerifyTitle2(generateFormPage(html));
691     }
692 
693     /**
694      * @throws Exception if the test fails
695      */
696     @Test
697     @Alerts("[object HTMLFormElement]:form1")
698     public void formForLabelableInsideForm() throws Exception {
699         final String html
700             = "  <label id='label1' for='text1'>Item</label>\n"
701             + "  <form id='form1'>\n"
702             + "    <input type='text' id='text1'>\n"
703             + "  </form>\n";
704 
705         loadPageVerifyTitle2(generateFormPage(html));
706     }
707 
708     /**
709      * @throws Exception if the test fails
710      */
711     @Test
712     @Alerts("null")
713     public void formNestedLabelableOutsideForm() throws Exception {
714         final String html
715             = "  <label id='label1'>Item\n"
716             + "    <input type='text' id='text1'>\n"
717             + "  </label>\n"
718             + "  <form id='form1'>\n"
719             + "    <input type='text' id='text2'>\n"
720             + "  </form>\n";
721 
722         loadPageVerifyTitle2(generateFormPage(html));
723     }
724 
725     /**
726      * @throws Exception if the test fails
727      */
728     @Test
729     @Alerts("null")
730     public void formNestedNotLabelableInsideForm() throws Exception {
731         final String html
732             = "  <form id='form1'>\n"
733             + "    <label id='label1'>Item\n"
734             + "      <div id='div1'></div>\n"
735             + "    </label>\n"
736             + "  </form>\n";
737 
738         loadPageVerifyTitle2(generateFormPage(html));
739     }
740 
741     /**
742      * @throws Exception if the test fails
743      */
744     @Test
745     @Alerts("[object HTMLFormElement]:form1")
746     public void formNestedLabelableInsideForm() throws Exception {
747         final String html
748             = "  <form id='form1'>\n"
749             + "    <label id='label1'>Item\n"
750             + "      <input type='text' id='text1'>\n"
751             + "    </label>\n"
752             + "  </form>\n";
753 
754         loadPageVerifyTitle2(generateFormPage(html));
755     }
756 
757     private static String generateFormPage(final String snippet) {
758         return DOCTYPE_HTML
759             + "<html>\n"
760             + "  <head>\n"
761             + "    <script>\n"
762             + LOG_TITLE_FUNCTION
763             + "      function dump(e) {\n"
764             + "        log(e + (e ? ':' + e.id : ''));\n"
765             + "      }\n"
766             + "      function doTest() {\n"
767             + "        dump(document.getElementById('label1').form);\n"
768             + "      }\n"
769             + "    </script>\n"
770             + "  </head>\n"
771             + "  <body onload='doTest()'>\n"
772             + snippet
773             + "  </body>\n"
774             + "</html>";
775     }
776 
777     /**
778      * @throws Exception if the test fails
779      */
780     @Test
781     @Alerts("null")
782     public void formSet() throws Exception {
783         final String html = DOCTYPE_HTML
784             + "<html>\n"
785             + "  <head>\n"
786             + "    <script>\n"
787             + LOG_TITLE_FUNCTION
788             + "      function doTest() {\n"
789             + "        try {\n"
790             + "          document.getElementById('label1').form = document.getElementById('form1');\n"
791             + "        } catch(e) {"
792             + "          logEx(e);\n"
793             + "        }\n"
794             + "        log(document.getElementById('label1').form);\n"
795             + "      }\n"
796             + "    </script>\n"
797             + "  </head>\n"
798             + "  <body onload='doTest()'>\n"
799             + "    <label id='label1'>Item</label>\n"
800             + "    <form id='form1'>\n"
801             + "      <input type='text' id='text1'>\n"
802             + "    </form>\n"
803             + "  </body>\n"
804             + "</html>";
805 
806         loadPageVerifyTitle2(html);
807     }
808 
809     /**
810      * @throws Exception if the test fails
811      */
812     @Test
813     public void clickAfterHtmlForSetByJS() throws Exception {
814         final String html = DOCTYPE_HTML
815             + "<html>\n"
816             + "  <head>\n"
817             + "    <script>\n"
818             + "      function doTest() {\n"
819             + "        document.getElementById('label1').htmlFor = 'checkbox1';\n"
820             + "      }\n"
821             + "    </script>\n"
822             + "  </head>\n"
823             + "  <body onload='doTest()'>\n"
824             + "    <label id='label1'>Item</label>\n"
825             + "    <input type='checkbox' id='checkbox1'>\n"
826             + "  </body>\n"
827             + "</html>";
828 
829         final WebDriver driver = loadPage2(html);
830         final WebElement checkbox = driver.findElement(By.id("checkbox1"));
831         assertFalse(checkbox.isSelected());
832         driver.findElement(By.id("label1")).click();
833         assertTrue(checkbox.isSelected());
834     }
835 
836     /**
837      * @throws Exception if the test fails
838      */
839     @Test
840     public void clickAfterNestedByJS() throws Exception {
841         final String html = DOCTYPE_HTML
842             + "<html>\n"
843             + "  <head>\n"
844             + "    <script>\n"
845             + "      function doTest() {\n"
846             + "        document.getElementById('label1').appendChild(document.getElementById('checkbox1'));\n"
847             + "      }\n"
848             + "    </script>\n"
849             + "  </head>\n"
850             + "  <body onload='doTest()'>\n"
851             + "    <label id='label1'>Item</label>\n"
852             + "    <input type='checkbox' id='checkbox1'>\n"
853             + "  </body>\n"
854             + "</html>";
855 
856         final WebDriver driver = loadPage2(html);
857         final WebElement checkbox = driver.findElement(By.id("checkbox1"));
858         assertFalse(checkbox.isSelected());
859         driver.findElement(By.id("label1")).click();
860         assertTrue(checkbox.isSelected());
861     }
862 
863     /**
864      * @throws Exception if the test fails
865      */
866     @Test
867     public void clickByJSAfterHtmlForSetByJS() throws Exception {
868         final String html = DOCTYPE_HTML
869             + "<html>\n"
870             + "  <head>\n"
871             + "    <script>\n"
872             + "      function doTest() {\n"
873             + "        document.getElementById('label1').htmlFor = 'checkbox1';\n"
874             + "      }\n"
875             + "      function delegateClick() {\n"
876             + "        try {\n"
877             + "          document.getElementById('label1').click();\n"
878             + "        } catch(e) {}\n"
879             + "      }\n"
880             + "    </script>\n"
881             + "  </head>\n"
882             + "  <body onload='doTest()'>\n"
883             + "    <label id='label1'>My Label</label>\n"
884             + "    <input type='checkbox' id='checkbox1'><br>\n"
885             + "    <input type=button id='button1' value='Test' onclick='delegateClick()'>\n"
886             + "  </body>\n"
887             + "</html>";
888 
889         final WebDriver driver = loadPage2(html);
890         final WebElement checkbox = driver.findElement(By.id("checkbox1"));
891         assertFalse(checkbox.isSelected());
892         driver.findElement(By.id("button1")).click();
893         assertTrue(checkbox.isSelected());
894     }
895 
896     /**
897      * @throws Exception if the test fails
898      */
899     @Test
900     public void clickByJSAfterNestedByJS() throws Exception {
901         final String html = DOCTYPE_HTML
902             + "<html>\n"
903             + "  <head>\n"
904             + "    <script>\n"
905             + "      function doTest() {\n"
906             + "        document.getElementById('label1').appendChild(document.getElementById('checkbox1'));\n"
907             + "      }\n"
908             + "      function delegateClick() {\n"
909             + "        try {\n"
910             + "          document.getElementById('label1').click();\n"
911             + "        } catch(e) {}\n"
912             + "      }\n"
913             + "    </script>\n"
914             + "  </head>\n"
915             + "  <body onload='doTest()'>\n"
916             + "    <label id='label1'>My Label</label>\n"
917             + "    <input type='checkbox' id='checkbox1'><br>\n"
918             + "    <input type=button id='button1' value='Test' onclick='delegateClick()'>\n"
919             + "  </body>\n"
920             + "</html>";
921 
922         final WebDriver driver = loadPage2(html);
923         final WebElement checkbox = driver.findElement(By.id("checkbox1"));
924         assertFalse(checkbox.isSelected());
925         driver.findElement(By.id("button1")).click();
926         assertTrue(checkbox.isSelected());
927     }
928 
929     /**
930      * @throws Exception if an error occurs
931      */
932     @Test
933     @Alerts({ "", "A", "a", "A", "a8", "8Afoo", "8", "@" })
934     public void accessKey() throws Exception {
935         final String html = DOCTYPE_HTML
936             + "<html>\n"
937             + "  <body>\n"
938             + "    <label id='a1'>a1</label>\n"
939             + "    <label id='a2' accesskey='A'>a2</label>\n"
940             + "    <script>\n"
941             + LOG_TITLE_FUNCTION
942             + "      var a1 = document.getElementById('a1'), a2 = document.getElementById('a2');\n"
943             + "      log(a1.accessKey);\n"
944             + "      log(a2.accessKey);\n"
945             + "      a1.accessKey = 'a';\n"
946             + "      a2.accessKey = 'A';\n"
947             + "      log(a1.accessKey);\n"
948             + "      log(a2.accessKey);\n"
949             + "      a1.accessKey = 'a8';\n"
950             + "      a2.accessKey = '8Afoo';\n"
951             + "      log(a1.accessKey);\n"
952             + "      log(a2.accessKey);\n"
953             + "      a1.accessKey = '8';\n"
954             + "      a2.accessKey = '@';\n"
955             + "      log(a1.accessKey);\n"
956             + "      log(a2.accessKey);\n"
957             + "    </script>\n"
958             + "  </body>\n"
959             + "</html>";
960 
961         loadPageVerifyTitle2(html);
962     }
963 }