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.htmlunit.junit.annotation.HtmlUnitNYI;
21  import org.junit.Test;
22  import org.junit.runner.RunWith;
23  
24  /**
25   * Tests for {@link HTMLTableCellElement}.
26   *
27   * @author Daniel Gredler
28   * @author Ahmed Ashour
29   * @author Ronald Brill
30   * @author Frank Danek
31   */
32  @RunWith(BrowserRunner.class)
33  public class HTMLTableCellElementTest extends WebDriverTestCase {
34  
35      /**
36       * @throws Exception if an error occurs
37       */
38      @Test
39      @Alerts({"left", "right", "3", "center", "8", "foo"})
40      public void align() throws Exception {
41          final String html = DOCTYPE_HTML
42              + "<html><body><table>\n"
43              + "  <tr>\n"
44              + "    <td id='td1' align='left'>a</td>\n"
45              + "    <td id='td2' align='right'>b</td>\n"
46              + "    <td id='td3' align='3'>c</td>\n"
47              + "  </tr>\n"
48              + "</table>\n"
49              + "<script>\n"
50              + LOG_TITLE_FUNCTION
51              + "  function set(e, value) {\n"
52              + "    try {\n"
53              + "      e.align = value;\n"
54              + "    } catch(e) { logEx(e); }\n"
55              + "  }\n"
56              + "  var td1 = document.getElementById('td1');\n"
57              + "  var td2 = document.getElementById('td2');\n"
58              + "  var td3 = document.getElementById('td3');\n"
59              + "  log(td1.align);\n"
60              + "  log(td2.align);\n"
61              + "  log(td3.align);\n"
62              + "  set(td1, 'center');\n"
63              + "  set(td2, '8');\n"
64              + "  set(td3, 'foo');\n"
65              + "  log(td1.align);\n"
66              + "  log(td2.align);\n"
67              + "  log(td3.align);\n"
68              + "</script>\n"
69              + "</body></html>";
70  
71          loadPageVerifyTitle2(html);
72      }
73  
74      /**
75       * @throws Exception if an error occurs
76       */
77      @Test
78      @Alerts({"p", "po", "", "u", "8", "U8"})
79      public void ch() throws Exception {
80          final String html = DOCTYPE_HTML
81              + "<html><body><table>\n"
82              + "  <tr>\n"
83              + "    <td id='td1' char='p'>a</td>\n"
84              + "    <td id='td2' char='po'>b</td>\n"
85              + "    <td id='td3'>c</td>\n"
86              + "  </tr>\n"
87              + "</table>\n"
88              + "<script>\n"
89              + LOG_TITLE_FUNCTION
90              + "  var td1 = document.getElementById('td1');\n"
91              + "  var td2 = document.getElementById('td2');\n"
92              + "  var td3 = document.getElementById('td3');\n"
93              + "  log(td1.ch);\n"
94              + "  log(td2.ch);\n"
95              + "  log(td3.ch);\n"
96              + "  td1.ch = 'u';\n"
97              + "  td2.ch = '8';\n"
98              + "  td3.ch = 'U8';\n"
99              + "  log(td1.ch);\n"
100             + "  log(td2.ch);\n"
101             + "  log(td3.ch);\n"
102             + "</script>\n"
103             + "</body></html>";
104 
105         loadPageVerifyTitle2(html);
106     }
107 
108     /**
109      * @throws Exception if an error occurs
110      */
111     @Test
112     @Alerts({"0", "4", "", "5.2", "-3", "abc"})
113     public void chOff() throws Exception {
114         final String html = DOCTYPE_HTML
115             + "<html><body><table>\n"
116             + "  <tr>\n"
117             + "    <td id='td1' charoff='0'>a</td>\n"
118             + "    <td id='td2' charoff='4'>b</td>\n"
119             + "    <td id='td3'>c</td>\n"
120             + "  </tr>\n"
121             + "</table>\n"
122             + "<script>\n"
123             + LOG_TITLE_FUNCTION
124             + "  var td1 = document.getElementById('td1');\n"
125             + "  var td2 = document.getElementById('td2');\n"
126             + "  var td3 = document.getElementById('td3');\n"
127             + "  log(td1.chOff);\n"
128             + "  log(td2.chOff);\n"
129             + "  log(td3.chOff);\n"
130             + "  td1.chOff = '5.2';\n"
131             + "  td2.chOff = '-3';\n"
132             + "  td3.chOff = 'abc';\n"
133             + "  log(td1.chOff);\n"
134             + "  log(td2.chOff);\n"
135             + "  log(td3.chOff);\n"
136             + "</script>\n"
137             + "</body></html>";
138 
139         loadPageVerifyTitle2(html);
140     }
141 
142     /**
143      * @throws Exception if an error occurs
144      */
145     @Test
146     @Alerts({"top", "baseline", "3", "middle", "8", "BOTtom"})
147     public void vAlign() throws Exception {
148         final String html = DOCTYPE_HTML
149             + "<html><body><table>\n"
150             + "  <tr>\n"
151             + "    <td id='td1' valign='top'>a</td>\n"
152             + "    <td id='td2' valign='baseline'>b</td>\n"
153             + "    <td id='td3' valign='3'>c</td>\n"
154             + "  </tr>\n"
155             + "</table>\n"
156             + "<script>\n"
157             + LOG_TITLE_FUNCTION
158             + "  function set(e, value) {\n"
159             + "    try {\n"
160             + "      e.vAlign = value;\n"
161             + "    } catch(e) { logEx(e); }\n"
162             + "  }\n"
163             + "  var td1 = document.getElementById('td1');\n"
164             + "  var td2 = document.getElementById('td2');\n"
165             + "  var td3 = document.getElementById('td3');\n"
166             + "  log(td1.vAlign);\n"
167             + "  log(td2.vAlign);\n"
168             + "  log(td3.vAlign);\n"
169             + "  set(td1, 'middle');\n"
170             + "  set(td2, 8);\n"
171             + "  set(td3, 'BOTtom');\n"
172             + "  log(td1.vAlign);\n"
173             + "  log(td2.vAlign);\n"
174             + "  log(td3.vAlign);\n"
175             + "</script>\n"
176             + "</body></html>";
177 
178         loadPageVerifyTitle2(html);
179     }
180 
181     /**
182      * @throws Exception if an error occurs
183      */
184     @Test
185     @Alerts({"", "#0000aa", "x"})
186     public void bgColor() throws Exception {
187         final String html = DOCTYPE_HTML
188             + "<html>\n"
189             + "  <head>\n"
190             + "    <script>\n"
191             + LOG_TITLE_FUNCTION
192             + "      function test() {\n"
193             + "        var td = document.getElementById('td');\n"
194             + "        log(td.bgColor);\n"
195             + "        td.bgColor = '#0000aa';\n"
196             + "        log(td.bgColor);\n"
197             + "        td.bgColor = 'x';\n"
198             + "        log(td.bgColor);\n"
199             + "      }\n"
200             + "    </script>\n"
201             + "  </head>\n"
202             + "  <body onload='test()'>\n"
203             + "  <table><tr><td id='td'>a</td></tr></table>\n"
204             + "  </body>\n"
205             + "</html>";
206 
207         loadPageVerifyTitle2(html);
208     }
209 
210     /**
211      * @throws Exception if an error occurs
212      */
213     @Test
214     @Alerts({"false", "null", "true", "", "true", "", "true", "blah", "false", "null"})
215     public void noWrap() throws Exception {
216         final String html = DOCTYPE_HTML
217             + "<html>\n"
218             + "  <head>\n"
219             + "    <script>\n"
220             + LOG_TITLE_FUNCTION
221             + "      function test() {\n"
222             + "        var td = document.getElementById('td');\n"
223             + "        log(td.noWrap);\n"
224             + "        log(td.getAttribute('noWrap'));\n"
225             + "        td.noWrap = 'nowrap';\n"
226             + "        log(td.noWrap);\n"
227             + "        log(td.getAttribute('noWrap'));\n"
228             + "        td.noWrap = 'x';\n"
229             + "        log(td.noWrap);\n"
230             + "        log(td.getAttribute('noWrap'));\n"
231             + "        td.setAttribute('noWrap', 'blah');\n"
232             + "        log(td.noWrap);\n"
233             + "        log(td.getAttribute('noWrap'));\n"
234             + "        td.noWrap = '';\n"
235             + "        log(td.noWrap);\n"
236             + "        log(td.getAttribute('noWrap'));\n"
237             + "      }\n"
238             + "    </script>\n"
239             + "  </head>\n"
240             + "  <body onload='test()'>\n"
241             + "  <table><tr><td id='td'>a</td></tr></table>\n"
242             + "  </body>\n"
243             + "</html>";
244 
245         loadPageVerifyTitle2(html);
246     }
247 
248     /**
249      * @throws Exception if an error occurs
250      */
251     @Test
252     @Alerts({"", "blah", "3", ""})
253     public void abbr() throws Exception {
254         final String html = DOCTYPE_HTML
255             + "<html>\n"
256             + "  <head>\n"
257             + "    <script>\n"
258             + LOG_TITLE_FUNCTION
259             + "      function test() {\n"
260             + "        var td = document.getElementById('td');\n"
261             + "        log(td.abbr);\n"
262             + "        td.abbr = 'blah';\n"
263             + "        log(td.abbr);\n"
264             + "        td.abbr = 3;\n"
265             + "        log(td.abbr);\n"
266             + "        td.abbr = '';\n"
267             + "        log(td.abbr);\n"
268             + "      }\n"
269             + "    </script>\n"
270             + "  </head>\n"
271             + "  <body onload='test()'>\n"
272             + "  <table><tr><td id='td'>a</td></tr></table>\n"
273             + "  </body>\n"
274             + "</html>";
275 
276         loadPageVerifyTitle2(html);
277     }
278 
279     /**
280      * @throws Exception if an error occurs
281      */
282     @Test
283     @Alerts({"1", "3", "1", "2", "1", "5", "1", "2", "1"})
284     public void colSpan() throws Exception {
285         final String html = DOCTYPE_HTML
286             + "<html><body><table>\n"
287             + "  <tr>\n"
288             + "    <td id='td1'>a</td>\n"
289             + "    <td id='td2' colspan='3'>b</td>\n"
290             + "    <td id='td3' colspan='foo'>c</td>\n"
291             + "  </tr>\n"
292             + "</table>\n"
293             + "<script>\n"
294             + LOG_TITLE_FUNCTION
295             + "  function set(e, value) {\n"
296             + "    try {\n"
297             + "      e.colSpan = value;\n"
298             + "    } catch(e) { logEx(e); }\n"
299             + "  }\n"
300             + "  var td1 = document.getElementById('td1');\n"
301             + "  var td2 = document.getElementById('td2');\n"
302             + "  var td3 = document.getElementById('td3');\n"
303             + "  log(td1.colSpan);\n"
304             + "  log(td2.colSpan);\n"
305             + "  log(td3.colSpan);\n"
306             + "  set(td1, '2');\n"
307             + "  set(td2, 'blah');\n"
308             + "  set(td3, 5);\n"
309             + "  log(td1.colSpan);\n"
310             + "  log(td2.colSpan);\n"
311             + "  log(td3.colSpan);\n"
312             + "  set(td1, -1);\n"
313             + "  set(td2, 2.2);\n"
314             + "  set(td3, 0);\n"
315             + "  log(td1.colSpan);\n"
316             + "  log(td2.colSpan);\n"
317             + "  log(td3.colSpan);\n"
318             + "</script>\n"
319             + "</body></html>";
320 
321         loadPageVerifyTitle2(html);
322     }
323 
324     /**
325      * @throws Exception if an error occurs
326      */
327     @Test
328     @Alerts("3")
329     public void colSpanLineBreaks() throws Exception {
330         final String html = DOCTYPE_HTML
331             + "<html><body><table>\n"
332             + "  <tr>\n"
333             + "    <td id='td1' colspan='\r3\t\n  '>b</td>\n"
334             + "  </tr>\n"
335             + "</table>\n"
336             + "<script>\n"
337             + LOG_TITLE_FUNCTION_NORMALIZE
338             + "  var td1 = document.getElementById('td1');\n"
339             + "  log(td1.colSpan);\n"
340             + "</script>\n"
341             + "</body></html>";
342 
343         loadPageVerifyTitle2(html);
344     }
345 
346     /**
347      * @throws Exception if an error occurs
348      */
349     @Test
350     @Alerts({"1", "1", "3", "3", "3"})
351     public void colSpanInvalid() throws Exception {
352         final String html = DOCTYPE_HTML
353             + "<html><body><table>\n"
354             + "  <tr>\n"
355             + "    <td id='td1' colspan='-1'>b</td>\n"
356             + "    <td id='td2' colspan='0'>b</td>\n"
357             + "    <td id='td3' colspan='3.14'>b</td>\n"
358             + "    <td id='td4' colspan='3.5'>b</td>\n"
359             + "    <td id='td5' colspan='3.7'>b</td>\n"
360             + "  </tr>\n"
361             + "</table>\n"
362             + "<script>\n"
363             + LOG_TITLE_FUNCTION_NORMALIZE
364             + "  var td1 = document.getElementById('td1');\n"
365             + "  var td2 = document.getElementById('td2');\n"
366             + "  var td3 = document.getElementById('td3');\n"
367             + "  var td4 = document.getElementById('td4');\n"
368             + "  var td5 = document.getElementById('td5');\n"
369             + "  log(td1.colSpan);\n"
370             + "  log(td2.colSpan);\n"
371             + "  log(td3.colSpan);\n"
372             + "  log(td4.colSpan);\n"
373             + "  log(td5.colSpan);\n"
374             + "</script>\n"
375             + "</body></html>";
376 
377         loadPageVerifyTitle2(html);
378     }
379 
380     /**
381      * @throws Exception if an error occurs
382      */
383     @Test
384     @Alerts({"999", "1000", "1000"})
385     public void colSpanLarge() throws Exception {
386         final String html = DOCTYPE_HTML
387             + "<html><body><table>\n"
388             + "  <tr>\n"
389             + "    <td id='td1' colspan='999'>b</td>\n"
390             + "    <td id='td2' colspan='1000'>b</td>\n"
391             + "    <td id='td3' colspan='1001'>b</td>\n"
392             + "  </tr>\n"
393             + "</table>\n"
394             + "<script>\n"
395             + LOG_TITLE_FUNCTION_NORMALIZE
396             + "  var td1 = document.getElementById('td1');\n"
397             + "  var td2 = document.getElementById('td2');\n"
398             + "  var td3 = document.getElementById('td3');\n"
399             + "  log(td1.colSpan);\n"
400             + "  log(td2.colSpan);\n"
401             + "  log(td3.colSpan);\n"
402             + "</script>\n"
403             + "</body></html>";
404 
405         loadPageVerifyTitle2(html);
406     }
407 
408     /**
409      * @throws Exception if an error occurs
410      */
411     @Test
412     @Alerts({"1", "3", "1", "2", "0", "5", "1", "2", "0"})
413     public void rowSpan() throws Exception {
414         final String html = DOCTYPE_HTML
415             + "<html><body><table>\n"
416             + "  <tr>\n"
417             + "    <td id='td1'>a</td>\n"
418             + "    <td id='td2' rowspan='3'>b</td>\n"
419             + "    <td id='td3' rowspan='foo'>c</td>\n"
420             + "  </tr>\n"
421             + "  <tr><td>a</td><td>b</td><td>c</td></tr>\n"
422             + "  <tr><td>a</td><td>b</td><td>c</td></tr>\n"
423             + "  <tr><td>a</td><td>b</td><td>c</td></tr>\n"
424             + "  <tr><td>a</td><td>b</td><td>c</td></tr>\n"
425             + "  <tr><td>a</td><td>b</td><td>c</td></tr>\n"
426             + "</table>\n"
427             + "<script>\n"
428             + LOG_TITLE_FUNCTION
429             + "  function set(e, value) {\n"
430             + "    try {\n"
431             + "      e.rowSpan = value;\n"
432             + "    } catch(e) { logEx(e); }\n"
433             + "  }\n"
434             + "  var td1 = document.getElementById('td1');\n"
435             + "  var td2 = document.getElementById('td2');\n"
436             + "  var td3 = document.getElementById('td3');\n"
437             + "  log(td1.rowSpan);\n"
438             + "  log(td2.rowSpan);\n"
439             + "  log(td3.rowSpan);\n"
440             + "  set(td1, '2');\n"
441             + "  set(td2, 'blah');\n"
442             + "  set(td3, 5);\n"
443             + "  log(td1.rowSpan);\n"
444             + "  log(td2.rowSpan);\n"
445             + "  log(td3.rowSpan);\n"
446             + "  set(td1, -1);\n"
447             + "  set(td2, 2.2);\n"
448             + "  set(td3, 0);\n"
449             + "  log(td1.rowSpan);\n"
450             + "  log(td2.rowSpan);\n"
451             + "  log(td3.rowSpan);\n"
452             + "</script>\n"
453             + "</body></html>";
454 
455         loadPageVerifyTitle2(html);
456     }
457 
458     /**
459      * @throws Exception if an error occurs
460      */
461     @Test
462     @Alerts("3")
463     public void rowSpanLineBreaks() throws Exception {
464         final String html = DOCTYPE_HTML
465             + "<html><body><table>\n"
466             + "  <tr>\n"
467             + "    <td id='td1' rowspan='\r3\t\n  '>a</td>\n"
468             + "  </tr>\n"
469             + "</table>\n"
470             + "<script>\n"
471             + LOG_TITLE_FUNCTION_NORMALIZE
472             + "  var td1 = document.getElementById('td1');\n"
473             + "  log(td1.rowSpan);\n"
474             + "</script>\n"
475             + "</body></html>";
476 
477         loadPageVerifyTitle2(html);
478     }
479 
480     /**
481      * @throws Exception if an error occurs
482      */
483     @Test
484     @Alerts({"1", "0", "3", "3", "3"})
485     public void rowSpanInvalid() throws Exception {
486         final String html = DOCTYPE_HTML
487             + "<html><body><table>\n"
488             + "  <tr>\n"
489             + "    <td id='td1' rowspan='-1'>b</td>\n"
490             + "    <td id='td2' rowspan='0'>b</td>\n"
491             + "    <td id='td3' rowspan='3.14'>b</td>\n"
492             + "    <td id='td4' rowspan='3.5'>b</td>\n"
493             + "    <td id='td5' rowspan='3.7'>b</td>\n"
494             + "  </tr>\n"
495             + "</table>\n"
496             + "<script>\n"
497             + LOG_TITLE_FUNCTION_NORMALIZE
498             + "  var td1 = document.getElementById('td1');\n"
499             + "  var td2 = document.getElementById('td2');\n"
500             + "  var td3 = document.getElementById('td3');\n"
501             + "  var td4 = document.getElementById('td4');\n"
502             + "  var td5 = document.getElementById('td5');\n"
503             + "  log(td1.rowSpan);\n"
504             + "  log(td2.rowSpan);\n"
505             + "  log(td3.rowSpan);\n"
506             + "  log(td4.rowSpan);\n"
507             + "  log(td5.rowSpan);\n"
508             + "</script>\n"
509             + "</body></html>";
510 
511         loadPageVerifyTitle2(html);
512     }
513 
514     /**
515      * @throws Exception if an error occurs
516      */
517     @Test
518     @Alerts({"999", "1001", "65534", "65534"})
519     public void rowSpanLarge() throws Exception {
520         final String html = DOCTYPE_HTML
521             + "<html><body><table>\n"
522             + "  <tr>\n"
523             + "    <td id='td1' rowspan='999'>b</td>\n"
524             + "    <td id='td2' rowspan='1001'>b</td>\n"
525             + "    <td id='td3' rowspan='65534'>b</td>\n"
526             + "    <td id='td4' rowspan='65535'>b</td>\n"
527             + "  </tr>\n"
528             + "</table>\n"
529             + "<script>\n"
530             + LOG_TITLE_FUNCTION_NORMALIZE
531             + "  var td1 = document.getElementById('td1');\n"
532             + "  var td2 = document.getElementById('td2');\n"
533             + "  var td3 = document.getElementById('td3');\n"
534             + "  var td4 = document.getElementById('td4');\n"
535             + "  log(td1.rowSpan);\n"
536             + "  log(td2.rowSpan);\n"
537             + "  log(td3.rowSpan);\n"
538             + "  log(td4.rowSpan);\n"
539             + "</script>\n"
540             + "</body></html>";
541 
542         loadPageVerifyTitle2(html);
543     }
544 
545     /**
546      * @throws Exception if an error occurs
547      */
548     @Test
549     @Alerts({"", "blah", "abc , xyz", "3", ""})
550     public void axis() throws Exception {
551         final String html = DOCTYPE_HTML
552             + "<html>\n"
553             + "  <head>\n"
554             + "    <script>\n"
555             + LOG_TITLE_FUNCTION
556             + "      function test() {\n"
557             + "        var td = document.getElementById('td');\n"
558             + "        log(td.axis);\n"
559             + "        td.axis = 'blah';\n"
560             + "        log(td.axis);\n"
561             + "        td.axis = 'abc , xyz';\n"
562             + "        log(td.axis);\n"
563             + "        td.axis = 3;\n"
564             + "        log(td.axis);\n"
565             + "        td.axis = '';\n"
566             + "        log(td.axis);\n"
567             + "      }\n"
568             + "    </script>\n"
569             + "  </head>\n"
570             + "  <body onload='test()'>\n"
571             + "  <table><tr><td id='td'>a</td></tr></table>\n"
572             + "  </body>\n"
573             + "</html>";
574 
575         loadPageVerifyTitle2(html);
576     }
577 
578     /**
579      * Tests some obscure table cell CSS calculations required by the MochiKit tests.
580      * @throws Exception if an error occurs
581      */
582     @Test
583     @Alerts({"100,42", "90,36"})
584     @HtmlUnitNYI(CHROME = {"100,30", "90,30"},
585             EDGE = {"100,30", "90,30"},
586             FF = {"100,30", "90,30"},
587             FF_ESR = {"100,30", "90,30"})
588     public void cellWidthHeightWithBorderCollapse() throws Exception {
589         final String html = DOCTYPE_HTML
590             + "<html><body><table id='t'><tr>\n"
591             + "<td id='td1' style='width: 80px; height: 30px; "
592                         + "border: 2px solid blue; border-width: 2px 7px 10px 13px; padding: 0px;'>a</td>\n"
593             + "</tr></table>\n"
594             + "<script>\n"
595             + LOG_TITLE_FUNCTION
596             + "  var t = document.getElementById('t');\n"
597             + "  var td1 = document.getElementById('td1');\n"
598 
599             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
600 
601             + "  t.style.borderCollapse = 'collapse';\n"
602             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
603 
604             + "</script></body></html>";
605 
606         loadPageVerifyTitle2(html);
607     }
608 
609     /**
610      * @throws Exception if an error occurs
611      */
612     @Test
613     @Alerts({"84,42", "84,42", "100,42", "82,36", "88,36", "90,36"})
614     @HtmlUnitNYI(CHROME = {"84,30", "80,30", "100,30", "82,30", "80,30", "90,30"},
615             EDGE = {"84,30", "80,30", "100,30", "82,30", "80,30", "90,30"},
616             FF = {"84,30", "80,30", "100,30", "82,30", "80,30", "90,30"},
617             FF_ESR = {"84,30", "80,30", "100,30", "82,30", "80,30", "90,30"})
618     public void cellWidthHeightWithBorderCollapseCellsInRow() throws Exception {
619         final String html = DOCTYPE_HTML
620             + "<html><body><table id='t'><tr>\n"
621             + "<td id='td1' style='width: 80px; height: 30px; border: 2px solid blue; padding: 0px;'>a</td>\n"
622             + "<td id='td2' style='width: 80px; height: 30px; "
623                         + "border: solid blue; border-width: 2px; padding: 0px;'>a</td>\n"
624             + "<td id='td3' style='width: 80px; height: 30px; "
625                         + "border: 2px solid blue; border-width: 2px 7px 10px 13px; padding: 0px;'>a</td>\n"
626             + "</tr></table>\n"
627             + "<script>\n"
628             + LOG_TITLE_FUNCTION
629             + "  var t = document.getElementById('t');\n"
630             + "  var td1 = document.getElementById('td1');\n"
631             + "  var td2 = document.getElementById('td2');\n"
632             + "  var td3 = document.getElementById('td3');\n"
633 
634             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
635             + "  log(td2.offsetWidth + ',' + td2.offsetHeight);\n"
636             + "  log(td3.offsetWidth + ',' + td3.offsetHeight);\n"
637 
638             + "  t.style.borderCollapse = 'collapse';\n"
639             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
640             + "  log(td2.offsetWidth + ',' + td2.offsetHeight);\n"
641             + "  log(td3.offsetWidth + ',' + td3.offsetHeight);\n"
642 
643             + "</script></body></html>";
644 
645         loadPageVerifyTitle2(html);
646     }
647 
648     /**
649      * Tests some obscure table cell CSS calculations required by the MochiKit tests.
650      * @throws Exception if an error occurs
651      */
652     @Test
653     @Alerts({"84,34", "84,34", "84,34", "82,32", "82,32", "82,32"})
654     @HtmlUnitNYI(CHROME = {"84,30", "84,30", "84,30", "82,30", "82,30", "82,30"},
655             EDGE = {"84,30", "84,30", "84,30", "82,30", "82,30", "82,30"},
656             FF = {"84,30", "84,30", "84,30", "82,30", "82,30", "82,30"},
657             FF_ESR = {"84,30", "84,30", "84,30", "82,30", "82,30", "82,30"})
658     public void cellWidthHeightWithBorderCollapseSameCellLayout() throws Exception {
659         final String html = DOCTYPE_HTML
660             + "<html><body><table id='t'><tr>\n"
661             + "<td id='td1' style='width: 80px; height: 30px; border: 2px solid blue; padding: 0px;'>a</td>\n"
662             + "<td id='td2' style='width: 80px; height: 30px; border: 2px solid blue; padding: 0px;'>a</td>\n"
663             + "<td id='td3' style='width: 80px; height: 30px; border: 2px solid blue; padding: 0px;'>a</td>\n"
664             + "</tr></table>\n"
665             + "<script>\n"
666             + LOG_TITLE_FUNCTION
667             + "  var t = document.getElementById('t');\n"
668             + "  var td1 = document.getElementById('td1');\n"
669             + "  var td2 = document.getElementById('td2');\n"
670             + "  var td3 = document.getElementById('td3');\n"
671 
672             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
673             + "  log(td2.offsetWidth + ',' + td2.offsetHeight);\n"
674             + "  log(td3.offsetWidth + ',' + td3.offsetHeight);\n"
675 
676             + "  t.style.borderCollapse = 'collapse';\n"
677             + "  log(td1.offsetWidth + ',' + td1.offsetHeight);\n"
678             + "  log(td2.offsetWidth + ',' + td2.offsetHeight);\n"
679             + "  log(td3.offsetWidth + ',' + td3.offsetHeight);\n"
680             + "</script></body></html>";
681 
682         loadPageVerifyTitle2(html);
683     }
684 
685     /**
686      * @throws Exception if an error occurs
687      */
688     @Test
689     @Alerts({"100px", "200px", "400", "abc", "-5", "100.2", "10%"})
690     public void width() throws Exception {
691         final String html = DOCTYPE_HTML
692             + "<html>\n"
693             + "  <head>\n"
694             + "    <script>\n"
695             + LOG_TITLE_FUNCTION
696             + "      function set(e, value) {\n"
697             + "        try {\n"
698             + "          e.width = value;\n"
699             + "        } catch(e) { logEx(e); }\n"
700             + "      }\n"
701             + "      function test() {\n"
702             + "        var td = document.getElementById('td');\n"
703             + "        set(td, '100px');\n"
704             + "        log(td.width);\n"
705             + "        td.height = '200px';\n"
706             + "        log(td.height);\n"
707             + "        set(td, '400');\n"
708             + "        log(td.width);\n"
709             + "        set(td, 'abc');\n"
710             + "        log(td.width);\n"
711             + "        set(td, -5);\n"
712             + "        log(td.width);\n"
713             + "        set(td, 100.2);\n"
714             + "        log(td.width);\n"
715             + "        set(td, '10%');\n"
716             + "        log(td.width);\n"
717             + "      }\n"
718             + "    </script>\n"
719             + "  </head>\n"
720             + "  <body onload='test()'>\n"
721             + "  <table><tr><td id='td'>a</td></tr></table>\n"
722             + "  </body>\n"
723             + "</html>";
724 
725         loadPageVerifyTitle2(html);
726     }
727 
728     /**
729      * @throws Exception if an error occurs
730      */
731     @Test
732     @Alerts("0")
733     public void offsetHeight() throws Exception {
734         final String html = DOCTYPE_HTML
735             + "<html><body>\n"
736             + "<table><tr>\n"
737             + "<td style='padding:0' id='it'></td>\n"
738             + "<td style='display: none'>t</td>\n"
739             + "</tr></table>\n"
740             + "<script>\n"
741             + LOG_TITLE_FUNCTION
742             + "var it = document.getElementById('it');\n"
743             + "log(it.offsetHeight);\n"
744             + "</script>\n"
745             + "</body></html>";
746 
747         loadPageVerifyTitle2(html);
748     }
749 
750     /**
751      * @throws Exception if the test fails
752      */
753     @Test
754     @Alerts({"undefined", "#667788", "unknown", "undefined", "undefined", "undefined"})
755     public void borderColor() throws Exception {
756         final String html = DOCTYPE_HTML
757             + "<html><body>\n"
758             + "  <table><tr><td id='tabd1'></td></tr></table>\n"
759             + "  <table><tr><td id='tabd2' borderColor='red'></td></tr></table>\n"
760             + "  <table><tr><td id='tabd3' borderColor='#123456'></td></tr></table>\n"
761             + "  <table><tr><td id='tabd4' borderColor='unknown'></td></tr></table>\n"
762             + "<script>\n"
763             + LOG_TITLE_FUNCTION
764             + "  var node = document.getElementById('tabd1');\n"
765             + "  log(node.borderColor);\n"
766 
767             + "  node.borderColor = '#667788';\n"
768             + "  log(node.borderColor);\n"
769 
770             + "  node.borderColor = 'unknown';\n"
771             + "  log(node.borderColor);\n"
772 
773             + "  var node = document.getElementById('tabd2');\n"
774             + "  log(node.borderColor);\n"
775             + "  var node = document.getElementById('tabd3');\n"
776             + "  log(node.borderColor);\n"
777             + "  var node = document.getElementById('tabd4');\n"
778             + "  log(node.borderColor);\n"
779 
780             + "</script></body></html>";
781 
782         loadPageVerifyTitle2(html);
783     }
784 
785     /**
786      * @throws Exception if the test fails
787      */
788     @Test
789     @Alerts({"undefined", "undefined", "undefined", "undefined", "undefined", "undefined"})
790     public void borderColorDark() throws Exception {
791         final String html = DOCTYPE_HTML
792             + "<html><body>\n"
793             + "  <table><tr><td id='tabd1'></td></tr></table>\n"
794             + "  <table><tr><td id='tabd2' borderColor='red'></td></tr></table>\n"
795             + "  <table><tr><td id='tabd3' borderColor='#123456'></td></tr></table>\n"
796             + "  <table><tr><td id='tabd4' borderColor='unknown'></td></tr></table>\n"
797             + "<script>\n"
798             + LOG_TITLE_FUNCTION
799             + "  var node = document.getElementById('tabd1');\n"
800             + "  log(node.borderColorDark);\n"
801 
802             + "  node.borderColor = '#667788';\n"
803             + "  log(node.borderColorDark);\n"
804 
805             + "  node.borderColor = 'unknown';\n"
806             + "  log(node.borderColorDark);\n"
807 
808             + "  var node = document.getElementById('tabd2');\n"
809             + "  log(node.borderColorDark);\n"
810             + "  var node = document.getElementById('tabd3');\n"
811             + "  log(node.borderColorDark);\n"
812             + "  var node = document.getElementById('tabd4');\n"
813             + "  log(node.borderColorDark);\n"
814 
815             + "</script></body></html>";
816 
817         loadPageVerifyTitle2(html);
818     }
819 
820     /**
821      * @throws Exception if the test fails
822      */
823     @Test
824     @Alerts({"undefined", "undefined", "undefined", "undefined", "undefined", "undefined"})
825     public void borderColorLight() throws Exception {
826         final String html = DOCTYPE_HTML
827             + "<html><body>\n"
828             + "  <table><tr><td id='tabd1'></td></tr></table>\n"
829             + "  <table><tr><td id='tabd2' borderColor='red'></td></tr></table>\n"
830             + "  <table><tr><td id='tabd3' borderColor='#123456'></td></tr></table>\n"
831             + "  <table><tr><td id='tabd4' borderColor='unknown'></td></tr></table>\n"
832             + "<script>\n"
833             + LOG_TITLE_FUNCTION
834             + "  var node = document.getElementById('tabd1');\n"
835             + "  log(node.borderColorLight);\n"
836 
837             + "  node.borderColor = '#667788';\n"
838             + "  log(node.borderColorLight);\n"
839 
840             + "  node.borderColor = 'unknown';\n"
841             + "  log(node.borderColorLight);\n"
842 
843             + "  var node = document.getElementById('tabd2');\n"
844             + "  log(node.borderColorLight);\n"
845             + "  var node = document.getElementById('tabd3');\n"
846             + "  log(node.borderColorLight);\n"
847             + "  var node = document.getElementById('tabd4');\n"
848             + "  log(node.borderColorLight);\n"
849 
850             + "</script></body></html>";
851 
852         loadPageVerifyTitle2(html);
853     }
854 
855     /**
856      * @throws Exception if the test fails
857      */
858     @Test
859     @Alerts({"true", "true", "false", "false"})
860     public void offsetHeightParentHidden() throws Exception {
861         final String html = DOCTYPE_HTML
862             + "<html>\n"
863             + "<head>\n"
864             + "  <script>\n"
865             + LOG_TITLE_FUNCTION
866             + "    function test() {\n"
867             + "      var table = document.getElementById('table1');\n"
868             + "      var td = document.getElementById('td1');\n"
869             + "      log(td.offsetWidth != 0);\n"
870             + "      log(td.offsetHeight != 0);\n"
871             + "      td.style.display = 'none';\n"
872             + "      log(td.offsetWidth != 0);\n"
873             + "      log(td.offsetHeight != 0);\n"
874             + "    }\n"
875             + "  </script>\n"
876             + "</head>\n"
877             + "<body onload='test()'>\n"
878             + "  <table id='table1'>\n"
879             + "    <tr><td id='td1'>One</td></tr>\n"
880             + "  </table>\n"
881             + "</body>\n"
882             + "</html>";
883 
884         loadPageVerifyTitle2(html);
885     }
886 
887 }