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 java.util.ArrayList;
18  import java.util.List;
19  
20  import org.htmlunit.CollectingAlertHandler;
21  import org.htmlunit.MockWebConnection;
22  import org.htmlunit.SimpleWebTestCase;
23  import org.htmlunit.WebClient;
24  import org.htmlunit.junit.BrowserRunner;
25  import org.htmlunit.junit.annotation.Alerts;
26  import org.htmlunit.junit.annotation.BuggyWebDriver;
27  import org.junit.Test;
28  import org.junit.runner.RunWith;
29  
30  /**
31   * Tests for various clickable elements.
32   *
33   * @author David K. Taylor
34   * @author Chris Erskine
35   * @author Marc Guillemot
36   * @author Ahmed Ashour
37   * @author Frank Danek
38   */
39  @RunWith(BrowserRunner.class)
40  public class ClickableElementTest extends SimpleWebTestCase {
41  
42      /**
43       * Full page driver for onClick tests.
44       *
45       * @param htmlContent HTML fragment for body of page with clickable element
46       *        identified by clickId ID attribute. Must have onClick that raises
47       *        an alert of "foo".
48       * @throws Exception if the test fails
49       */
50      private void onClickPageTest(final String htmlContent) throws Exception {
51          setExpectedAlerts("foo");
52          onClickPageTest(htmlContent, 1);
53      }
54  
55      /**
56       * Full page driver for onClick tests.
57       *
58       * @param htmlContent HTML fragment for body of page with clickable element
59       *        identified by clickId ID attribute.
60       * @param numClicks number of times to click element
61       * @param expectedAlerts array of expected popup values
62       * @throws Exception if the test fails
63       */
64      private void onClickPageTest(final String htmlContent, final int numClicks) throws Exception {
65          onClickPageTest(htmlContent, numClicks, false);
66      }
67  
68      /**
69       * Full page driver for onClick tests.
70       *
71       * @param htmlContent HTML fragment for body of page with clickable element identified by clickId ID attribute
72       * @param numClicks number of times to click element
73       * @param expectedAlerts array of expected popup values
74       * @param exceptionOnError indicate to throw on error
75       * @throws Exception if the test fails
76       */
77      private void onClickPageTest(final String htmlContent, final int numClicks,
78              final boolean exceptionOnError) throws Exception {
79  
80          final WebClient client = getWebClientWithMockWebConnection();
81  
82          final MockWebConnection webConnection = getMockWebConnection();
83          webConnection.setDefaultResponse(htmlContent);
84          client.getOptions().setThrowExceptionOnScriptError(exceptionOnError);
85  
86          final List<String> collectedAlerts = new ArrayList<>();
87          final CollectingAlertHandler alertHandler = new CollectingAlertHandler(collectedAlerts);
88          client.setAlertHandler(alertHandler);
89  
90          final HtmlPage page = client.getPage(URL_FIRST);
91          final HtmlElement clickable = page.getHtmlElementById("clickId");
92  
93          for (int i = 0; i < numClicks; i++) {
94              clickable.click();
95          }
96  
97          assertEquals(getExpectedAlerts(), collectedAlerts);
98      }
99  
100     /**
101      * Body driver for onClick tests.
102      *
103      * @param htmlBody HTML text body
104      * @throws Exception if the test fails
105      */
106     private void onClickBodyTest(final String htmlBody) throws Exception {
107         onClickPageTest(DOCTYPE_HTML + "<html><head><title>foo</title></head>\n" + htmlBody
108                  + "</html>");
109     }
110 
111     /**
112      * Simple tag name driver for onClick tests.
113      *
114      * @param tagName HTML tag name for simple tag with text body
115      * @throws Exception if the test fails
116      */
117     private void onClickSimpleTest(final String tagName) throws Exception {
118         onClickBodyTest("<body><" + tagName + " id='clickId' onClick='alert(\"foo\")'>Text</" + tagName + "></body>\n");
119     }
120 
121     /**
122      * Test onClick handler and click method of anchor element.
123      *
124      * @throws Exception if the test fails
125      */
126     @Test
127     public void anchor_onClick() throws Exception {
128         onClickSimpleTest("a");
129     }
130 
131     /**
132      * Test onClick handler and click method of abbreviation element.
133      *
134      * @throws Exception if the test fails
135      */
136     @Test
137     public void abbreviation_onClick() throws Exception {
138         onClickSimpleTest("abbr");
139     }
140 
141     /**
142      * Test onClick handler and click method of acronym element.
143      *
144      * @throws Exception if the test fails
145      */
146     @Test
147     public void acronym_onClick() throws Exception {
148         onClickSimpleTest("acronym");
149     }
150 
151     /**
152      * Test onClick handler and click method of address element.
153      *
154      * @throws Exception if the test fails
155      */
156     @Test
157     public void address_onClick() throws Exception {
158         onClickSimpleTest("address");
159     }
160 
161     /**
162      * Test onClick handler and click method of bold element.
163      *
164      * @throws Exception if the test fails
165      */
166     @Test
167     public void bold_onClick() throws Exception {
168         onClickSimpleTest("b");
169     }
170 
171     /**
172      * Test onClick handler and click method of big element.
173      *
174      * @throws Exception if the test fails
175      */
176     @Test
177     public void big_onClick() throws Exception {
178         onClickSimpleTest("big");
179     }
180 
181     /**
182      * Test onClick handler and click method of blockquote element.
183      *
184      * @throws Exception if the test fails
185      */
186     @Test
187     public void blockquote_onClick() throws Exception {
188         onClickSimpleTest("blockquote");
189     }
190 
191     /**
192      * Test onClick handler and click method of body element.
193      *
194      * @throws Exception if the test fails
195      */
196     @Test
197     public void body_onClick() throws Exception {
198         onClickBodyTest("<body id='clickId' onClick='alert(\"foo\")'>Text</body>\n");
199     }
200 
201     /**
202      * Test onClick handler and click method of button element.
203      *
204      * @throws Exception if the test fails
205      */
206     @Test
207     public void button_onClick() throws Exception {
208         onClickBodyTest("<body><form><button id='clickId' onClick='alert(\"foo\")'>Item</button></form></body>\n");
209     }
210 
211     /**
212      * Test onClick handler can be called multiple times.
213      *
214      * @throws Exception if the test fails
215      */
216     @Test
217     @Alerts({"foo0", "foo1"})
218     public void button_onClickTwice() throws Exception {
219         onClickPageTest("<body><form>\n"
220                 + "<button id='clickId' onClick='alert(\"foo\" + count++); return false;'>Item</button>\n"
221                 + "<script> var count = 0 </script>\n"
222                 + "</form></body>\n", 2);
223     }
224 
225     /**
226      * Test onClick handler and click method of cite element.
227      *
228      * @throws Exception if the test fails
229      */
230     @Test
231     public void cite_onClick() throws Exception {
232         onClickSimpleTest("cite");
233     }
234 
235     /**
236      * Test onClick handler and click method of code element.
237      *
238      * @throws Exception if the test fails
239      */
240     @Test
241     public void code_onClick() throws Exception {
242         onClickSimpleTest("code");
243     }
244 
245     /**
246      * Test onClick handler and click method of table column element.
247      *
248      * @throws Exception if the test fails
249      */
250     @Test
251     public void tableColumn_onClick() throws Exception {
252         onClickBodyTest("<body><table><caption>Caption</caption><colgroup>\n"
253             + "<col id='clickId' onClick='alert(\"foo\")'/></colgroup><thead><tr><th>\n"
254             + "Header</th></tr></thead><tbody><tr><td>Data</td></tr></tbody><tfoot><tr>\n"
255             + "th>Header</th></tr></tfoot></table></body>\n");
256     }
257 
258     /**
259      * Test onClick handler and click method of table column group element.
260      *
261      * @throws Exception if the test fails
262      */
263     @Test
264     public void tableColumnGroup_onClick() throws Exception {
265         onClickBodyTest("<body><table><caption>Caption</caption>\n"
266             + "<colgroup id='clickId' onClick='alert(\"foo\")'><col/></colgroup><thead>\n"
267             + "<tr><th>Header</th></tr></thead><tbody><tr><td>Data</td></tr></tbody><tfoot>\n"
268             + "<tr><th>Header</th></tr></tfoot></table></body>\n");
269     }
270 
271     /**
272      * Test onClick handler and click method of center element.
273      *
274      * @throws Exception if the test fails
275      */
276     @Test
277     public void center_onClick() throws Exception {
278         onClickSimpleTest("center");
279     }
280 
281     /**
282      * Test onClick handler and click method of table caption element.
283      *
284      * @throws Exception if the test fails
285      */
286     @Test
287     public void tableCaption_onClick() throws Exception {
288         onClickBodyTest("<body><table><caption id='clickId' onClick='alert(\"foo\")'>\n"
289             + "Caption</caption><colgroup><col/></colgroup><thead><tr><th>Header</th></tr>\n"
290             + "</thead><tbody><tr><td>Data</td></tr></tbody><tfoot><tr><th>Header</th></tr>\n"
291             + "</tfoot></table></body>\n");
292     }
293 
294     /**
295      * Test onClick handler and click method of definition description dd element.
296      *
297      * @throws Exception if the test fails
298      */
299     @Test
300     public void definitionDescription_onClick() throws Exception {
301         onClickBodyTest("<body><dl><dt>Term</dt><dd id='clickId' onClick='alert(\"foo\")'>Definition</dd></dl></body>");
302     }
303 
304     /**
305      * Test that no NPE is thrown when JS fails on link click
306      * and WebClient.setThrowExceptionOnScriptError(false) is used.
307      * Test for bug #329.
308      * @throws Exception if the test fails
309      */
310     @Test
311     public void javaScriptError_onClick() throws Exception {
312         onClickPageTest(DOCTYPE_HTML
313                 + "<html><head></head><body>\n"
314                 + "<form method='POST'><input type='button' id='clickId' onclick='y()'></form>\n"
315                 + "</body></html>",
316                 1, false);
317     }
318 
319     /**
320      * Test onClick handler and click method of definition element.
321      *
322      * @throws Exception if the test fails
323      */
324     @Test
325     public void definition_onClick() throws Exception {
326         onClickSimpleTest("dfn");
327     }
328 
329     /**
330      * Test onClick handler and click method of directory element.
331      *
332      * @throws Exception if the test fails
333      */
334     @Test
335     public void directory_onClick() throws Exception {
336         onClickSimpleTest("dir");
337     }
338 
339     /**
340      * Test onClick handler and click method of definition list dl element.
341      *
342      * @throws Exception if the test fails
343      */
344     @Test
345     public void definitionList_onClick() throws Exception {
346         onClickBodyTest("<body><dl id='clickId' onClick='alert(\"foo\")'><dt>Term</dt><dd>Definition</dd></dl></body>");
347     }
348 
349     /**
350      * Test onClick handler and click method of definition term dt element.
351      *
352      * @throws Exception if the test fails
353      */
354     @Test
355     public void definitionTerm_onClick() throws Exception {
356         onClickBodyTest("<body><dl><dt id='clickId' onClick='alert(\"foo\")'>Term</dt><dd>Definition</dd></dl></body>");
357     }
358 
359     /**
360      * Test onClick handler and click method of deleted text element.
361      *
362      * @throws Exception if the test fails
363      */
364     @Test
365     public void deletedText_onClick() throws Exception {
366         onClickSimpleTest("del");
367     }
368 
369     /**
370      * Test onClick handler and click method of division element.
371      *
372      * @throws Exception if the test fails
373      */
374     @Test
375     public void division_onClick() throws Exception {
376         onClickSimpleTest("div");
377     }
378 
379     /**
380      * Test onClick handler and click method of emphasis element.
381      *
382      * @throws Exception if the test fails
383      */
384     @Test
385     public void emphasis_onClick() throws Exception {
386         onClickSimpleTest("em");
387     }
388 
389     /**
390      * Test onClick handler and click method of field set element.
391      *
392      * @throws Exception if the test fails
393      */
394     @Test
395     public void fieldSet_onClick() throws Exception {
396         onClickBodyTest("<body><form><fieldset id='clickId' onClick='alert(\"foo\")'>\n"
397             + "<legend>Legend</legend></fieldset></form></body>\n");
398     }
399 
400     /**
401      * Test onClick handler and click method of form element.
402      *
403      * @throws Exception if the test fails
404      */
405     @Test
406     public void form_onClick() throws Exception {
407         onClickSimpleTest("form");
408     }
409 
410     /**
411      * Test onClick handler and click method of italics element.
412      *
413      * @throws Exception if the test fails
414      */
415     @Test
416     public void italics_onClick() throws Exception {
417         onClickSimpleTest("i");
418     }
419 
420     /**
421      * Test onClick handler and click method of header1 element.
422      *
423      * @throws Exception if the test fails
424      */
425     @Test
426     public void header1_onClick() throws Exception {
427         onClickSimpleTest("h1");
428     }
429 
430     /**
431      * Test onClick handler and click method of header2 element.
432      *
433      * @throws Exception if the test fails
434      */
435     @Test
436     public void header2_onClick() throws Exception {
437         onClickSimpleTest("h2");
438     }
439 
440     /**
441      * Test onClick handler and click method of header3 element.
442      *
443      * @throws Exception if the test fails
444      */
445     @Test
446     public void header3_onClick() throws Exception {
447         onClickSimpleTest("h3");
448     }
449 
450     /**
451      * Test onClick handler and click method of header4 element.
452      *
453      * @throws Exception if the test fails
454      */
455     @Test
456     public void header4_onClick() throws Exception {
457         onClickSimpleTest("h4");
458     }
459 
460     /**
461      * Test onClick handler and click method of header5 element.
462      *
463      * @throws Exception if the test fails
464      */
465     @Test
466     public void header5_onClick() throws Exception {
467         onClickSimpleTest("h5");
468     }
469 
470     /**
471      * Test onClick handler and click method of header6 element.
472      *
473      * @throws Exception if the test fails
474      */
475     @Test
476     public void header6_onClick() throws Exception {
477         onClickSimpleTest("h6");
478     }
479 
480     /**
481      * Test onClick handler and click method of horizontal rule element.
482      *
483      * @throws Exception if the test fails
484      */
485     @Test
486     public void horizontalRule_onClick() throws Exception {
487         onClickSimpleTest("hr");
488     }
489 
490     /**
491      * Test onClick handler and click method of input element.
492      *
493      * @throws Exception if the test fails
494      */
495     @Test
496     public void input_onClick() throws Exception {
497         onClickBodyTest("<body><form><input id='clickId' onClick='alert(\"foo\")'>Item</input></form></body>\n");
498     }
499 
500     /**
501      * Test onClick handler and click method of inserted text element.
502      *
503      * @throws Exception if the test fails
504      */
505     @Test
506     public void insertedText_onClick() throws Exception {
507         onClickSimpleTest("ins");
508     }
509 
510     /**
511      * Test onClick handler and click method of keyboard element.
512      *
513      * @throws Exception if the test fails
514      */
515     @Test
516     public void keyboard_onClick() throws Exception {
517         onClickSimpleTest("kbd");
518     }
519 
520     /**
521      * Test onClick handler and click method of label element.
522      *
523      * @throws Exception if the test fails
524      */
525     @Test
526     public void label_onClick() throws Exception {
527         onClickBodyTest("<body><form><label id='clickId' onClick='alert(\"foo\")'>Item</label></form></body>\n");
528     }
529 
530     /**
531      * Test onClick handler and click method of legend element.
532      *
533      * @throws Exception if the test fails
534      */
535     @Test
536     public void legend_onClick() throws Exception {
537         onClickBodyTest("<body><form><fieldset><legend id='clickId' onClick='alert(\"foo\")'>\n"
538             + "Legend</legend></fieldset></form></body>\n");
539     }
540 
541     /**
542      * Test onClick handler and click method of List Item element.
543      *
544      * @throws Exception if the test fails
545      */
546     @Test
547     public void listItem_onClick() throws Exception {
548         onClickBodyTest("<body><ol><li id='clickId' onClick='alert(\"foo\")'>Item</li></ol></body>\n");
549     }
550 
551     /**
552      * Test onClick handler and click method of menu element.
553      *
554      * @throws Exception if the test fails
555      */
556     @Test
557     public void menu_onClick() throws Exception {
558         onClickBodyTest("<body><menu id='clickId' onClick='alert(\"foo\")'><li>Item</li></menu></body>\n");
559     }
560 
561     /**
562      * Test onClick handler and click method of object element.
563      *
564      * @throws Exception if the test fails
565      */
566     @Test
567     public void object_onClick() throws Exception {
568         onClickSimpleTest("object");
569     }
570 
571     /**
572      * Test onClick handler and click method of option element.
573      *
574      * @throws Exception if the test fails
575      */
576     @Test
577     @Alerts("foo")
578     @BuggyWebDriver(CHROME = "")
579     // ChromeDriver does not generate a "foo" but it occurs manually
580     public void option_onClick() throws Exception {
581         final String htmlContent = DOCTYPE_HTML
582                 + "<html><head><title>foo</title></head>\n"
583                 + "<body><form><select size='2'><option id='clickId' onClick='alert(\"foo\")'>\n"
584                 + "Option</option></select></form></body>\n"
585                 + "</html>";
586 
587         onClickPageTest(htmlContent, 1);
588     }
589 
590     /**
591      * Test onClick handler and click method of Option Group element.
592      *
593      * @throws Exception if the test fails
594      */
595     @Test
596     public void optionGroup_onClick() throws Exception {
597         onClickBodyTest("<body><form><select><optgroup id='clickId' onClick='alert(\"foo\")'>\n"
598             + "<option>Option</option></optgroup></select></form></body>\n");
599     }
600 
601     /**
602      * Test onClick handler and click method of Ordered List element.
603      *
604      * @throws Exception if the test fails
605      */
606     @Test
607     public void orderedList_onClick() throws Exception {
608         onClickBodyTest("<body><ol id='clickId' onClick='alert(\"foo\")'><li>Item</li></ol></body>\n");
609     }
610 
611     /**
612      * Test onClick handler and click method of paragraph element.
613      *
614      * @throws Exception if the test fails
615      */
616     @Test
617     public void paragraph_onClick() throws Exception {
618         onClickSimpleTest("p");
619     }
620 
621     /**
622      * Test onClick handler and click method of pre element.
623      *
624      * @throws Exception if the test fails
625      */
626     @Test
627     public void pre_onClick() throws Exception {
628         onClickSimpleTest("pre");
629     }
630 
631     /**
632      * Test onClick handler and click method of inline Quotation element.
633      *
634      * @throws Exception if the test fails
635      */
636     @Test
637     public void quotation_onClick() throws Exception {
638         onClickSimpleTest("q");
639     }
640 
641     /**
642      * Test onClick handler and click method of strikethrough element.
643      *
644      * @throws Exception if the test fails
645      */
646     @Test
647     public void strikethrough_onClick() throws Exception {
648         onClickSimpleTest("s");
649     }
650 
651     /**
652      * Test onClick handler and click method of sample element.
653      *
654      * @throws Exception if the test fails
655      */
656     @Test
657     public void sample_onClick() throws Exception {
658         onClickSimpleTest("samp");
659     }
660 
661     /**
662      * Test onClick handler and click method of select element.
663      *
664      * @throws Exception if the test fails
665      */
666     @Test
667     public void select_onClick() throws Exception {
668         onClickBodyTest("<body><form><select id='clickId' onClick='alert(\"foo\")'>\n"
669             + "<option>Option</option></select></form></body>\n");
670     }
671 
672     /**
673      * Test onClick handler and click method of small element.
674      *
675      * @throws Exception if the test fails
676      */
677     @Test
678     public void small_onClick() throws Exception {
679         onClickSimpleTest("small");
680     }
681 
682     /**
683      * Test onClick handler and click method of span element.
684      *
685      * @throws Exception if the test fails
686      */
687     @Test
688     public void span_onClick() throws Exception {
689         onClickSimpleTest("span");
690     }
691 
692     /**
693      * Test onClick handler and click method of strike element.
694      *
695      * @throws Exception if the test fails
696      */
697     @Test
698     public void strike_onClick() throws Exception {
699         onClickSimpleTest("strike");
700     }
701 
702     /**
703      * Test onClick handler and click method of subscript element.
704      *
705      * @throws Exception if the test fails
706      */
707     @Test
708     public void subscript_onClick() throws Exception {
709         onClickSimpleTest("sub");
710     }
711 
712     /**
713      * Test onClick handler and click method of superscript element.
714      *
715      * @throws Exception if the test fails
716      */
717     @Test
718     public void superscript_onClick() throws Exception {
719         onClickSimpleTest("sup");
720     }
721 
722     /**
723      * Test onClick handler and click method of table element.
724      *
725      * @throws Exception if the test fails
726      */
727     @Test
728     public void table_onClick() throws Exception {
729         onClickBodyTest("<body><table id='clickId' onClick='alert(\"foo\")'><caption>\n"
730             + "Caption</caption><colgroup><col/></colgroup><thead><tr><th>Header</th></tr>\n"
731             + "</thead><tbody><tr><td>Data</td></tr></tbody><tfoot><tr><th>Header</th></tr>\n"
732             + "</tfoot></table></body>\n");
733     }
734 
735     /**
736      * Test onClick handler and click method of table body element.
737      *
738      * @throws Exception if the test fails
739      */
740     @Test
741     public void tableBody_onClick() throws Exception {
742         onClickBodyTest("<body><table><caption>Caption</caption><colgroup><col/>\n"
743             + "</colgroup><thead><tr><th>Header</th></tr></thead>\n"
744             + "<tbody id='clickId' onClick='alert(\"foo\")'><tr><td>Data</td></tr>\n"
745             + "</tbody><tfoot><tr><th>Header</th></tr></tfoot></table></body>\n");
746     }
747 
748     /**
749      * Test onClick handler and click method of table data cell element.
750      *
751      * @throws Exception if the test fails
752      */
753     @Test
754     public void tableDataCell_onClick() throws Exception {
755         onClickBodyTest("<body><table><caption>Caption</caption><colgroup><col/>\n"
756             + "</colgroup><thead><tr><th>Header</th></tr></thead><tbody><tr>\n"
757             + "<td id='clickId' onClick='alert(\"foo\")'>Data</td></tr></tbody>\n"
758             + "<tfoot><tr><th>Header</th></tr></tfoot></table></body>\n");
759     }
760 
761     /**
762      * Test onClick handler and click method of textarea element.
763      *
764      * @throws Exception if the test fails
765      */
766     @Test
767     public void textarea_onClick() throws Exception {
768         onClickBodyTest("<body><form><textarea id='clickId' onClick='alert(\"foo\")'>Item</textarea></form></body>\n");
769     }
770 
771     /**
772      * Test onClick handler and click method of table footer element.
773      *
774      * @throws Exception if the test fails
775      */
776     @Test
777     public void tableFooter_onClick() throws Exception {
778         onClickBodyTest("<body><table><caption>Caption</caption><colgroup><col/>\n"
779             + "</colgroup><thead><tr><th>Header</th></tr></thead><tbody><tr><td>Data</td>\n"
780             + "</tr></tbody><tfoot id='clickId' onClick='alert(\"foo\")'><tr><th>Header</th>\n"
781             + "</tr></tfoot></table></body>\n");
782     }
783 
784     /**
785      * Test onClick handler and click method of table header cell element.
786      *
787      * @throws Exception if the test fails
788      */
789     @Test
790     public void tableHeaderCell_onClick() throws Exception {
791         onClickBodyTest("<body><table><caption>Caption</caption><colgroup>\n"
792             + "<col/></colgroup><thead><tr><th id='clickId' onClick='alert(\"foo\")'>\n"
793             + "Header</th></tr></thead><tbody><tr><td>Data</td></tr></tbody><tfoot><tr>\n"
794             + "<th>Header</th></tr></tfoot></table></body>\n");
795     }
796 
797     /**
798      * Test onClick handler and click method of table header element.
799      *
800      * @throws Exception if the test fails
801      */
802     @Test
803     public void tableHeader_onClick() throws Exception {
804         onClickBodyTest("<body><table><caption>Caption</caption><colgroup><col/>\n"
805             + "</colgroup><thead id='clickId' onClick='alert(\"foo\")'><tr><th>Header</th>\n"
806             + "</tr></thead><tbody><tr><td>Data</td></tr></tbody><tfoot><tr><th>Header</th>\n"
807             + "</tr></tfoot></table></body>\n");
808     }
809 
810     /**
811      * Test onClick handler and click method of table row element.
812      *
813      * @throws Exception if the test fails
814      */
815     @Test
816     public void tableRow_onClick() throws Exception {
817         onClickBodyTest("<body><table><caption>Caption</caption><colgroup><col/>\n"
818             + "</colgroup><thead><tr><th>Header</th></tr></thead><tbody>\n"
819             + "<tr id='clickId' onClick='alert(\"foo\")'><td>Data</td></tr></tbody>\n"
820             + "<tfoot><tr><th>Header</th></tr></tfoot></table></body>\n");
821     }
822 
823     /**
824      * Test when HtmlTableRow.onclick is set by JavaScript.
825      *
826      * @throws Exception if the test fails
827      */
828     @Test
829     public void tableRow_onClickSetOnLoad() throws Exception {
830         onClickPageTest(DOCTYPE_HTML
831                         + "<html><head>\n"
832                         + "<script language='JavaScript'>\n"
833                         + "function doFoo() { alert('foo');        }\n"
834                         + "function doOnload() { document.getElementById('clickId').onclick = doFoo;}\n"
835                         + "</script>\n"
836                         + "</head><body onload=\"doOnload();\">\n"
837                         + "<table><tbody><tr id='clickId'><td>cell value</td></tr></tbody></table>\n"
838                         + "</body></html>");
839     }
840 
841     /**
842      * @throws Exception if the test fails
843      */
844     @Test
845     public void checkbox_onClickUpdatesStateFirst() throws Exception {
846         onClickPageTest(DOCTYPE_HTML
847                         + "<html><head>\n"
848                         + "<script language='JavaScript'>\n"
849                         + "function doFoo(event) { if (this.checked) alert('foo'); else alert('bar'); }\n"
850                         + "function doOnload() { document.getElementById('clickId').onclick = doFoo;}\n"
851                         + "</script>\n"
852                         + "</head><body onload=\"doOnload();\">\n"
853                         + "<input type='checkbox' id='clickId'>\n"
854                         + "</body></html>");
855     }
856 
857     /**
858      * Test when HtmlTableRow.onclick is set by a JavaScript.
859      *
860      * @throws Exception if the test fails
861      */
862     @Test
863     public void tableRow_onClickSetByNestedScript() throws Exception {
864         onClickBodyTest("<body><table><tbody><tr id='clickId'><td>cell value</td></tr></tbody></table>\n"
865                         + "<script language='JavaScript'>\n"
866                                 + "function doFoo(event) { alert('foo'); }\n"
867                                 + "document.getElementById('clickId').onclick = doFoo;</script></body>\n");
868     }
869 
870     /**
871      * Test onClick handler and click method of teletype element.
872      *
873      * @throws Exception if the test fails
874      */
875     @Test
876     public void teletype_onClick() throws Exception {
877         onClickSimpleTest("tt");
878     }
879 
880     /**
881      * Test onClick handler and click method of underline element.
882      *
883      * @throws Exception if the test fails
884      */
885     @Test
886     public void underline_onClick() throws Exception {
887         onClickSimpleTest("u");
888     }
889 
890     /**
891      * Test onClick handler and click method of unordered List element.
892      *
893      * @throws Exception if the test fails
894      */
895     @Test
896     public void unorderedList_onClick() throws Exception {
897         onClickBodyTest("<body><ul id='clickId' onClick='alert(\"foo\")'><li>Item</li></ul></body>\n");
898     }
899 
900     /**
901      * Test onClick handler and click method of variable element.
902      *
903      * @throws Exception if the test fails
904      */
905     @Test
906     public void variable_onClick() throws Exception {
907         onClickSimpleTest("var");
908     }
909 
910     /**
911      * Test setting onClick handler from inside the onClick handler.
912      *
913      * @throws Exception if the test fails
914      */
915     @Test
916     @Alerts("foo")
917     public void setOnClick() throws Exception {
918         onClickPageTest(DOCTYPE_HTML
919                 + "<html><body><form>\n"
920                 + "<button type='button' id='clickId' onclick='alert(\"foo\"); onclick=null;'>Item</button>\n"
921                 + "</form></body></html>", 2);
922     }
923 }