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.htmlunit.junit.annotation.HtmlUnitNYI;
20  import org.junit.jupiter.api.Test;
21  import org.openqa.selenium.By;
22  import org.openqa.selenium.WebDriver;
23  import org.openqa.selenium.WebElement;
24  import org.openqa.selenium.interactions.Actions;
25  
26  /**
27   * Tests for {@link HTMLElement}.
28   *
29   * @author Ahmed Ashour
30   * @author Marc Guillemot
31   * @author Ronald Brill
32   * @author Frank Danek
33   */
34  public class HTMLElement2Test extends WebDriverTestCase {
35  
36      /**
37       * @throws Exception if the test fails
38       */
39      @Test
40      @Alerts({"undefined", "undefined"})
41      public void scopeName() throws Exception {
42          final String html = DOCTYPE_HTML
43              + "<html><head>\n"
44              + "<script>\n"
45              + LOG_TITLE_FUNCTION
46              + "  function test() {\n"
47              + "    log(document.body.scopeName);\n"
48              + "    log(document.body.tagUrn);\n"
49              + "  }\n"
50              + "</script>\n"
51              + "</head>\n"
52              + "<body onload='test()'>\n"
53              + "</body></html>";
54          loadPageVerifyTitle2(html);
55      }
56  
57      /**
58       * @throws Exception if the test fails
59       */
60      @Test
61      @Alerts({"undefined", "undefined", "undefined", "http://www.meh.com/meh"})
62      public void scopeName2() throws Exception {
63          final String html = "<html xmlns:blah='http://www.blah.com/blah'><head>\n"
64              + "<script>\n"
65              + LOG_TITLE_FUNCTION
66              + "  function test() {\n"
67              + "    var x = document.getElementById('x');\n"
68              + "    log(x.scopeName);\n"
69              + "    log(x.tagUrn);\n"
70              + "    try {\n"
71              + "      x.tagUrn = 'http://www.meh.com/meh';\n"
72              + "      log(x.scopeName);\n"
73              + "      log(x.tagUrn);\n"
74              + "    } catch(e) { logEx(e); }\n"
75              + "  }\n"
76              + "</script>\n"
77              + "</head>\n"
78              + "<body onload='test()'><blah:abc id='x'></blah:abc></body></html>";
79          loadPageVerifyTitle2(html);
80      }
81  
82      /**
83       * Test offsets (real values don't matter currently).
84       *
85       * @throws Exception if the test fails
86       */
87      @Test
88      @Alerts({"number", "number", "number", "number", "number", "number", "number", "number"})
89      public void offsets() throws Exception {
90          final String html = DOCTYPE_HTML
91                + "<html>\n"
92                + "<head></head>\n"
93                + "<body>\n"
94                + "</div></body>\n"
95                + "<div id='div1'>foo</div>\n"
96                + "<script>\n"
97                + LOG_TITLE_FUNCTION
98                + "function alertOffsets(_oElt) {\n"
99                + "  log(typeof _oElt.offsetHeight);\n"
100               + "  log(typeof _oElt.offsetWidth);\n"
101               + "  log(typeof _oElt.offsetLeft);\n"
102               + "  log(typeof _oElt.offsetTop);\n"
103               + "}\n"
104               + "alertOffsets(document.body);\n"
105               + "alertOffsets(document.getElementById('div1'));\n"
106               + "</script></body></html>";
107         loadPageVerifyTitle2(html);
108     }
109 
110     /**
111      * @throws Exception if an error occurs
112      */
113     @Test
114     @Alerts("attachEvent not available")
115     public void offsetWidth_withEvent() throws Exception {
116         final String html = DOCTYPE_HTML
117             + "<html>\n"
118             + "<head>\n"
119             + "<script>\n"
120             + LOG_TITLE_FUNCTION
121             + "  function test() {\n"
122             + "    var myDiv2 = document.getElementById('myDiv2');\n"
123             + "    if(!document.attachEvent) { log('attachEvent not available'); return }\n"
124 
125             + "    myDiv2.attachEvent('ondataavailable', handler);\n"
126             + "    document.attachEvent('ondataavailable', handler);\n"
127             + "    var m = document.createEventObject();\n"
128             + "    m.eventType = 'ondataavailable';\n"
129             + "    myDiv2.fireEvent(m.eventType, m);\n"
130             + "    document.fireEvent(m.eventType, m);\n"
131             + "  }\n"
132             + "  function handler() {\n"
133             + "    var e = document.getElementById('myDiv');\n"
134             + "    e.style.width = 30;\n"
135             + "    log(e.offsetWidth);\n"
136             + "  }\n"
137             + "</script>\n"
138             + "</head>\n"
139             + "<body onload='test()'>\n"
140             + "  <div id='myDiv'></div>\n"
141             + "  <div id='myDiv2'></div>\n"
142             + "</body></html>";
143         loadPageVerifyTitle2(html);
144     }
145 
146     /**
147      * @throws Exception if an error occurs
148      */
149     @Test
150     @Alerts({"true", "true"})
151     public void offsetWidth_spanWithDifferentFontSize() throws Exception {
152         final String html = DOCTYPE_HTML
153             + "<html>\n"
154             + "<head>\n"
155             + "<script>\n"
156             + LOG_TITLE_FUNCTION
157             + "  function test() {\n"
158             + "    var myDefault = document.getElementById('myDefault');\n"
159             + "    var myLarge = document.getElementById('myLarge');\n"
160 
161             + "    log(myDefault.offsetWidth > 20);\n"
162             + "    log(myLarge.offsetWidth > myDefault.offsetWidth);\n"
163             + "  }\n"
164             + "</script>\n"
165             + "</head>\n"
166             + "<body onload='test()'>\n"
167             + "  <span id='myDefault'>1234567890</span>\n"
168             + "  <span id='myLarge' style='font-size: 10em'>1234567890</span>\n"
169             + "</body></html>";
170         loadPageVerifyTitle2(html);
171     }
172 
173     /**
174      * @throws Exception if an error occurs
175      */
176     @Test
177     @Alerts({"true", "true"})
178     @HtmlUnitNYI(CHROME = {"true", "false"},
179             EDGE = {"true", "false"},
180             FF = {"true", "false"},
181             FF_ESR = {"true", "false"})
182     public void offsetWidth_spanWithDifferentFonts() throws Exception {
183         final String html = DOCTYPE_HTML
184             + "<html>\n"
185             + "<head>\n"
186             + "<script>\n"
187             + LOG_TITLE_FUNCTION
188             + "  function test() {\n"
189             + "    var mySerif = document.getElementById('mySerif');\n"
190             + "    var mySans = document.getElementById('mySans');\n"
191 
192             + "    log(mySerif.offsetWidth > 20);\n"
193             + "    log(mySans.offsetWidth > mySerif.offsetWidth);\n"
194             + "  }\n"
195             + "</script>\n"
196             + "</head>\n"
197             + "<body onload='test()'>\n"
198             + "  <span id='mySerif' style='font-family: serif'>1234567890</span>\n"
199             + "  <span id='mySans' style='font-family: sans-serif'>1234567890</span>\n"
200             + "</body></html>";
201         loadPageVerifyTitle2(html);
202     }
203 
204     /**
205      * @throws Exception if an error occurs
206      */
207     @Test
208     @Alerts({"15", "15"})
209     public void offsetTopAndLeft_Padding() throws Exception {
210         final String html = DOCTYPE_HTML
211             + "<html>\n"
212             + "  <head>\n"
213             + "    <script>\n"
214             + LOG_TITLE_FUNCTION
215             + "      function test() {\n"
216             + "        var e = document.getElementById('d');\n"
217             + "        log(e.offsetTop);\n"
218             + "        log(e.offsetLeft);\n"
219             + "      }\n"
220             + "    </script>\n"
221             + "  </head>\n"
222             + "  <body onload='test()' style='padding: 3px; margin: 0px; border: 0px solid green;'>\n"
223             + "    <div style='padding: 5px; margin: 0px; border: 0px solid blue;'>\n"
224             + "      <div style='padding: 7px; margin: 0px; border: 0px solid red;'>\n"
225             + "        <div id='d' style='padding: 13px; margin: 0px; border: 0px solid black;'>d</div>\n"
226             + "      </div>\n"
227             + "    </div>\n"
228             + "  </body>\n"
229             + "</html>";
230         loadPageVerifyTitle2(html);
231     }
232 
233     /**
234      * @throws Exception if an error occurs
235      */
236     @Test
237     @Alerts({"13", "28"})
238     public void offsetTopAndLeft_Margins() throws Exception {
239         final String html = DOCTYPE_HTML
240             + "<html>\n"
241             + "  <head>\n"
242             + "    <script>\n"
243             + LOG_TITLE_FUNCTION
244             + "      function test() {\n"
245             + "        var e = document.getElementById('d');\n"
246             + "        log(e.offsetTop);\n"
247             + "        log(e.offsetLeft);\n"
248             + "      }\n"
249             + "    </script>\n"
250             + "  </head>\n"
251             + "  <body onload='test()' style='padding: 0px; margin: 3px; border: 0px solid green;'>\n"
252             + "    <div style='padding: 0px; margin: 5px; border: 0px solid blue;'>\n"
253             + "      <div style='padding: 0px; margin: 7px; border: 0px solid red;'>\n"
254             + "        <div id='d' style='padding: 0px; margin: 13px; border: 0px solid black;'>d</div>\n"
255             + "      </div>\n"
256             + "    </div>\n"
257             + "  </body>\n"
258             + "</html>";
259         loadPageVerifyTitle2(html);
260     }
261 
262     /**
263      * @throws Exception if an error occurs
264      */
265     @Test
266     @Alerts(DEFAULT = {"15", "15"},
267             FF = {"12", "12"},
268             FF_ESR = {"12", "12"})
269     @HtmlUnitNYI(CHROME = {"12", "12"},
270             EDGE = {"12", "12"})
271     public void offsetTopAndLeft_Borders() throws Exception {
272         final String html = DOCTYPE_HTML
273             + "<html>\n"
274             + "  <head>\n"
275             + "    <script>\n"
276             + LOG_TITLE_FUNCTION
277             + "      function test() {\n"
278             + "        var e = document.getElementById('d');\n"
279             + "        log(e.offsetTop);\n"
280             + "        log(e.offsetLeft);\n"
281             + "      }\n"
282             + "    </script>\n"
283             + "  </head>\n"
284             + "  <body onload='test()' style='padding: 0px; margin: 0px; border: 3px solid green;'>\n"
285             + "    <div style='padding: 0px; margin: 0px; border: 5px solid blue;'>\n"
286             + "      <div style='padding: 0px; margin: 0px; border: 7px solid red;'>\n"
287             + "        <div id='d' style='padding: 0px; margin: 0px; border: 13px solid black;'>d</div>\n"
288             + "      </div>\n"
289             + "    </div>\n"
290             + "  </body>\n"
291             + "</html>";
292         loadPageVerifyTitle2(html);
293     }
294 
295     /**
296      * @throws Exception if an error occurs
297      */
298     @Test
299     @Alerts({"0", "0"})
300     public void offsetTopAndLeft_Nothing() throws Exception {
301         final String html = DOCTYPE_HTML
302             + "<html>\n"
303             + "  <head>\n"
304             + "    <script>\n"
305             + LOG_TITLE_FUNCTION
306             + "      function test() {\n"
307             + "        var e = document.getElementById('d');\n"
308             + "        log(e.offsetTop);\n"
309             + "        log(e.offsetLeft);\n"
310             + "      }\n"
311             + "    </script>\n"
312             + "  </head>\n"
313             + "  <body onload='test()' style='padding: 0px; margin: 0px; border: 0px solid green;'>\n"
314             + "    <div style='padding: 0px; margin: 0px; border: 0px solid blue;'>\n"
315             + "      <div style='padding: 0px; margin: 0px; border: 0px solid red;'>\n"
316             + "        <div id='d' style='padding: 0px; margin: 0px; border: 0px solid black;'>d</div>\n"
317             + "      </div>\n"
318             + "    </div>\n"
319             + "  </body>\n"
320             + "</html>";
321         loadPageVerifyTitle2(html);
322     }
323 
324     /**
325      * @throws Exception if an error occurs
326      */
327     @Test
328     @Alerts({"50", "50"})
329     public void offsetTopAndLeft_AbsolutelyPositioned() throws Exception {
330         final String html = DOCTYPE_HTML
331             + "<html>\n"
332             + "  <head>\n"
333             + "    <script>\n"
334             + LOG_TITLE_FUNCTION
335             + "      function test() {\n"
336             + "        var e = document.getElementById('d');\n"
337             + "        log(e.offsetTop);\n"
338             + "        log(e.offsetLeft);\n"
339             + "      }\n"
340             + "    </script>\n"
341             + "  </head>\n"
342             + "  <body onload='test()'>\n"
343             + "    <div>\n"
344             + "      <div>\n"
345             + "        <div id='d' style='position:absolute; top:50px; left:50px;'>d</div>\n"
346             + "      </div>\n"
347             + "    </div>\n"
348             + "  </body>\n"
349             + "</html>";
350         loadPageVerifyTitle2(html);
351     }
352 
353     /**
354      * @throws Exception if an error occurs
355      */
356     @Test
357     @Alerts({"8", "8"})
358     // so far we still support the quirks behaviour
359     @HtmlUnitNYI(CHROME = {"50", "50"},
360             EDGE = {"50", "50"},
361             FF = {"50", "50"},
362             FF_ESR = {"50", "50"})
363     public void offsetTopAndLeft_AbsolutelyPositionedValueWithoutUnit() throws Exception {
364         final String html = DOCTYPE_HTML
365             + "<html>\n"
366             + "  <head>\n"
367             + "    <script>\n"
368             + LOG_TITLE_FUNCTION
369             + "      function test() {\n"
370             + "        var e = document.getElementById('d');\n"
371             + "        log(e.offsetTop);\n"
372             + "        log(e.offsetLeft);\n"
373             + "      }\n"
374             + "    </script>\n"
375             + "  </head>\n"
376             + "  <body onload='test()'>\n"
377             + "    <div>\n"
378             + "      <div>\n"
379             + "        <div id='d' style='position:absolute; top:50; left:50;'>d</div>\n"
380             + "      </div>\n"
381             + "    </div>\n"
382             + "  </body>\n"
383             + "</html>";
384         loadPageVerifyTitle2(html);
385     }
386 
387     /**
388      * @throws Exception if an error occurs
389      */
390     @Test
391     @Alerts({"1 absolute_auto 0", "2 absolute_length 50", "3 absolute_inherit 10", "4 fixed_auto 10",
392                 "5 fixed_length 50", "6 fixed_inherit 10", "7 relative_auto 0", "8 relative_length 50",
393                 "9 relative_inherit 10", "10 static_auto 0", "11 static_length 0", "12 static_inherit 0",
394                 "13 inherit_auto 0", "14 inherit_length 50", "15 inherit_inherit 10"})
395     public void offsetLeft_PositionLeft_DifferentCombinations() throws Exception {
396         final String html = DOCTYPE_HTML
397             + "<html><body onload='test()'><script language='javascript'>\n"
398             + LOG_TITLE_FUNCTION
399             + "String.prototype.trim = function() {\n"
400             + "  return this.replace(/^\\s+|\\s+$/g, '');\n"
401             + "}\n"
402             + "function test() {\n"
403             + "  var output = document.getElementById('output');\n"
404             + "  output.value = '';\n"
405             + "  var children = document.getElementById('container').childNodes;\n"
406             + "  for(var i = 0; i < children.length; i++) {\n"
407             + "    var c = children[i];\n"
408             + "    if(c.tagName) output.value += (c.innerHTML + ' ' + c.id + ' ' + c.offsetLeft + '\\n');\n"
409             + "  }\n"
410             + "  var alerts = output.value.split('\\n');\n"
411             + "  for(var i = 0; i < alerts.length; i++) {\n"
412             + "    var s = alerts[i].trim();\n"
413             + "    if(s) log(s);\n"
414             + "  }\n"
415             + "}\n"
416             + "</script>\n"
417             + "<textarea id='output' cols='40' rows='20'></textarea>\n"
418             + "<div id='container' style='position: absolute; left: 10px;'>\n"
419             + "  <div id='absolute_auto' style='position: absolute; left: auto;'>1</div>\n"
420             + "  <div id='absolute_length' style='position: absolute; left: 50px;'>2</div>\n"
421             + "  <div id='absolute_inherit' style='position: absolute; left: inherit;'>3</div>\n"
422             + "  <div id='fixed_auto' style='position: fixed; left: auto;'>4</div>\n"
423             + "  <div id='fixed_length' style='position: fixed; left: 50px;'>5</div>\n"
424             + "  <div id='fixed_inherit' style='position: fixed; left: inherit;'>6</div>\n"
425             + "  <div id='relative_auto' style='position: relative; left: auto;'>7</div>\n"
426             + "  <div id='relative_length' style='position: relative; left: 50px;'>8</div>\n"
427             + "  <div id='relative_inherit' style='position: relative; left: inherit;'>9</div>\n"
428             + "  <div id='static_auto' style='position: static; left: auto;'>10</div>\n"
429             + "  <div id='static_length' style='position: static; left: 50px;'>11</div>\n"
430             + "  <div id='static_inherit' style='position: static; left: inherit;'>12</div>\n"
431             + "  <div id='inherit_auto' style='position: inherit; left: auto;'>13</div>\n"
432             + "  <div id='inherit_length' style='position: inherit; left: 50px;'>14</div>v>\n"
433             + "  <div id='inherit_inherit' style='position: inherit; left: inherit;'>15</div>\n"
434             + "</div>\n"
435             + "</body></html>";
436         loadPageVerifyTitle2(html);
437     }
438 
439     /**
440      * @throws Exception if an error occurs
441      */
442     @Test
443     @Alerts({"40", "10"})
444     public void offsetTopAndLeft_parentAbsolute() throws Exception {
445         final String html = DOCTYPE_HTML
446             + "<html>\n"
447             + "<head>\n"
448             + "<script>\n"
449             + LOG_TITLE_FUNCTION
450             + "  function test() {\n"
451             + "    var e = document.getElementById('innerDiv');\n"
452             + "    log(e.offsetLeft);\n"
453             + "    log(e.offsetTop);\n"
454             + "  }\n"
455             + "</script>\n"
456             + "</head>\n"
457             + "<body onload='test()'>\n"
458             + "<div id='styleTest' style='position: absolute; left: 400px; top: 50px; padding: 10px 20px 30px 40px;'>\n"
459             + "<div id='innerDiv'></div>TEST</div>\n"
460             + "</body></html>";
461         loadPageVerifyTitle2(html);
462     }
463 
464     /**
465      * @throws Exception if an error occurs
466      */
467     @Test
468     @Alerts({"400", "50"})
469     public void offsetTopAndLeft_Fixed() throws Exception {
470         final String html = DOCTYPE_HTML
471             + "<html>\n"
472             + "<head>\n"
473             + "<script>\n"
474             + LOG_TITLE_FUNCTION
475             + "  function test() {\n"
476             + "    var e = document.getElementById('innerDiv');\n"
477             + "    log(e.offsetLeft);\n"
478             + "    log(e.offsetTop);\n"
479             + "  }\n"
480             + "</script>\n"
481             + "</head>\n"
482             + "<body onload='test()'>\n"
483             + "<div id='innerDiv' style='position: fixed; left: 400px; top: 50px;'></div>TEST</div>\n"
484             + "</body></html>";
485         loadPageVerifyTitle2(html);
486     }
487 
488     /**
489      * Minimal flow/layouting test: verifies that the <tt>offsetTop</tt> property changes depending
490      * on previous siblings. In the example below, the second div is below the first one, so its
491      * offsetTop must be greater than zero. This sort of test is part of the Dojo unit tests, so
492      * this needs to pass for the Dojo unit tests to pass.
493      *
494      * @throws Exception if an error occurs
495      */
496     @Test
497     @Alerts({"true", "true", "2", "3", "4", "5", "6", "7", "8", "9", "99", "199", "5999"})
498     public void offsetTopWithPreviousSiblings() throws Exception {
499         String html = DOCTYPE_HTML
500             + "<html><head>\n"
501             + "<script>\n"
502             + LOG_TITLE_FUNCTION
503             + "  function test() {\n"
504             + "    log(document.getElementById('d1').offsetTop == 0);\n"
505             + "    var d2OffsetTop = document.getElementById('d2').offsetTop;\n"
506             + "    log(d2OffsetTop > 0);\n"
507 
508             + "    log(document.getElementById('d3').offsetTop/d2OffsetTop);\n"
509             + "    log(document.getElementById('d4').offsetTop/d2OffsetTop);\n"
510             + "    log(document.getElementById('d5').offsetTop/d2OffsetTop);\n"
511             + "    log(document.getElementById('d6').offsetTop/d2OffsetTop);\n"
512             + "    log(document.getElementById('d7').offsetTop/d2OffsetTop);\n"
513             + "    log(document.getElementById('d8').offsetTop/d2OffsetTop);\n"
514             + "    log(document.getElementById('d9').offsetTop/d2OffsetTop);\n"
515             + "    log(document.getElementById('d10').offsetTop/d2OffsetTop);\n"
516 
517             + "    log(document.getElementById('d100').offsetTop/d2OffsetTop);\n"
518             + "    log(document.getElementById('d200').offsetTop/d2OffsetTop);\n"
519 
520             + "    log(document.getElementById('d6000').offsetTop/d2OffsetTop);\n"
521             + "  }\n"
522             + "</script>\n"
523             + "</head>\n"
524             + "<body style='padding: 0px; margin: 0px;' onload='test()'>\n";
525         for (int i = 1; i <= 6000; i++) {
526             html += "  <div id='d" + i + "'>bar</div>\n";
527         }
528         html = html
529             + "</body>\n"
530             + "</html>";
531         loadPageVerifyTitle2(html);
532     }
533 
534     /**
535      * Partial regression test for Bug #968.
536      * @throws Exception if an error occurs
537      */
538     @Test
539     @Alerts({"8", "8"})
540     public void offsetTopAndLeftWhenParentIsBody() throws Exception {
541         final String html = DOCTYPE_HTML
542             + "<html><head>\n"
543             + "<script>\n"
544             + LOG_TITLE_FUNCTION
545             + "  function test() {\n"
546             + "    var d = document.getElementById('d');\n"
547             + "    log(d.offsetLeft);\n"
548             + "    log(d.offsetTop);\n"
549             + "  }\n"
550             + "</script>\n"
551             + "</head>\n"
552             + "  <body onload='test()'>\n"
553             + "    <div id='d'>foo</div>\n"
554             + "  </body>\n"
555             + "</html>";
556         loadPageVerifyTitle2(html);
557     }
558 
559     /**
560      * Regression test for Bug #999.
561      * @throws Exception if an error occurs
562      */
563     @Test
564     @Alerts({"23", "19"})
565     public void offsetTopAndLeftWithRelativePosition() throws Exception {
566         final String html = DOCTYPE_HTML
567             + "<html><body onload='test()'><script language='javascript'>\n"
568             + LOG_TITLE_FUNCTION
569             + "  function test() {\n"
570             + "    var inner = document.createElement('div');\n"
571             + "    var outer = document.createElement('div');\n"
572             + "    \n"
573             + "    document.body.appendChild(outer);\n"
574             + "    outer.appendChild(inner);\n"
575             + "    \n"
576             + "    outer.style.position = 'absolute';\n"
577             + "    inner.style.position = 'relative';\n"
578             + "    inner.style.left = '19.0px';\n"
579             + "    inner.style.top = '23.0px';\n"
580             + "    \n"
581             + "    log(inner.offsetTop);\n"
582             + "    log(inner.offsetLeft);\n"
583             + "  }\n"
584             + "</script></body></html>";
585         loadPageVerifyTitle2(html);
586     }
587 
588     /**
589      * @throws Exception if an error occurs
590      */
591     @Test
592     @Alerts(DEFAULT = {"", "1240", "", "34", "34", "0", "0", "0", "0"},
593             EDGE = {"", "1232", "", "34", "34", "0", "0", "0", "0"})
594     @HtmlUnitNYI(EDGE = {"", "1240", "", "34", "34", "0", "0", "0", "0"})
595     public void offsetWidthAndHeight() throws Exception {
596         final String html = DOCTYPE_HTML
597             + "<html><head>\n"
598             + "<style>\n"
599             + ".dontDisplay { display: none }\n"
600             + ".hideMe { visibility: hidden }\n"
601             + "</style>\n"
602             + "<script>\n"
603             + LOG_TITLE_FUNCTION
604             + "  function test() {\n"
605             + "    var e = document.getElementById('myDiv');\n"
606             + "    e.style.width = 30;\n"
607             + "    log(e.style.width);\n"
608             + "    log(e.offsetWidth);\n"
609             + "    e.style.height = 55;\n"
610             + "    log(e.style.height);\n"
611             + "    log(e.offsetHeight);\n"
612             + "    e.className = 'hideMe';\n"
613             + "    log(e.offsetHeight);\n"
614             + "    e.className = 'dontDisplay';\n"
615             + "    log(e.offsetHeight);\n"
616             + "    log(e.offsetWidth);\n"
617             + "    var nested = document.getElementById('nested');\n"
618             + "    log(nested.offsetHeight);\n"
619             + "    log(nested.offsetWidth);\n"
620             + "  }\n"
621             + "</script>\n"
622             + "</head>\n"
623             + "<body onload='test()'>\n"
624             + "  <div id='myDiv' style='border: 3px solid #fff; padding: 5px;'><div id='nested'>hello</div></div>\n"
625             + "</body></html>";
626         loadPageVerifyTitle2(html);
627     }
628 
629     /**
630      * Regression test for Bug #1037.
631      * @throws Exception if an error occurs
632      */
633     @Test
634     @Alerts({"0", "0"})
635     public void offsetWidthAndHeight_displayNoneAndChildren() throws Exception {
636         final String html = DOCTYPE_HTML
637             + "<html><body>\n"
638             + "<div id='div' style='display: none;'><div style='width: 20px; height: 30px;'></div></div>\n"
639             + "<script>\n"
640             + LOG_TITLE_FUNCTION
641             + "log(document.getElementById('div').offsetWidth);</script>\n"
642             + "<script>log(document.getElementById('div').offsetHeight);</script>\n"
643             + "</body></html>";
644         loadPageVerifyTitle2(html);
645     }
646 
647     /**
648      * Regression test for Bug #1290.
649      * @throws Exception if an error occurs
650      */
651     @Test
652     @Alerts({"0", "18"})
653     public void offsetHeight_explicitHeightZero() throws Exception {
654         final String html = DOCTYPE_HTML
655             + "<html><body>\n"
656             + "<div id='d1' style='height: 0px;'><div id='d2'>x</div></div>\n"
657             + "<script>\n"
658             + LOG_TITLE_FUNCTION
659             + "log(document.getElementById('d1').offsetHeight);</script>\n"
660             + "<script>log(document.getElementById('d2').offsetHeight);</script>\n"
661             + "</body></html>";
662         loadPageVerifyTitle2(html);
663     }
664 
665     /**
666      * Partial regression test for Bug #968.
667      * @throws Exception if an error occurs
668      */
669     @Test
670     @Alerts({"75", "2", "5", "20", "50", "50", "18"})
671     public void offsetHeight_calculatedBasedOnChildren() throws Exception {
672         final String html = DOCTYPE_HTML
673             + "<html>\n"
674             + "  <body onload='h(\"d1\"); h(\"d2\"); h(\"d3\"); h(\"d4\"); h(\"d5\"); h(\"d6\"); h(\"d7\");'>\n"
675             + "    <div id='d1'>\n"
676             + "      <div id='d2' style='height:2px;'>x</div>\n"
677             + "      <div id='d3' style='height:5px;'><div id='d4' style='height:20px;'>x</div></div>\n"
678             + "      <div id='d5'><div id='d6' style='height:50px;'>x</div></div>\n"
679             + "      <div id='d7'>x</div>\n"
680             + "    </div>\n"
681             + "    <script>\n"
682             + LOG_TITLE_FUNCTION
683             + "function h(id) { log(document.getElementById(id).offsetHeight); }</script>\n"
684             + "  </body>\n"
685             + "</html>";
686         loadPageVerifyTitle2(html);
687     }
688 
689     /**
690      * @throws Exception if an error occurs
691      */
692     @Test
693     @Alerts({"true", "true"})
694     public void offsetHeight_takeFontSizeIntoAccount() throws Exception {
695         final String html = DOCTYPE_HTML
696                 + "<html><head>\n"
697                 + "<script>\n"
698                 + LOG_TITLE_FUNCTION
699                 + "  function test() {\n"
700                 + "    var elem = document.getElementById('myTestDiv');\n"
701                 + "    var initial = elem.offsetHeight;\n"
702                 + "    log(initial > 10);\n"
703                 + "    elem.style.fontSize = '42px';\n"
704                 + "    log(elem.offsetHeight > initial);\n"
705                 + "  }\n"
706                 + "</script>\n"
707                 + "</head>\n"
708                 + "<body onload='test()'>\n"
709                 + "  <div id='myTestDiv'>something</div>\n"
710                 + "</body></html>";
711 
712         loadPageVerifyTitle2(html);
713     }
714 
715     /**
716      * Value of offsetWidth is currently wrong when width is a % of the page.
717      * @throws Exception if an error occurs
718      */
719     @Test
720     @Alerts({"true", "true"})
721     public void offsetWidth_calculatedBasedOnPage() throws Exception {
722         final String html = DOCTYPE_HTML
723             + "<html><body>\n"
724             + "<div id='d1' style='width: 20%'>hello</div>\n"
725             + "<div><div id='d2' style='width: 20%'>hello</div></div>\n"
726             + "<script>\n"
727             + LOG_TITLE_FUNCTION
728             + "log(document.getElementById('d1').offsetWidth > 0);\n"
729             + "log(document.getElementById('d2').offsetWidth > 0);\n"
730             + "</script></body>\n"
731             + "</html>";
732         loadPageVerifyTitle2(html);
733     }
734 
735     /**
736      * @throws Exception if an error occurs
737      */
738     @Test
739     @Alerts("30")
740     public void offsetWidth_parentWidthConstrainsChildWidth() throws Exception {
741         final String html = DOCTYPE_HTML
742             + "<html>\n"
743             + "<head>\n"
744             + "  <style>#a { width: 30px; }</style>\n"
745             + "</head>\n"
746             + "<body>\n"
747             + "<div id='a'><div id='b'>foo</div></div>\n"
748             + "<script>\n"
749             + LOG_TITLE_FUNCTION
750             + "log(document.getElementById('b').offsetWidth);</script>\n"
751             + "</body>\n"
752             + "</html>";
753         loadPageVerifyTitle2(html);
754     }
755 
756     /**
757      * @throws Exception if an error occurs
758      */
759     @Test
760     @Alerts("30")
761     public void offsetWidth_parentWidthConstrainsChildWidth2() throws Exception {
762         final String html = DOCTYPE_HTML
763             + "<html>\n"
764             + "<head>\n"
765             + "  <style>#a{width:30px;} #b{border:2px;padding:3px;}</style>\n"
766             + "</head>\n"
767             + "<body>\n"
768             + "<div id='a'><div id='b'>foo</div></div>\n"
769             + "<script>\n"
770             + LOG_TITLE_FUNCTION
771             + "log(document.getElementById('b').offsetWidth);</script>\n"
772             + "</body>\n"
773             + "</html>";
774         loadPageVerifyTitle2(html);
775     }
776 
777     /**
778      * When CSS float is set to "right" or "left", the width of an element is related to
779      * its content and it doesn't takes the full available width.
780      * @throws Exception if an error occurs
781      */
782     @Test
783     @Alerts({"1", "0.5", "true"})
784     public void offsetWidth_cssFloat_rightOrLeft() throws Exception {
785         final String html = DOCTYPE_HTML
786             + "<html>\n"
787             + "<head></head>\n"
788             + "<body>\n"
789             + "<div id='withoutFloat1'>hello</div><div>hellohello</div>\n"
790             + "<div id='withFloat1' style='float: left'>hello</div><div style='float: left'>hellohello</div>\n"
791             + "<script>\n"
792             + LOG_TITLE_FUNCTION
793             + "var eltWithoutFloat1 = document.getElementById('withoutFloat1');\n"
794             + "log(eltWithoutFloat1.offsetWidth / eltWithoutFloat1.nextSibling.offsetWidth);\n"
795             + "var eltWithFloat1 = document.getElementById('withFloat1');\n"
796             + "log(eltWithFloat1.offsetWidth / eltWithFloat1.nextSibling.offsetWidth);\n"
797             // we don't make any strong assumption on the screen size here,
798             // but expect it to be big enough to show 10 times "hello" on one line
799             + "log(eltWithoutFloat1.offsetWidth > 10 * eltWithFloat1.offsetWidth);\n"
800             + "</script>\n"
801             + "</body>\n"
802             + "</html>";
803         loadPageVerifyTitle2(html);
804     }
805 
806     /**
807      * @throws Exception if an error occurs
808      */
809     @Test
810     @Alerts({"true", "true", "true"})
811     public void offsetWidth_takeContentIntoAccount() throws Exception {
812         final String html = DOCTYPE_HTML
813                 + "<html><head>\n"
814                 + "<script>\n"
815                 + LOG_TITLE_FUNCTION
816                 + "  function test() {\n"
817                 + "    var elem1 = document.getElementById('myTest1');\n"
818                 + "    var elem2 = document.getElementById('myTest2');\n"
819                 + "    var elem3 = document.getElementById('myTest3');\n"
820                 + "    log(elem1.offsetWidth == 0);\n"
821                 + "    log(elem1.offsetWidth < elem2.offsetWidth);\n"
822                 + "    log(elem2.offsetWidth < elem3.offsetWidth);\n"
823                 + "  }\n"
824                 + "</script>\n"
825                 + "</head>\n"
826                 + "<body onload='test()'>\n"
827                 + "  <span id='myTest1'></span>\n"
828                 + "  <span id='myTest2'>short</span>\n"
829                 + "  <span id='myTest3'>loooooooooong</span>\n"
830                 + "</body></html>";
831 
832         loadPageVerifyTitle2(html);
833     }
834 
835     /**
836      * @throws Exception if an error occurs
837      */
838     @Test
839     @Alerts({"true", "true"})
840     public void offsetWidth_takeFontSizeIntoAccount() throws Exception {
841         final String html = DOCTYPE_HTML
842                 + "<html><head>\n"
843                 + "<script>\n"
844                 + LOG_TITLE_FUNCTION
845                 + "  function test() {\n"
846                 + "    var elem = document.getElementById('myTestDiv');\n"
847                 + "    var initial = elem.offsetWidth;\n"
848                 + "    log(initial > 10);\n"
849                 + "    elem.style.fontSize = '42px';\n"
850                 + "    log(elem.offsetWidth > initial);\n"
851                 + "  }\n"
852                 + "</script>\n"
853                 + "</head>\n"
854                 + "<body onload='test()'>\n"
855                 + "  <span id='myTestDiv'>something</span>\n"
856                 + "</body></html>";
857 
858         loadPageVerifyTitle2(html);
859     }
860 
861     /**
862      * @throws Exception if the test fails
863      */
864     @Test
865     @Alerts({"something", "0"})
866     public void textContent_null() throws Exception {
867         final String html = DOCTYPE_HTML
868             + "<html><head>\n"
869             + "<script>\n"
870             + LOG_TITLE_FUNCTION
871             + "  function test() {\n"
872             + "    checkChildren();\n"
873             + "    myTestDiv.textContent = null;\n"
874             + "    checkChildren();\n"
875             + "  }\n"
876             + "  function checkChildren() {\n"
877             + "    if (myTestDiv.childNodes.length == 0)\n"
878             + "      log('0');\n"
879             + "    else\n"
880             + "      log(myTestDiv.childNodes.item(0).data);\n"
881             + "  }\n"
882             + "</script>\n"
883             + "</head>\n"
884             + "<body onload='test()'>\n"
885             + "  <div id='myTestDiv'>something</div>\n"
886             + "</body></html>";
887 
888         loadPageVerifyTitle2(html);
889     }
890 
891     /**
892      * @throws Exception if the test fails
893      */
894     @Test
895     @Alerts({"something", "0"})
896     public void textContent_emptyString() throws Exception {
897         final String html = DOCTYPE_HTML
898             + "<html><head>\n"
899             + "<script>\n"
900             + LOG_TITLE_FUNCTION
901             + "  function test() {\n"
902             + "    checkChildren();\n"
903             + "    myTestDiv.textContent = '';\n"
904             + "    checkChildren();\n"
905             + "  }\n"
906             + "  function checkChildren() {\n"
907             + "    if (myTestDiv.childNodes.length == 0)\n"
908             + "      log('0');\n"
909             + "    else\n"
910             + "      log(myTestDiv.childNodes.item(0).data);\n"
911             + "  }\n"
912             + "</script>\n"
913             + "</head>\n"
914             + "<body onload='test()'>\n"
915             + "  <div id='myTestDiv'>something</div>\n"
916             + "</body></html>";
917 
918         loadPageVerifyTitle2(html);
919     }
920 
921     /**
922      * @throws Exception if the test fails
923      */
924     @Test
925     @Alerts({"something", "Hello World"})
926     public void innerText() throws Exception {
927         final String html = DOCTYPE_HTML
928             + "<html><head>\n"
929             + "<script>\n"
930             + LOG_TITLE_FUNCTION
931             + "  function test() {\n"
932             + "    checkChildren();\n"
933             + "    myTestDiv.innerText = 'Hello World';\n"
934             + "    checkChildren();\n"
935             + "  }\n"
936             + "  function checkChildren() {\n"
937             + "    if (myTestDiv.childNodes.length == 0)\n"
938             + "      log('0');\n"
939             + "    else\n"
940             + "      log(myTestDiv.childNodes.item(0).data);\n"
941             + "  }\n"
942             + "</script>\n"
943             + "</head>\n"
944             + "<body onload='test()'>\n"
945             + "  <div id='myTestDiv'>something</div>\n"
946             + "</body></html>";
947 
948         loadPageVerifyTitle2(html);
949     }
950 
951     /**
952      * @throws Exception if the test fails
953      */
954     @Test
955     @Alerts({"something", "3", "Hello", "[object HTMLBRElement]", "World"})
956     public void innerText_LineBreak() throws Exception {
957         final String html = DOCTYPE_HTML
958             + "<html><head>\n"
959             + "<script>\n"
960             + LOG_TITLE_FUNCTION
961             + "  function test() {\n"
962             + "    log(myTestDiv.childNodes.item(0).data);\n"
963 
964             + "    myTestDiv.innerText = 'Hello\\nWorld';\n"
965             + "    log(myTestDiv.childNodes.length);\n"
966             + "    log(myTestDiv.childNodes.item(0).data);\n"
967             + "    log(myTestDiv.childNodes.item(1));\n"
968             + "    log(myTestDiv.childNodes.item(2).data);\n"
969             + "  }\n"
970             + "</script>\n"
971             + "</head>\n"
972             + "<body onload='test()'>\n"
973             + "  <div id='myTestDiv'>something</div>\n"
974             + "</body></html>";
975 
976         loadPageVerifyTitle2(html);
977     }
978 
979 
980     /**
981      * @throws Exception if the test fails
982      */
983     @Test
984     @Alerts({"0", "1", " ", "0", "1", "undefined", "1", "[object Object]"})
985     public void innerText_Empty() throws Exception {
986         final String html = DOCTYPE_HTML
987             + "<html><head>\n"
988             + "<script>\n"
989             + LOG_TITLE_FUNCTION
990             + "  function test() {\n"
991             + "    myTestDiv0.innerText = '';\n"
992             + "    log(myTestDiv0.childNodes.length);\n"
993 
994             + "    myTestDiv1.innerText = ' ';\n"
995             + "    log(myTestDiv1.childNodes.length);\n"
996             + "    log(myTestDiv1.childNodes.item(0).data);\n"
997 
998             + "    myTestDiv2.innerText = null;\n"
999             + "    log(myTestDiv2.childNodes.length);\n"
1000 
1001             + "    myTestDiv3.innerText = undefined;\n"
1002             + "    log(myTestDiv3.childNodes.length);\n"
1003             + "    log(myTestDiv3.childNodes.item(0).data);\n"
1004 
1005             + "    myTestDiv4.innerText = { a: 'b'};\n"
1006             + "    log(myTestDiv4.childNodes.length);\n"
1007             + "    log(myTestDiv4.childNodes.item(0).data);\n"
1008             + "  }\n"
1009             + "</script>\n"
1010             + "</head>\n"
1011             + "<body onload='test()'>\n"
1012             + "  <div id='myTestDiv0'>something</div>\n"
1013             + "  <div id='myTestDiv1'>something</div>\n"
1014             + "  <div id='myTestDiv2'>something</div>\n"
1015             + "  <div id='myTestDiv3'>something</div>\n"
1016             + "  <div id='myTestDiv4'>something</div>\n"
1017             + "</body></html>";
1018 
1019         loadPageVerifyTitle2(html);
1020     }
1021 
1022     /**
1023      * @throws Exception if the test fails
1024      */
1025     @Test
1026     @Alerts({"something", "0"})
1027     public void innerText_null() throws Exception {
1028         final String html = DOCTYPE_HTML
1029             + "<html><head>\n"
1030             + "<script>\n"
1031             + LOG_TITLE_FUNCTION
1032             + "  function test() {\n"
1033             + "    checkChildren();\n"
1034             + "    myTestDiv.innerText = null;\n"
1035             + "    checkChildren();\n"
1036             + "  }\n"
1037             + "  function checkChildren() {\n"
1038             + "    if (myTestDiv.childNodes.length == 0)\n"
1039             + "      log('0');\n"
1040             + "    else\n"
1041             + "      log(myTestDiv.childNodes.item(0).data);\n"
1042             + "  }\n"
1043             + "</script>\n"
1044             + "</head>\n"
1045             + "<body onload='test()'>\n"
1046             + "  <div id='myTestDiv'>something</div>\n"
1047             + "</body></html>";
1048 
1049         loadPageVerifyTitle2(html);
1050     }
1051 
1052     /**
1053      * @throws Exception if the test fails
1054      */
1055     @Test
1056     @Alerts(DEFAULT = {"before\\nsvg-text\\nafter", "before\\nsvg-text\\nafter"},
1057             FF = {"beforesvg-textafter", "beforesvg-textafter"},
1058             FF_ESR = {"beforesvg-textafter", "beforesvg-textafter"})
1059     public void innerText_SVG() throws Exception {
1060         final String html = DOCTYPE_HTML
1061             + "<html><head>\n"
1062             + "<script>\n"
1063             + LOG_TITLE_FUNCTION_NORMALIZE
1064             + "  function test() {\n"
1065             + "    log(myTestDiv.innerText);\n"
1066             + "    log(myTestDiv.outerText);\n"
1067             + "  }\n"
1068             + "</script>\n"
1069             + "</head>\n"
1070             + "<body onload='test()'>abc"
1071             + "<div id='myTestDiv'>before<svg><title>svg-title</title><text>svg-text</text></svg>after</div>def"
1072             + "</body></html>";
1073 
1074         loadPageVerifyTitle2(html);
1075     }
1076 
1077     /**
1078      * @throws Exception if the test fails
1079      */
1080     @Test
1081     @Alerts({"MyTitlevar i;", "MyTitlevar i;"})
1082     public void innerText_Head() throws Exception {
1083         final String html = DOCTYPE_HTML
1084             + "<html><head>"
1085             + "<title>MyTitle</title>"
1086             + "<script>var i;</script>"
1087             + "</head>"
1088             + "<body onload='test()'>\n"
1089             + "<script>\n"
1090             + LOG_TEXTAREA_FUNCTION
1091             + "  function test() {\n"
1092             + "    log(document.head.innerText);\n"
1093             + "    log(document.head.outerText);\n"
1094             + "  }\n"
1095             + "</script>\n"
1096             + LOG_TEXTAREA
1097             + "</body></html>";
1098 
1099         loadPageVerifyTextArea2(html);
1100     }
1101 
1102     /**
1103      * @throws Exception if the test fails
1104      */
1105     @Test
1106     @Alerts({"something", "0"})
1107     public void innerText_emptyString() throws Exception {
1108         final String html = DOCTYPE_HTML
1109             + "<html><head>\n"
1110             + "<script>\n"
1111             + LOG_TITLE_FUNCTION
1112             + "  function test() {\n"
1113             + "    checkChildren();\n"
1114             + "    myTestDiv.innerText = '';\n"
1115             + "    checkChildren();\n"
1116             + "  }\n"
1117             + "  function checkChildren() {\n"
1118             + "    if (myTestDiv.childNodes.length == 0)\n"
1119             + "      log('0');\n"
1120             + "    else\n"
1121             + "      log(myTestDiv.childNodes.item(0).data);\n"
1122             + "  }\n"
1123             + "</script>\n"
1124             + "</head>\n"
1125             + "<body onload='test()'>\n"
1126             + "  <div id='myTestDiv'>something</div>\n"
1127             + "</body></html>";
1128 
1129         loadPageVerifyTitle2(html);
1130     }
1131 
1132     /**
1133      * @throws Exception if the test fails
1134      */
1135     @Test
1136     @Alerts({"something", " "})
1137     public void innerText_blankString() throws Exception {
1138         final String html = DOCTYPE_HTML
1139             + "<html><head>\n"
1140             + "<script>\n"
1141             + LOG_TITLE_FUNCTION
1142             + "  function test() {\n"
1143             + "    checkChildren();\n"
1144             + "    myTestDiv.innerText = '    \t';\n"
1145             + "    checkChildren();\n"
1146             + "  }\n"
1147             + "  function checkChildren() {\n"
1148             + "    if (myTestDiv.childNodes.length == 0)\n"
1149             + "      log('0');\n"
1150             + "    else\n"
1151             + "      log(myTestDiv.childNodes.item(0).data);\n"
1152             + "  }\n"
1153             + "</script>\n"
1154             + "</head>\n"
1155             + "<body onload='test()'>\n"
1156             + "  <div id='myTestDiv'>something</div>\n"
1157             + "</body></html>";
1158 
1159         loadPageVerifyTitle2(html);
1160     }
1161 
1162     /**
1163      * @throws Exception if the test fails
1164      */
1165     @Test
1166     @Alerts({"1", "undefined", "1", "Hello World", "Hello World"})
1167     public void outerText() throws Exception {
1168         final String html = DOCTYPE_HTML
1169             + "<html><head>\n"
1170             + "<script>\n"
1171             + LOG_TITLE_FUNCTION
1172             + "  function test() {\n"
1173             + "    checkChildren();\n"
1174             + "    myTestDiv.outerText = 'Hello World';\n"
1175             + "    checkChildren();\n"
1176             + "    log(myCheckDiv.innerHTML);\n"
1177             + "  }\n"
1178             + "  function checkChildren() {\n"
1179             + "    log(myCheckDiv.childNodes.length);\n"
1180             + "    if (myCheckDiv.childNodes.length > 0)\n"
1181             + "      log(myCheckDiv.childNodes.item(0).data);\n"
1182             + "  }\n"
1183             + "</script>\n"
1184             + "</head>\n"
1185             + "<body onload='test()'>\n"
1186             + "  <div id='myCheckDiv'><div id='myTestDiv'>something</div></div>\n"
1187             + "</body></html>";
1188 
1189         loadPageVerifyTitle2(html);
1190     }
1191 
1192 
1193     /**
1194      * @throws Exception if the test fails
1195      */
1196     @Test
1197     @Alerts({"3", " ", "1", " Hello World ", " Hello World "})
1198     @HtmlUnitNYI(CHROME = {"3", " ", "3", " ", " Hello World "},
1199             EDGE = {"3", " ", "3", " ", " Hello World "},
1200             FF = {"3", " ", "3", " ", " Hello World "},
1201             FF_ESR = {"3", " ", "3", " ", " Hello World "})
1202     public void outerText_removeSurroundings() throws Exception {
1203         final String html = DOCTYPE_HTML
1204             + "<html><head>\n"
1205             + "<script>\n"
1206             + LOG_TITLE_FUNCTION
1207             + "  function test() {\n"
1208             + "    checkChildren();\n"
1209             + "    myTestDiv.outerText = 'Hello World';\n"
1210             + "    checkChildren();\n"
1211             + "    log(myCheckDiv.innerHTML);\n"
1212             + "  }\n"
1213             + "  function checkChildren() {\n"
1214             + "    log(myCheckDiv.childNodes.length);\n"
1215             + "    if (myCheckDiv.childNodes.length > 0)\n"
1216             + "      log(myCheckDiv.childNodes.item(0).data);\n"
1217             + "  }\n"
1218             + "</script>\n"
1219             + "</head>\n"
1220             + "<body onload='test()'>\n"
1221             + "  <div id='myCheckDiv'>  <div id='myTestDiv'>something</div>\n</div>\n"
1222             + "</body></html>";
1223 
1224         loadPageVerifyTitle2(html);
1225     }
1226 
1227     /**
1228      * @throws Exception if the test fails
1229      */
1230     @Test
1231     @Alerts({"something", "3", "Hello", "[object HTMLBRElement]", "World",
1232              "Hello<br>World"})
1233     public void outerText_LineBreak() throws Exception {
1234         final String html = DOCTYPE_HTML
1235             + "<html><head>\n"
1236             + "<script>\n"
1237             + LOG_TITLE_FUNCTION
1238             + "  function test() {\n"
1239             + "    log(myTestDiv.childNodes.item(0).data);\n"
1240 
1241             + "    myTestDiv.outerText = 'Hello\\nWorld';\n"
1242             + "    log(myCheckDiv.childNodes.length);\n"
1243             + "    log(myCheckDiv.childNodes.item(0).data);\n"
1244             + "    log(myCheckDiv.childNodes.item(1));\n"
1245             + "    log(myCheckDiv.childNodes.item(2).data);\n"
1246 
1247             + "    log(myCheckDiv.innerHTML);\n"
1248             + "  }\n"
1249             + "</script>\n"
1250             + "</head>\n"
1251             + "<body onload='test()'>\n"
1252             + "  <div id='myCheckDiv'><div id='myTestDiv'>something</div></div>\n"
1253             + "</body></html>";
1254 
1255         loadPageVerifyTitle2(html);
1256     }
1257 
1258 
1259     /**
1260      * @throws Exception if the test fails
1261      */
1262     @Test
1263     @Alerts({"11", "3", " ", "[object HTMLDivElement]", " undefined [object Object] ",
1264              " <div id=\"myTestDiv0\"></div> undefined [object Object] "})
1265     @HtmlUnitNYI(CHROME = {"11", "11", " ", "[object HTMLDivElement]", " ",
1266                            " <div id=\"myTestDiv0\"></div> undefined [object Object] "},
1267             EDGE = {"11", "11", " ", "[object HTMLDivElement]", " ",
1268                     " <div id=\"myTestDiv0\"></div> undefined [object Object] "},
1269             FF = {"11", "11", " ", "[object HTMLDivElement]", " ",
1270                   " <div id=\"myTestDiv0\"></div> undefined [object Object] "},
1271             FF_ESR = {"11", "11", " ", "[object HTMLDivElement]", " ",
1272                       " <div id=\"myTestDiv0\"></div> undefined [object Object] "})
1273     public void outerText_Empty() throws Exception {
1274         final String html = DOCTYPE_HTML
1275             + "<html><head>\n"
1276             + "<script>\n"
1277             + LOG_TITLE_FUNCTION
1278             + "  function test() {\n"
1279             + "    myTestDiv0.innerText = '';\n"
1280             + "    log(myCheckDiv.childNodes.length);\n"
1281 
1282             + "    myTestDiv1.outerText = ' ';\n"
1283             + "    myTestDiv2.outerText = null;\n"
1284             + "    myTestDiv3.outerText = undefined;\n"
1285             + "    myTestDiv4.outerText = { a: 'b'};\n"
1286 
1287             + "    log(myCheckDiv.childNodes.length);\n"
1288             + "    log(myCheckDiv.childNodes.item(0).data);\n"
1289             + "    log(myCheckDiv.childNodes.item(1));\n"
1290             + "    log(myCheckDiv.childNodes.item(2).data);\n"
1291 
1292             + "    log(myCheckDiv.innerHTML);\n"
1293             + "  }\n"
1294             + "</script>\n"
1295             + "</head>\n"
1296             + "<body onload='test()'>\n"
1297             + "  <div id='myCheckDiv'>\n"
1298             + "    <div id='myTestDiv0'>something</div>\n"
1299             + "    <div id='myTestDiv1'>something</div>\n"
1300             + "    <div id='myTestDiv2'>something</div>\n"
1301             + "    <div id='myTestDiv3'>something</div>\n"
1302             + "    <div id='myTestDiv4'>something</div>\n"
1303             + "  </div>/n"
1304             + "</body></html>";
1305 
1306         loadPageVerifyTitle2(html);
1307     }
1308 
1309     /**
1310      * @throws Exception if the test fails
1311      */
1312     @Test
1313     @Alerts({"1", "[object HTMLDivElement]", "1", "[object Text]", ""})
1314     public void outerText_null() throws Exception {
1315         final String html = DOCTYPE_HTML
1316             + "<html><head>\n"
1317             + "<script>\n"
1318             + LOG_TITLE_FUNCTION
1319             + "  function test() {\n"
1320             + "    checkChildren();\n"
1321             + "    myTestDiv.outerText = null;\n"
1322             + "    checkChildren();\n"
1323             + "    log(myCheckDiv.innerHTML);\n"
1324             + "  }\n"
1325             + "  function checkChildren() {\n"
1326             + "    log(myCheckDiv.childNodes.length);\n"
1327             + "    if (myCheckDiv.childNodes.length > 0)\n"
1328             + "      log(myCheckDiv.childNodes.item(0));\n"
1329             + "  }\n"
1330             + "</script>\n"
1331             + "</head>\n"
1332             + "<body onload='test()'>\n"
1333             + "  <div id='myCheckDiv'><div id='myTestDiv'>something</div></div>\n"
1334             + "</body></html>";
1335 
1336         loadPageVerifyTitle2(html);
1337     }
1338 
1339     /**
1340      * @throws Exception if the test fails
1341      */
1342     @Test
1343     @Alerts({"1", "[object HTMLDivElement]", "1", "[object Text]", ""})
1344     public void outerText_emptyString() throws Exception {
1345         final String html = DOCTYPE_HTML
1346             + "<html><head>\n"
1347             + "<script>\n"
1348             + LOG_TITLE_FUNCTION
1349             + "  function test() {\n"
1350             + "    checkChildren();\n"
1351             + "    myTestDiv.outerText = '';\n"
1352             + "    checkChildren();\n"
1353             + "    log(myCheckDiv.innerHTML);\n"
1354             + "  }\n"
1355             + "  function checkChildren() {\n"
1356             + "    log(myCheckDiv.childNodes.length);\n"
1357             + "    if (myCheckDiv.childNodes.length > 0)\n"
1358             + "      log(myCheckDiv.childNodes.item(0));\n"
1359             + "  }\n"
1360             + "</script>\n"
1361             + "</head>\n"
1362             + "<body onload='test()'>\n"
1363             + "  <div id='myCheckDiv'><div id='myTestDiv'>something</div></div>\n"
1364             + "</body></html>";
1365 
1366         loadPageVerifyTitle2(html);
1367     }
1368 
1369     /**
1370      * @throws Exception if the test fails
1371      */
1372     @Test
1373     @Alerts({"1", "[object HTMLDivElement]", "1", "[object Text]", " "})
1374     public void outerText_blankString() throws Exception {
1375         final String html = DOCTYPE_HTML
1376             + "<html><head>\n"
1377             + "<script>\n"
1378             + LOG_TITLE_FUNCTION
1379             + "  function test() {\n"
1380             + "    checkChildren();\n"
1381             + "    myTestDiv.outerText = '   \t';\n"
1382             + "    checkChildren();\n"
1383             + "    log(myCheckDiv.innerHTML);\n"
1384             + "  }\n"
1385             + "  function checkChildren() {\n"
1386             + "    log(myCheckDiv.childNodes.length);\n"
1387             + "    if (myCheckDiv.childNodes.length > 0)\n"
1388             + "      log(myCheckDiv.childNodes.item(0));\n"
1389             + "  }\n"
1390             + "</script>\n"
1391             + "</head>\n"
1392             + "<body onload='test()'>\n"
1393             + "  <div id='myCheckDiv'><div id='myTestDiv'>something</div></div>\n"
1394             + "</body></html>";
1395 
1396         loadPageVerifyTitle2(html);
1397     }
1398 
1399     /**
1400      * Blur isn't fired on DIV elements for instance.
1401      * @throws Exception if the test fails
1402      */
1403     @Test
1404     @Alerts({"input handler", "blur input"})
1405     public void eventHandlerBubble_blur() throws Exception {
1406         events("blur");
1407     }
1408 
1409     /**
1410      * Focus isn't fired on DIV elements for instance.
1411      * @throws Exception if the test fails
1412      */
1413     @Test
1414     @Alerts({"input handler", "focus input"})
1415     public void eventHandlerBubble_focus() throws Exception {
1416         events("focus");
1417     }
1418 
1419     /**
1420      * @throws Exception if the test fails
1421      */
1422     @Test
1423     @Alerts({"input handler", "click input", "div handler", "click div"})
1424     public void eventHandlerBubble_click() throws Exception {
1425         events("click");
1426     }
1427 
1428     private void events(final String type) throws Exception {
1429         final String html = DOCTYPE_HTML
1430             + "<html><head>\n"
1431             + "</head>\n"
1432             + "<body>\n"
1433             + "<div id='div' on" + type + "='log(\"div handler\")'>\n"
1434             + "<input id='input' on" + type + "='log(\"input handler\")'>\n"
1435             + "</div>\n"
1436             + LOG_TEXTAREA
1437             + "<script>\n"
1438             + LOG_TEXTAREA_FUNCTION
1439             + "function addListener(id, event) {\n"
1440             + "  var handler = function(e) { log(event + ' ' + id) };\n"
1441             + "  var e = document.getElementById(id);\n"
1442             + "  e.addEventListener(event, handler, false);\n"
1443             + "}\n"
1444             + "var eventType = '" + type + "';\n"
1445             + "addListener('div', eventType);\n"
1446             + "addListener('input', eventType);\n"
1447             + "</script>\n"
1448             + "</body></html>";
1449 
1450         final WebDriver driver = loadPage2(html);
1451         driver.findElement(By.id("input")).click();
1452         final WebElement log = driver.findElement(By.id("myLog"));
1453         log.click();
1454         verifyTextArea2(driver, getExpectedAlerts());
1455     }
1456 
1457     /**
1458      * @throws Exception if the test fails
1459      */
1460     @Test
1461     @Alerts({"null", "klazz"})
1462     public void setAttributeNodeUnknown() throws Exception {
1463         final String html = DOCTYPE_HTML
1464             + "<html><head>\n"
1465             + "<script>\n"
1466             + LOG_TITLE_FUNCTION
1467             + "  function test() {\n"
1468             + "    var attribute = document.createAttribute('unknown');\n"
1469             + "    attribute.nodeValue = 'klazz';\n"
1470             + "    log(document.body.setAttributeNode(attribute));\n"
1471             + "    log(document.body.getAttributeNode('unknown').nodeValue);\n"
1472             + "  }\n"
1473             + "</script></head>\n"
1474             + "<body onload='test()'></body></html>";
1475 
1476         loadPageVerifyTitle2(html);
1477     }
1478 
1479     /**
1480      * @throws Exception if the test fails
1481      */
1482     @Test
1483     @Alerts({"null", "klazz"})
1484     public void setAttributeNodeUnknown2() throws Exception {
1485         final String html = DOCTYPE_HTML
1486             + "<html><head>\n"
1487             + "<script>\n"
1488             + LOG_TITLE_FUNCTION
1489             + "  function test() {\n"
1490             + "    var attribute = document.createAttribute('unknown');\n"
1491             + "    log(document.body.setAttributeNode(attribute));\n"
1492             + "    attribute.nodeValue = 'klazz';\n"
1493             + "    log(document.body.getAttributeNode('unknown').nodeValue);\n"
1494             + "  }\n"
1495             + "</script></head>\n"
1496             + "<body onload='test()'></body></html>";
1497 
1498         loadPageVerifyTitle2(html);
1499     }
1500 
1501     /**
1502      * @throws Exception if the test fails
1503      */
1504     @Test
1505     @Alerts({"null", "klazz"})
1506     public void setAttributeNodeClass() throws Exception {
1507         final String html = DOCTYPE_HTML
1508             + "<html><head>\n"
1509             + "<script>\n"
1510             + LOG_TITLE_FUNCTION
1511             + "  function test() {\n"
1512             + "    var attribute = document.createAttribute('class');\n"
1513             + "    attribute.nodeValue = 'klazz';\n"
1514             + "    log(document.body.setAttributeNode(attribute));\n"
1515             + "    log(document.body.getAttributeNode('class').nodeValue);\n"
1516             + "  }\n"
1517             + "</script></head>\n"
1518             + "<body onload='test()'></body></html>";
1519 
1520         loadPageVerifyTitle2(html);
1521     }
1522 
1523     /**
1524      * @throws Exception if the test fails
1525      */
1526     @Test
1527     @Alerts({"null", "klazz"})
1528     public void setAttributeNodeClass2() throws Exception {
1529         final String html = DOCTYPE_HTML
1530             + "<html><head>\n"
1531             + "<script>\n"
1532             + LOG_TITLE_FUNCTION
1533             + "  function test() {\n"
1534             + "    var attribute = document.createAttribute('class');\n"
1535             + "    log(document.body.setAttributeNode(attribute));\n"
1536             + "    attribute.nodeValue = 'klazz';\n"
1537             + "    log(document.body.getAttributeNode('class').nodeValue);\n"
1538             + "  }\n"
1539             + "</script></head>\n"
1540             + "<body onload='test()'></body></html>";
1541 
1542         loadPageVerifyTitle2(html);
1543     }
1544 
1545     /**
1546      * @throws Exception if an error occurs
1547      */
1548     @Test
1549     @Alerts({"true", "center", "true", "center", "false"})
1550     public void removeAttributeNode() throws Exception {
1551         final String html = DOCTYPE_HTML
1552             + "<html><head><script>\n"
1553             + LOG_TITLE_FUNCTION
1554             + "  function test() {\n"
1555             + "    var e = document.getElementById('foo');\n"
1556             + "    log(e.removeAttributeNode != null);\n"
1557             + "    log(e.getAttribute('align'));\n"
1558             + "    log(e.hasAttribute('align'));\n"
1559             + "    var attr = e.getAttributeNode('align');\n"
1560             + "    log(attr.value);\n"
1561             + "    e.removeAttributeNode(attr);\n"
1562             + "    log(e.hasAttribute('align'));\n"
1563             + "  }\n"
1564             + "</script></head>\n"
1565             + "<body onload='test()'>\n"
1566             + "  <div id='foo' align='center' />\n"
1567             + "</body></html>";
1568         loadPageVerifyTitle2(html);
1569     }
1570 
1571     /**
1572      * @throws Exception if the test fails
1573      */
1574     @Test
1575     @Alerts({"3", "div1"})
1576     public void querySelectorAll() throws Exception {
1577         final String html = DOCTYPE_HTML
1578             + "<html><head>\n"
1579             + "<style>\n"
1580             + "  .red   {color:#FF0000;}\n"
1581             + "  .green {color:#00FF00;}\n"
1582             + "  .blue  {color:#0000FF;}\n"
1583             + "</style>\n"
1584             + "<script>\n"
1585             + LOG_TITLE_FUNCTION
1586             + "function test() {\n"
1587             + "  var redTags = document.body.querySelectorAll('.green,.red');\n"
1588             + "  log(redTags.length);\n"
1589             + "  log(redTags.item(0).id);\n"
1590             + "}\n"
1591             + "</script></head><body onload='test()'>\n"
1592             + "  <div id='div1' class='red'>First</div>\n"
1593             + "  <div id='div2' class='red'>Second</div>\n"
1594             + "  <div id='div3' class='green'>Third</div>\n"
1595             + "  <div id='div4' class='blue'>Fourth</div>\n"
1596             + "</body></html>";
1597 
1598         loadPageVerifyTitle2(html);
1599     }
1600 
1601     /**
1602      * @throws Exception if the test fails
1603      */
1604     @Test
1605     @Alerts({"1", "p1"})
1606     public void querySelectorAllOnDisconnectedElement() throws Exception {
1607         final String html = DOCTYPE_HTML
1608             + "<html><head>\n"
1609             + "<script>\n"
1610             + LOG_TITLE_FUNCTION
1611             + "function test() {\n"
1612             + "  var myDiv = document.createElement('div');\n"
1613             + "  myDiv.innerHTML = '<p id=\"p1\" class=\"TEST\"></p>';\n"
1614             + "  var found = myDiv.querySelectorAll('.TEST');\n"
1615             + "  log(found.length);\n"
1616             + "  log(found.item(0).id);\n"
1617             + "}\n"
1618             + "</script></head>\n"
1619             + "<body onload='test()'>\n"
1620             + "</body></html>";
1621 
1622         loadPageVerifyTitle2(html);
1623     }
1624 
1625     /**
1626      * @throws Exception if the test fails
1627      */
1628     @Test
1629     @Alerts("SyntaxError/DOMException")
1630     public void querySelectorAll_badSelector() throws Exception {
1631         for (final String selector : HTMLDocumentTest.JQUERY_CUSTOM_SELECTORS) {
1632             doTestQuerySelectorAll_badSelector(selector);
1633         }
1634 
1635         // some other bad selectors tested in jQuery 1.8.2 tests
1636         final String[] otherBadSelectors = {":nth-child(2n+-0)", ":nth-child(2+0)",
1637             ":nth-child(- 1n)", ":nth-child(-1 n)"};
1638         for (final String selector : otherBadSelectors) {
1639             doTestQuerySelectorAll_badSelector(selector);
1640         }
1641     }
1642 
1643     private void doTestQuerySelectorAll_badSelector(final String selector) throws Exception {
1644         final String html = DOCTYPE_HTML
1645             + "<html><body><div id='it'></div><script>\n"
1646             + LOG_TITLE_FUNCTION
1647             + "try {\n"
1648             + "  document.getElementById('it').querySelectorAll('" + selector + "');\n"
1649             + "  log('working: " + selector + "');\n"
1650             + "} catch(e) { logEx(e); }\n"
1651             + "</script></body></html>";
1652 
1653         loadPageVerifyTitle2(html);
1654     }
1655 
1656     /**
1657      * @throws Exception if the test fails
1658      */
1659     @Test
1660     @Alerts("SyntaxError/DOMException")
1661     public void querySelector_badSelectorJQueryCustomSelectors() throws Exception {
1662         for (final String selector : HTMLDocumentTest.JQUERY_CUSTOM_SELECTORS) {
1663             doTestQuerySelector_badSelector(selector);
1664         }
1665     }
1666 
1667     /**
1668      * @throws Exception if the test fails
1669      */
1670     @Test
1671     @Alerts("SyntaxError/DOMException")
1672     public void querySelector_badSelectorJQueryBrowserTest() throws Exception {
1673         doTestQuerySelector_badSelector("[s!='']:x");
1674     }
1675 
1676     private void doTestQuerySelector_badSelector(final String selector) throws Exception {
1677         final String html = DOCTYPE_HTML
1678             + "<html><body><div id='it'></div><script>\n"
1679             + LOG_TITLE_FUNCTION
1680             + "try {\n"
1681             + "  document.getElementById('it').querySelector(\"" + selector + "\");\n"
1682             + "  log(\"working " + selector + "\");\n"
1683             + "} catch(e) { logEx(e); }\n"
1684             + "</script></body></html>";
1685 
1686         loadPageVerifyTitle2(html);
1687     }
1688 
1689     /**
1690      * Function querySelectorAll should return nodes matched by many rules only once.
1691      * @throws Exception if the test fails
1692      */
1693     @Test
1694     @Alerts("1")
1695     public void querySelectorAll_noDuplication() throws Exception {
1696         final String html = DOCTYPE_HTML
1697             + "<html><body>\n"
1698             + "<div><span>First</span></div>\n"
1699             + "<script>\n"
1700             + LOG_TITLE_FUNCTION
1701             + "  var tags = document.body.querySelectorAll('span, div > span');\n"
1702             + "  log(tags.length);\n"
1703             + "</script></body></html>";
1704 
1705         loadPageVerifyTitle2(html);
1706     }
1707 
1708     /**
1709      * Test the use of innerHTML to set new HTML code.
1710      * @throws Exception if the test fails
1711      */
1712     @Test
1713     @Alerts({"Old = <b>Old innerHTML</b><!-- old comment -->",
1714                 "New =  <b><i id=\"newElt\">New cell value</i></b>",
1715                 "I"})
1716     public void getSetInnerHTMLComplex() throws Exception {
1717         final String html = DOCTYPE_HTML
1718             + "<html>\n"
1719             + "<head>\n"
1720             + "  <script>\n"
1721             + LOG_TEXTAREA_FUNCTION
1722             + "  function doTest() {\n"
1723             + "    var myNode = document.getElementById('myNode');\n"
1724             + "    log('Old = ' + myNode.innerHTML);\n"
1725             + "    myNode.innerHTML = ' <b><i id=\"newElt\">New cell value</i></b>';\n"
1726             + "    log('New = ' + myNode.innerHTML);\n"
1727             + "    log(document.getElementById('newElt').tagName);\n"
1728             + "  }\n"
1729             + "  </script>\n"
1730             + "</head>\n"
1731             + "<body onload='doTest()'>\n"
1732             + "  <p id='myNode'><b>Old innerHTML</b><!-- old comment --></p>\n"
1733             + LOG_TEXTAREA
1734             + "</body>\n"
1735             + "</html>";
1736 
1737         final WebDriver driver = loadPageVerifyTextArea2(html);
1738 
1739         final WebElement pElt = driver.findElement(By.id("myNode"));
1740         assertEquals("p", pElt.getTagName());
1741 
1742         final WebElement elt = driver.findElement(By.id("newElt"));
1743         assertEquals("New cell value", elt.getText());
1744         assertEquals(1, driver.getWindowHandles().size());
1745     }
1746 
1747     /**
1748      * Test the use of outerHTML to set new HTML code.
1749      * @throws Exception if the test fails
1750      */
1751     @Test
1752     @Alerts({"Old\\s=\\s<b\\sid=\"innerNode\">Old\\souterHTML</b>",
1753                 "New\\s=\\s\\s<b><i\\sid=\"newElt\">New\\scell\\svalue</i></b>",
1754                 "I"})
1755     public void getSetOuterHTMLComplex() throws Exception {
1756         final String html = DOCTYPE_HTML
1757             + "<html>\n"
1758             + "<head>\n"
1759             + "  <script>\n"
1760             + LOG_TITLE_FUNCTION_NORMALIZE
1761             + "  function doTest() {\n"
1762             + "    var myNode = document.getElementById('myNode');\n"
1763             + "    var innerNode = document.getElementById('innerNode');\n"
1764             + "    log('Old = ' + innerNode.outerHTML);\n"
1765             + "    innerNode.outerHTML = ' <b><i id=\"newElt\">New cell value</i></b>';\n"
1766             + "    log('New = ' + myNode.innerHTML);\n"
1767             + "    log(document.getElementById('newElt').tagName);\n"
1768             + "  }\n"
1769             + "  </script>\n"
1770             + "</head>\n"
1771             + "<body onload='doTest()'>\n"
1772             + "<p id='myNode'><b id='innerNode'>Old outerHTML</b></p>\n"
1773             + "</body>\n"
1774             + "</html>";
1775 
1776         final WebDriver driver = loadPageVerifyTitle2(html);
1777 
1778         final WebElement pElt = driver.findElement(By.id("myNode"));
1779         assertEquals("p", pElt.getTagName());
1780 
1781         final WebElement elt = driver.findElement(By.id("newElt"));
1782         assertEquals("New cell value", elt.getText());
1783         assertEquals(1, driver.getWindowHandles().size());
1784     }
1785 
1786     /**
1787      * @throws Exception if an error occurs
1788      */
1789     @Test
1790     @Alerts({"false", "true"})
1791     public void dispatchEvent2() throws Exception {
1792         final String html = DOCTYPE_HTML
1793             + "<html>\n"
1794             + "<head>\n"
1795             + "<script>\n"
1796             + LOG_TITLE_FUNCTION
1797             + "  function simulateClick() {\n"
1798             + "    var evt = document.createEvent('MouseEvents');\n"
1799             + "    evt.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0,"
1800                         + " false, false, false, false, 0, null);\n"
1801             + "    var cb = document.getElementById('checkbox');\n"
1802             + "    cb.dispatchEvent(evt);\n"
1803             + "  }\n"
1804             + "  function test() {\n"
1805             + "    log(document.getElementById('checkbox').checked);\n"
1806             + "    simulateClick();\n"
1807             + "    log(document.getElementById('checkbox').checked);\n"
1808             + "  }\n"
1809             + "</script>\n"
1810             + "<body onload='test()'>\n"
1811             + "  <input type='checkbox' id='checkbox'/><label for='checkbox'>Checkbox</label>\n"
1812             + "</body>\n"
1813             + "</html>";
1814 
1815         loadPageVerifyTitle2(html);
1816     }
1817 
1818     /**
1819      * Test case for issue #1626.
1820      * @throws Exception if an error occurs
1821      */
1822     @Test
1823     @Alerts("true")
1824     public void offsetLeft_PositionFixed() throws Exception {
1825         final String html = DOCTYPE_HTML
1826                 + "<html>\n"
1827                 + "<head>\n"
1828                 + "  <script>\n"
1829                 + LOG_TITLE_FUNCTION
1830                 + "  </script>\n"
1831                 + "  <style>\n"
1832                 + "    body {\n"
1833                 + "      padding: 0; margin:0;\n"
1834                 + "    }\n"
1835                 + "    #container {\n"
1836                 + "      width: 200px; position: fixed; right: 0px;\n"
1837                 + "    }\n"
1838                 + "  </style>\n"
1839                 + "</head>\n"
1840                 + "<body onload=\"log(document.getElementById('container').offsetLeft > 0)\">\n"
1841                 + "  <div id=\"container\">\n"
1842                 + "    <ul>\n"
1843                 + "      <li><span>1st</span> List Item.</li>\n"
1844                 + "      <li><span>Another</span> List Item.</li>\n"
1845                 + "    </ul>\n"
1846                 + "  </div>\n"
1847                 + "</body>\n"
1848                 + "</html>";
1849 
1850         loadPageVerifyTitle2(html);
1851     }
1852 
1853     /**
1854      * @throws Exception if an error occurs
1855      */
1856     @Test
1857     @Alerts({"clicked", "fireEvent not available"})
1858     public void fireEvent_WithoutTemplate() throws Exception {
1859         final String html = DOCTYPE_HTML
1860             + "<html>\n"
1861             + "  <head>\n"
1862             + "    <script>\n"
1863             + LOG_TITLE_FUNCTION
1864             + "    function doTest() {\n"
1865             + "      var elem = document.getElementById('a');\n"
1866             + "      if (!elem.fireEvent) { log('fireEvent not available'); return }\n"
1867             + "      elem.fireEvent('onclick');\n"
1868             + "    }\n"
1869             + "    </script>\n"
1870             + "  </head>\n"
1871             + "<body>\n"
1872             + "  <div id='a' onclick='log(\"clicked\")'>foo</div>\n"
1873             + "  <div id='b' onmouseover='doTest()'>bar</div>\n"
1874             + "</body></html>";
1875 
1876         final WebDriver driver = loadPage2(html);
1877         driver.findElement(By.id("a")).click();
1878         verifyTitle2(driver, getExpectedAlerts()[0]);
1879 
1880         final Actions actions = new Actions(driver);
1881         actions.moveToElement(driver.findElement(By.id("b")));
1882         actions.perform();
1883         verifyTitle2(driver, getExpectedAlerts());
1884     }
1885 
1886     /**
1887      * @throws Exception if an error occurs
1888      */
1889     @Test
1890     @Alerts({"click", "fireEvent not available", "fireEvent not available"})
1891     public void fireEvent_WithTemplate() throws Exception {
1892         final String html = DOCTYPE_HTML
1893             + "<html>\n"
1894             + "  <head>\n"
1895             + "    <script>\n"
1896             + LOG_TITLE_FUNCTION
1897             + "    function dolog(e) {\n"
1898             + "      log(e.type);\n"
1899             + "    }\n"
1900 
1901             + "    function doTest() {\n"
1902             + "      var elem = document.getElementById('a');\n"
1903             + "      if (!elem.fireEvent) { log('fireEvent not available'); return }\n"
1904             + "      elem.fireEvent('onclick');\n"
1905             + "    }\n"
1906 
1907             + "    function doTest2() {\n"
1908             + "      var elem = document.getElementById('a');\n"
1909             + "      if (!elem.fireEvent) { log('fireEvent not available'); return }\n"
1910             + "      var template = document.createEventObject();\n"
1911             + "      elem.fireEvent('onclick', template);\n"
1912             + "    }\n"
1913 
1914             + "    </script>\n"
1915             + "  </head>\n"
1916             + "<body>\n"
1917             + "  <div id='a' onclick='dolog(event)'>foo</div>\n"
1918             + "  <div id='b' onclick='doTest()'>bar</div>\n"
1919             + "  <div id='c' onclick='doTest2()'>baz</div>\n"
1920             + "</body></html>";
1921 
1922         final WebDriver driver = loadPage2(html);
1923         driver.findElement(By.id("a")).click();
1924         verifyTitle2(driver, getExpectedAlerts()[0]);
1925 
1926         driver.findElement(By.id("b")).click();
1927         verifyTitle2(driver, getExpectedAlerts()[0], getExpectedAlerts()[1]);
1928 
1929         driver.findElement(By.id("c")).click();
1930         verifyTitle2(driver, getExpectedAlerts());
1931     }
1932 
1933     /**
1934      * Document.write after setting innerHTML.
1935      * @throws Exception if the test fails
1936      */
1937     @Test
1938     @Alerts("hello")
1939     public void setInnerHTMLDocumentWrite() throws Exception {
1940         final String html = DOCTYPE_HTML
1941             + "<html>\n"
1942             + "<head><title>test</title></head>\n"
1943             + "<body>\n"
1944             + "<script>\n"
1945             + "     var a = document.createElement('a');\n"
1946             + "     a.innerHTML = 'break';\n"
1947             + "     document.write('hello');\n"
1948             + "</script></body></html>";
1949         final WebDriver driver = loadPage2(html);
1950         assertEquals(getExpectedAlerts()[0], driver.findElement(By.tagName("body")).getText());
1951     }
1952 
1953     /**
1954      * @throws Exception if the test fails
1955      */
1956     @Test
1957     @Alerts({"First: body1", "Second:", "Second: body1 setActive not available"})
1958     // alert conflicts with focus/blur
1959     public void setActiveAndFocus() throws Exception {
1960         final String firstHtml = DOCTYPE_HTML
1961             + "<html>\n"
1962             + "<head>\n"
1963             + "  <title>First: </title>\n"
1964             + "  <script>var win2;</script>\n"
1965             + "</head>\n"
1966             + "<body id='body1' onload='document.title += \" \" + document.activeElement.id'>\n"
1967             + "<form name='form1'>\n"
1968             + "  <input id='text1' onfocus='document.title += \" onfocus text1\"; win2.focus();'>\n"
1969             + "  <button id='button1' onClick='win2=window.open(\"" + URL_SECOND + "\", \"second\");'>Click me</a>\n"
1970             + "</form>\n"
1971             + "</body></html>";
1972 
1973         final String secondHtml = DOCTYPE_HTML
1974             + "<html>\n"
1975             + "<head>\n"
1976             + "  <title>Second: </title>\n"
1977             + "</head>\n"
1978             + "<body id='body2'>\n"
1979             + "  <input id='text2' onfocus='document.title += \" onfocus text2\"'>\n"
1980             + "  <button id='button2' onClick='doTest();'>Click me</a>\n"
1981             + "  <script>\n"
1982             + "    function doTest() {\n"
1983             + "      var elem = opener.document.getElementById('text1');\n"
1984             + "      document.title += ' ' + opener.document.activeElement.id;\n"
1985             + "      if (!elem.setActive) { document.title += ' setActive not available'; return; }\n"
1986             + "      elem.setActive();\n"
1987             + "      document.title += ' ' + opener.document.activeElement.id;\n"
1988             + "      document.title += ' ' + document.activeElement;\n"
1989             + "      document.getElementById('text2').setActive();\n"
1990             + "      document.title += ' ' + document.activeElement.id;\n"
1991             + "      document.title += ' ' + opener;\n"
1992             + "      opener.focus();\n"
1993             + "    }\n"
1994             + "  </script>\n"
1995             + "</body></html>";
1996         getMockWebConnection().setResponse(URL_SECOND, secondHtml);
1997 
1998         final WebDriver driver = loadPage2(firstHtml);
1999         assertTitle(driver, getExpectedAlerts()[0]);
2000 
2001         driver.findElement(By.id("button1")).click();
2002 
2003         driver.switchTo().window("second");
2004         assertTitle(driver, getExpectedAlerts()[1]);
2005 
2006         driver.findElement(By.id("button2")).click();
2007         assertTitle(driver,  getExpectedAlerts()[2]);
2008     }
2009 
2010     /**
2011      * @throws Exception failure
2012      */
2013     @Test
2014     @Alerts({"DIV,DIV,http://www.w3.org/1999/xhtml,null,div", "svg,svg,http://www.w3.org/2000/svg,null,svg",
2015              "g,g,http://www.w3.org/2000/svg,null,g", "svg,svg,http://www.w3.org/2000/svg,null,svg"})
2016     public void variousNames() throws Exception {
2017         final String html =
2018             "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
2019                             + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"
2020             + "<html>\n"
2021             + "<head>\n"
2022             + "<script>\n"
2023             + LOG_TITLE_FUNCTION
2024             + "  function test() {\n"
2025             + "    debug(document.getElementById('myDiv'));\n"
2026             + "    debug(document.getElementById('mySVG'));\n"
2027             + "    debug(document.getElementById('myG'));\n"
2028             + "    debug(document.getElementById('mySVGWithNS'));\n"
2029             + "  }\n"
2030             + "  function debug(e) {\n"
2031             + "    log(e.nodeName + ',' + e.tagName + ',' + e.namespaceURI + ',' + e.prefix + ',' + e.localName);\n"
2032             + "  }\n"
2033             + "</script>\n"
2034             + "</head>\n"
2035             + "<body onload='test()'>\n"
2036             + "  <div id=myDiv>test</div>\n"
2037             + "  <svg id='mySVG'>\n"
2038             + "    <G id='myG'></G>\n"
2039             + "  </svg>\n"
2040             + "  <svg id='mySVGWithNS' xmlns='http://www.w3.org/2017/svg'>\n"
2041             + "  </svg>\n"
2042             + "</body></html>\n";
2043 
2044         loadPageVerifyTitle2(html);
2045     }
2046 
2047     /**
2048      * @throws Exception if the test fails
2049      */
2050     @Test
2051     @Alerts("success")
2052     public void setOnclick() throws Exception {
2053         eventHandlerSetterGetterTest("onclick");
2054     }
2055 
2056     /**
2057      * @throws Exception if the test fails
2058      */
2059     @Test
2060     @Alerts("success")
2061     public void setOndblclick() throws Exception {
2062         eventHandlerSetterGetterTest("ondblclick");
2063     }
2064 
2065     /**
2066      * @throws Exception if the test fails
2067      */
2068     @Test
2069     @Alerts("success")
2070     public void setOnblur() throws Exception {
2071         eventHandlerSetterGetterTest("onblur");
2072     }
2073 
2074     /**
2075      * @throws Exception if the test fails
2076      */
2077     @Test
2078     @Alerts("success")
2079     public void setOnfocus() throws Exception {
2080         eventHandlerSetterGetterTest("onfocus");
2081     }
2082 
2083     /**
2084      * @throws Exception if the test fails
2085      */
2086     @Test
2087     @Alerts("success")
2088     public void setOnkeydown() throws Exception {
2089         eventHandlerSetterGetterTest("onkeydown");
2090     }
2091 
2092     /**
2093      * @throws Exception if the test fails
2094      */
2095     @Test
2096     @Alerts("success")
2097     public void setOnkeypress() throws Exception {
2098         eventHandlerSetterGetterTest("onkeypress");
2099     }
2100 
2101     /**
2102      * @throws Exception if the test fails
2103      */
2104     @Test
2105     @Alerts("success")
2106     public void setOnkeyup() throws Exception {
2107         eventHandlerSetterGetterTest("onkeyup");
2108     }
2109 
2110     /**
2111      * @throws Exception if the test fails
2112      */
2113     @Test
2114     @Alerts("success")
2115     public void setOnmousedown() throws Exception {
2116         eventHandlerSetterGetterTest("onmousedown");
2117     }
2118 
2119     /**
2120      * @throws Exception if the test fails
2121      */
2122     @Test
2123     @Alerts("success")
2124     public void setOnmouseup() throws Exception {
2125         eventHandlerSetterGetterTest("onmouseup");
2126     }
2127 
2128     /**
2129      * @throws Exception if the test fails
2130      */
2131     @Test
2132     @Alerts("success")
2133     public void setOnmouseover() throws Exception {
2134         eventHandlerSetterGetterTest("onmouseover");
2135     }
2136 
2137     /**
2138      * @throws Exception if the test fails
2139      */
2140     @Test
2141     @Alerts("success")
2142     public void setOnmouseout() throws Exception {
2143         eventHandlerSetterGetterTest("onmouseout");
2144     }
2145 
2146     /**
2147      * @throws Exception if the test fails
2148      */
2149     @Test
2150     @Alerts("success")
2151     public void setOnmousemove() throws Exception {
2152         eventHandlerSetterGetterTest("onmousemove");
2153     }
2154 
2155     /**
2156      * @throws Exception if the test fails
2157      */
2158     @Test
2159     @Alerts("success")
2160     public void setOnresize() throws Exception {
2161         eventHandlerSetterGetterTest("onresize");
2162     }
2163 
2164     /**
2165      * @throws Exception if the test fails
2166      */
2167     @Test
2168     @Alerts("success")
2169     public void setOnerror() throws Exception {
2170         eventHandlerSetterGetterTest("onerror");
2171     }
2172 
2173     /**
2174      * @param eventName the name of the event
2175      * @throws Exception if the test fails
2176      */
2177     private void eventHandlerSetterGetterTest(final String eventName) throws Exception {
2178         final String html = DOCTYPE_HTML
2179             + "<html>\n"
2180             + "<head>\n"
2181             + "<script>\n"
2182             + LOG_TITLE_FUNCTION
2183             + "function handler(event) {}\n"
2184             + "function test() {\n"
2185             + "  var oDiv = document.getElementById('myDiv');\n"
2186             + "  oDiv." + eventName + " = handler;\n"
2187             + "  if (oDiv." + eventName + " == handler) {\n"
2188             + "    log('success');\n"
2189             + "  } else {\n"
2190             + "    log('fail');\n"
2191             + "  }\n"
2192             + "}\n"
2193             + "</script>\n"
2194             + "</head>\n"
2195             + "<body onload='test()'>\n"
2196             + "<div id='myDiv'><br/><div><span>test</span></div></div>\n"
2197             + "</body>\n"
2198             + "</html>";
2199 
2200         loadPageVerifyTitle2(html);
2201     }
2202 
2203 }