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.BrowserRunner;
19  import org.htmlunit.junit.annotation.Alerts;
20  import org.junit.Test;
21  import org.junit.runner.RunWith;
22  
23  /**
24   * Tests for {@link HTMLTableSectionElement}.
25   *
26   * @author Daniel Gredler
27   * @author Frank Danek
28   * @author Ronald Brill
29   */
30  @RunWith(BrowserRunner.class)
31  public class HTMLTableSectionElementTest extends WebDriverTestCase {
32  
33      /**
34       * @throws Exception if an error occurs
35       */
36      @Test
37      @Alerts({"", "hello", "left", "hi", "right"})
38      public void align_thead() throws Exception {
39          align("th");
40      }
41  
42      /**
43       * @throws Exception if an error occurs
44       */
45      @Test
46      @Alerts({"", "hello", "left", "hi", "right"})
47      public void align_tbody() throws Exception {
48          align("tb");
49      }
50  
51      /**
52       * @throws Exception if an error occurs
53       */
54      @Test
55      @Alerts({"", "hello", "left", "hi", "right"})
56      public void align_tfoot() throws Exception {
57          align("tf");
58      }
59  
60      private void align(final String id) throws Exception {
61          final String html = DOCTYPE_HTML
62              + "<html>\n"
63              + "  <head>\n"
64              + "    <script>\n"
65              + LOG_TITLE_FUNCTION
66              + "      function test() {\n"
67              + "        var t = document.getElementById('" + id + "');\n"
68              + "        log(t.align);\n"
69              + "        set(t, 'hello');\n"
70              + "        log(t.align);\n"
71              + "        set(t, 'left');\n"
72              + "        log(t.align);\n"
73              + "        set(t, 'hi');\n"
74              + "        log(t.align);\n"
75              + "        set(t, 'right');\n"
76              + "        log(t.align);\n"
77              + "      }\n"
78              + "      function set(e, value) {\n"
79              + "        try {\n"
80              + "          e.align = value;\n"
81              + "        } catch(e) { logEx(e); }\n"
82              + "      }\n"
83              + "    </script>\n"
84              + "  </head>\n"
85              + "  <body onload='test()'>\n"
86              + "    <table id='t'>\n"
87              + "      <thead id='th'/>\n"
88              + "      <tbody id='tb'/>\n"
89              + "      <tfoot id='tf'/>\n"
90              + "    </table>\n"
91              + "  </body>\n"
92              + "</html>";
93  
94          loadPageVerifyTitle2(html);
95      }
96  
97      /**
98       * @throws Exception if an error occurs
99       */
100     @Test
101     @Alerts({"top", "baseline", "3", "middle", "8", "BOTtom"})
102     public void vAlign_thead() throws Exception {
103         vAlign("th");
104     }
105 
106     /**
107      * @throws Exception if an error occurs
108      */
109     @Test
110     @Alerts({"top", "baseline", "3", "middle", "8", "BOTtom"})
111     public void vAlign_tbody() throws Exception {
112         vAlign("tb");
113     }
114 
115     /**
116      * @throws Exception if an error occurs
117      */
118     @Test
119     @Alerts({"top", "baseline", "3", "middle", "8", "BOTtom"})
120     public void vAlign_tfoot() throws Exception {
121         vAlign("tf");
122     }
123 
124     private void vAlign(final String id) throws Exception {
125         final String html = DOCTYPE_HTML
126             + "<html>\n"
127             + "  <head>\n"
128             + "    <script>\n"
129             + LOG_TITLE_FUNCTION
130             + "      function test() {\n"
131             + "        var t1 = document.getElementById('" + id + "1');\n"
132             + "        var t2 = document.getElementById('" + id + "2');\n"
133             + "        var t3 = document.getElementById('" + id + "3');\n"
134             + "        log(t1.vAlign);\n"
135             + "        log(t2.vAlign);\n"
136             + "        log(t3.vAlign);\n"
137             + "        set(t1, 'middle');\n"
138             + "        set(t2, 8);\n"
139             + "        set(t3, 'BOTtom');\n"
140             + "        log(t1.vAlign);\n"
141             + "        log(t2.vAlign);\n"
142             + "        log(t3.vAlign);\n"
143             + "      }\n"
144             + "      function set(e, value) {\n"
145             + "        try {\n"
146             + "          e.vAlign = value;\n"
147             + "        } catch(e) { logEx(e); }\n"
148             + "      }\n"
149             + "    </script>\n"
150             + "  </head>\n"
151             + "  <body onload='test()'>\n"
152             + "    <table id='t1'>\n"
153             + "      <thead id='th1' valign='top'/>\n"
154             + "      <tbody id='tb1' valign='top'/>\n"
155             + "      <tfoot id='tf1' valign='top'/>\n"
156             + "    </table>\n"
157             + "    <table id='t2'>\n"
158             + "      <thead id='th2' valign='baseline'/>\n"
159             + "      <tbody id='tb2' valign='baseline'/>\n"
160             + "      <tfoot id='tf2' valign='baseline'/>\n"
161             + "    </table>\n"
162             + "    <table id='t3'>\n"
163             + "      <thead id='th3' valign='3'/>\n"
164             + "      <tbody id='tb3' valign='3'/>\n"
165             + "      <tfoot id='tf3' valign='3'/>\n"
166             + "    </table>\n"
167             + "  </body>\n"
168             + "</html>";
169 
170         loadPageVerifyTitle2(html);
171     }
172 
173     /**
174      * @throws Exception if an error occurs
175      */
176     @Test
177     @Alerts({"p", "po", "", "u", "8", "U8"})
178     public void ch_thead() throws Exception {
179         ch("th");
180     }
181 
182     /**
183      * @throws Exception if an error occurs
184      */
185     @Test
186     @Alerts({"p", "po", "", "u", "8", "U8"})
187     public void ch_tbody() throws Exception {
188         ch("tb");
189     }
190 
191     /**
192      * @throws Exception if an error occurs
193      */
194     @Test
195     @Alerts({"p", "po", "", "u", "8", "U8"})
196     public void ch_tfoot() throws Exception {
197         ch("tf");
198     }
199 
200     private void ch(final String id) throws Exception {
201         final String html = DOCTYPE_HTML
202             + "<html>\n"
203             + "  <head>\n"
204             + "    <script>\n"
205             + LOG_TITLE_FUNCTION
206             + "      function test() {\n"
207             + "        var t1 = document.getElementById('" + id + "1');\n"
208             + "        var t2 = document.getElementById('" + id + "2');\n"
209             + "        var t3 = document.getElementById('" + id + "3');\n"
210             + "        log(t1.ch);\n"
211             + "        log(t2.ch);\n"
212             + "        log(t3.ch);\n"
213             + "        set(t1, 'u');\n"
214             + "        set(t2, 8);\n"
215             + "        set(t3, 'U8');\n"
216             + "        log(t1.ch);\n"
217             + "        log(t2.ch);\n"
218             + "        log(t3.ch);\n"
219             + "      }\n"
220             + "      function set(e, value) {\n"
221             + "        try {\n"
222             + "          e.ch = value;\n"
223             + "        } catch(e) { logEx(e); }\n"
224             + "      }\n"
225             + "    </script>\n"
226             + "  </head>\n"
227             + "  <body onload='test()'>\n"
228             + "    <table id='t1'>\n"
229             + "      <thead id='th1' char='p'/>\n"
230             + "      <tbody id='tb1' char='p'/>\n"
231             + "      <tfoot id='tf1' char='p'/>\n"
232             + "    </table>\n"
233             + "    <table id='t2'>\n"
234             + "      <thead id='th2' char='po'/>\n"
235             + "      <tbody id='tb2' char='po'/>\n"
236             + "      <tfoot id='tf2' char='po'/>\n"
237             + "    </table>\n"
238             + "    <table id='t3'>\n"
239             + "      <thead id='th3'/>\n"
240             + "      <tbody id='tb3'/>\n"
241             + "      <tfoot id='tf3'/>\n"
242             + "    </table>\n"
243             + "  </body>\n"
244             + "</html>";
245 
246         loadPageVerifyTitle2(html);
247     }
248 
249     /**
250      * @throws Exception if an error occurs
251      */
252     @Test
253     @Alerts({"0", "4", "", "5.2", "-3", "abc"})
254     public void chOff_thead() throws Exception {
255         chOff("th");
256     }
257 
258     /**
259      * @throws Exception if an error occurs
260      */
261     @Test
262     @Alerts({"0", "4", "", "5.2", "-3", "abc"})
263     public void chOff_tbody() throws Exception {
264         chOff("tb");
265     }
266 
267     /**
268      * @throws Exception if an error occurs
269      */
270     @Test
271     @Alerts({"0", "4", "", "5.2", "-3", "abc"})
272     public void chOff_tfoot() throws Exception {
273         chOff("tf");
274     }
275 
276     private void chOff(final String id) throws Exception {
277         final String html = DOCTYPE_HTML
278             + "<html>\n"
279             + "  <head>\n"
280             + "    <script>\n"
281             + LOG_TITLE_FUNCTION
282             + "      function test() {\n"
283             + "        var t1 = document.getElementById('" + id + "1');\n"
284             + "        var t2 = document.getElementById('" + id + "2');\n"
285             + "        var t3 = document.getElementById('" + id + "3');\n"
286             + "        log(t1.chOff);\n"
287             + "        log(t2.chOff);\n"
288             + "        log(t3.chOff);\n"
289             + "        set(t1, '5.2');\n"
290             + "        set(t2, -3);\n"
291             + "        set(t3, 'abc');\n"
292             + "        log(t1.chOff);\n"
293             + "        log(t2.chOff);\n"
294             + "        log(t3.chOff);\n"
295             + "      }\n"
296             + "      function set(e, value) {\n"
297             + "        try {\n"
298             + "          e.chOff = value;\n"
299             + "        } catch(e) { logEx(e); }\n"
300             + "      }\n"
301             + "    </script>\n"
302             + "  </head>\n"
303             + "  <body onload='test()'>\n"
304             + "    <table id='t1'>\n"
305             + "      <thead id='th1' charoff='0'/>\n"
306             + "      <tbody id='tb1' charoff='0'/>\n"
307             + "      <tfoot id='tf1' charoff='0'/>\n"
308             + "    </table>\n"
309             + "    <table id='t2'>\n"
310             + "      <thead id='th2' charoff='4'/>\n"
311             + "      <tbody id='tb2' charoff='4'/>\n"
312             + "      <tfoot id='tf2' charoff='4'/>\n"
313             + "    </table>\n"
314             + "    <table id='t3'>\n"
315             + "      <thead id='th3'/>\n"
316             + "      <tbody id='tb3'/>\n"
317             + "      <tfoot id='tf3'/>\n"
318             + "    </table>\n"
319             + "  </body>\n"
320             + "</html>";
321 
322         loadPageVerifyTitle2(html);
323     }
324 
325     /**
326      * @throws Exception if the test fails
327      */
328     @Test
329     @Alerts("<tr><td>world</td></tr>")
330     public void TBODY_innerHTML() throws Exception {
331         final String html = DOCTYPE_HTML
332             + "<html><head>\n"
333             + "<script>\n"
334             + LOG_TITLE_FUNCTION
335             + "  function test() {\n"
336             + "    var t = document.getElementById('myId');\n"
337             + "    try {\n"
338             + "      t.innerHTML = '<tr><td>world</td></tr>';\n"
339             + "    } catch(e) { logEx(e); }\n"
340             + "    log(t.innerHTML.toLowerCase());\n"
341             + "  }\n"
342             + "</script>\n"
343             + "</head><body onload='test()'>\n"
344             + "  <table>\n"
345             + "    <tbody id='myId'><tr><td>hello</td></tr></tbody>\n"
346             + "  </table>\n"
347             + "</body></html>";
348 
349         loadPageVerifyTitle2(html);
350     }
351 
352     /**
353      * @throws Exception if the test fails
354      */
355     @Test
356     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
357     public void innerText_body() throws Exception {
358         final String html = DOCTYPE_HTML
359             + "<html><body>\n"
360             + "  <table>\n"
361             + "    <tbody id='tab_row'><tr><td>cell1</td></tr></tbody>\n"
362             + "  </table>\n"
363             + "<script>\n"
364             + LOG_TITLE_FUNCTION
365             + "  var node = document.getElementById('tab_row');\n"
366             + "  log(node.innerText);\n"
367             + "  log(node.firstChild);\n"
368 
369             + "  try { node.innerText = 'abc'; } catch(e) { logEx(e); }\n"
370             + "  log(node.innerText);\n"
371             + "  log(node.firstChild);\n"
372 
373             + "  try { node.innerText = ''; } catch(e) { logEx(e); }\n"
374             + "  log(node.innerText);\n"
375             + "</script></body></html>";
376 
377         loadPageVerifyTitle2(html);
378     }
379 
380     /**
381      * @throws Exception if the test fails
382      */
383     @Test
384     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
385     public void innerText_header() throws Exception {
386         final String html = DOCTYPE_HTML
387             + "<html><body>\n"
388             + "  <table>\n"
389             + "    <thead id='tab_row'><tr><td>cell1</td></tr></thead>\n"
390             + "  </table>\n"
391             + "<script>\n"
392             + LOG_TITLE_FUNCTION
393             + "  var node = document.getElementById('tab_row');\n"
394             + "  log(node.innerText);\n"
395             + "  log(node.firstChild);\n"
396 
397             + "  try { node.innerText = 'abc'; } catch(e) { log(e); }\n"
398             + "  log(node.innerText);\n"
399             + "  log(node.firstChild);\n"
400 
401             + "  try { node.innerText = ''; } catch(e) { logEx(e); }\n"
402             + "  log(node.innerText);\n"
403             + "</script></body></html>";
404 
405         loadPageVerifyTitle2(html);
406     }
407 
408     /**
409      * @throws Exception if the test fails
410      */
411     @Test
412     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
413     public void innerText_footer() throws Exception {
414         final String html = DOCTYPE_HTML
415             + "<html><body>\n"
416             + "  <table>\n"
417             + "    <tfoot id='tab_row'><tr><td>cell1</td></tr></tfoot>\n"
418             + "  </table>\n"
419             + "<script>\n"
420             + LOG_TITLE_FUNCTION
421             + "  var node = document.getElementById('tab_row');\n"
422             + "  log(node.innerText);\n"
423             + "  log(node.firstChild);\n"
424 
425             + "  try { node.innerText = 'abc'; } catch(e) { logEx(e); }\n"
426             + "  log(node.innerText);\n"
427             + "  log(node.firstChild);\n"
428 
429             + "  try { node.innerText = ''; } catch(e) { logEx(e); }\n"
430             + "  log(node.innerText);\n"
431             + "</script></body></html>";
432 
433         loadPageVerifyTitle2(html);
434     }
435 
436     /**
437      * @throws Exception if the test fails
438      */
439     @Test
440     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
441     public void textContent_body() throws Exception {
442         final String html = DOCTYPE_HTML
443             + "<html><body>\n"
444             + "  <table>\n"
445             + "    <tbody id='tab_row'><tr><td>cell1</td></tr></tbody>\n"
446             + "  </table>\n"
447             + "<script>\n"
448             + LOG_TITLE_FUNCTION
449             + "  var node = document.getElementById('tab_row');\n"
450             + "  log(node.textContent);\n"
451             + "  log(node.firstChild);\n"
452 
453             + "  try { node.textContent = 'abc'; } catch(e) { logEx(e); }\n"
454             + "  log(node.textContent);\n"
455             + "  log(node.firstChild);\n"
456 
457             + "  try { node.textContent = ''; } catch(e) { logEx(e); }\n"
458             + "  log(node.textContent);\n"
459             + "</script></body></html>";
460 
461         loadPageVerifyTitle2(html);
462     }
463 
464     /**
465      * @throws Exception if the test fails
466      */
467     @Test
468     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
469     public void textContent_header() throws Exception {
470         final String html = DOCTYPE_HTML
471             + "<html><body>\n"
472             + "  <table>\n"
473             + "    <thead id='tab_row'><tr><td>cell1</td></tr></thead>\n"
474             + "  </table>\n"
475             + "<script>\n"
476             + LOG_TITLE_FUNCTION
477             + "  var node = document.getElementById('tab_row');\n"
478             + "  log(node.textContent);\n"
479             + "  log(node.firstChild);\n"
480 
481             + "  try { node.textContent = 'abc'; } catch(e) { logEx(e); }\n"
482             + "  log(node.textContent);\n"
483             + "  log(node.firstChild);\n"
484 
485             + "  try { node.textContent = ''; } catch(e) { logEx(e); }\n"
486             + "  log(node.textContent);\n"
487             + "</script></body></html>";
488 
489         loadPageVerifyTitle2(html);
490     }
491 
492     /**
493      * @throws Exception if the test fails
494      */
495     @Test
496     @Alerts({"cell1", "[object HTMLTableRowElement]", "abc", "[object Text]", ""})
497     public void textContent_footer() throws Exception {
498         final String html = DOCTYPE_HTML
499             + "<html><body>\n"
500             + "  <table>\n"
501             + "    <tfoot id='tab_row'><tr><td>cell1</td></tr></tfoot>\n"
502             + "  </table>\n"
503             + "<script>\n"
504             + LOG_TITLE_FUNCTION
505             + "  var node = document.getElementById('tab_row');\n"
506             + "  log(node.textContent);\n"
507             + "  log(node.firstChild);\n"
508 
509             + "  try { node.textContent = 'abc'; } catch(e) { logEx(e); }\n"
510             + "  log(node.textContent);\n"
511             + "  log(node.firstChild);\n"
512 
513             + "  try { node.textContent = ''; } catch(e) { logEx(e); }\n"
514             + "  log(node.textContent);\n"
515             + "</script></body></html>";
516 
517         loadPageVerifyTitle2(html);
518     }
519 
520     /**
521      * @throws Exception if an error occurs
522      */
523     @Test
524     @Alerts({"undefined", "#0000aa", "x"})
525     public void bgColorFooter() throws Exception {
526         final String html = DOCTYPE_HTML
527             + "<html>\n"
528             + "  <head>\n"
529             + "    <script>\n"
530             + LOG_TITLE_FUNCTION
531             + "      function test() {\n"
532             + "        var tfoot = document.getElementById('tfoot');\n"
533             + "        log(tfoot.bgColor);\n"
534             + "        tfoot.bgColor = '#0000aa';\n"
535             + "        log(tfoot.bgColor);\n"
536             + "        tfoot.bgColor = 'x';\n"
537             + "        log(tfoot.bgColor);\n"
538             + "      }\n"
539             + "    </script>\n"
540             + "  </head>\n"
541             + "  <body onload='test()'>\n"
542             + "  <table><tfoot id='tfoot'><tr><td>cell1</td></tr></tfoot></table>\n"
543             + "  </body>\n"
544             + "</html>";
545 
546         loadPageVerifyTitle2(html);
547     }
548 
549     /**
550      * @throws Exception if an error occurs
551      */
552     @Test
553     @Alerts({"undefined", "#0000aa", "x"})
554     public void bgColorHeader() throws Exception {
555         final String html = DOCTYPE_HTML
556             + "<html>\n"
557             + "  <head>\n"
558             + "    <script>\n"
559             + LOG_TITLE_FUNCTION
560             + "      function test() {\n"
561             + "        var thead = document.getElementById('thead');\n"
562             + "        log(thead.bgColor);\n"
563             + "        thead.bgColor = '#0000aa';\n"
564             + "        log(thead.bgColor);\n"
565             + "        thead.bgColor = 'x';\n"
566             + "        log(thead.bgColor);\n"
567             + "      }\n"
568             + "    </script>\n"
569             + "  </head>\n"
570             + "  <body onload='test()'>\n"
571             + "  <table><thead id='thead'><tr><td>cell1</td></tr></thead></table>\n"
572             + "  </body>\n"
573             + "</html>";
574 
575         loadPageVerifyTitle2(html);
576     }
577 
578     /**
579      * @throws Exception if an error occurs
580      */
581     @Test
582     @Alerts({"<thead id=\"thead\"><tr><td>cell1</td></tr></thead>", "new"})
583     public void outerHTML() throws Exception {
584         final String html = DOCTYPE_HTML
585             + "<html>\n"
586             + "  <head>\n"
587             + "    <script>\n"
588             + LOG_TITLE_FUNCTION
589             + "      function test() {\n"
590             + "        log(document.getElementById('thead').outerHTML);\n"
591             + "        document.getElementById('thead').outerHTML = '<div id=\"new\">text<div>';\n"
592             + "        log(document.getElementById('new').id);\n"
593             + "      }\n"
594             + "    </script>\n"
595             + "  </head>\n"
596             + "  <body onload='test()'>\n"
597             + "  <table><thead id='thead'><tr><td>cell1</td></tr></thead></table>\n"
598             + "  </body>\n"
599             + "</html>";
600 
601         loadPageVerifyTitle2(html);
602     }
603 }