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