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.dom;
16  
17  import java.net.URL;
18  
19  import org.htmlunit.MockWebConnection;
20  import org.htmlunit.WebDriverTestCase;
21  import org.htmlunit.junit.BrowserRunner;
22  import org.htmlunit.junit.annotation.Alerts;
23  import org.htmlunit.junit.annotation.HtmlUnitNYI;
24  import org.htmlunit.util.MimeType;
25  import org.junit.Test;
26  import org.junit.runner.RunWith;
27  import org.openqa.selenium.By;
28  import org.openqa.selenium.WebDriver;
29  
30  /**
31   * Tests for {@link Document}.
32   *
33   * @author Ronald Brill
34   * @author Marc Guillemot
35   * @author Frank Danek
36   * @author Madis Pärn
37   * @author Ahmed Ashour
38   */
39  @RunWith(BrowserRunner.class)
40  public class Document2Test extends WebDriverTestCase {
41  
42      /**
43       * @throws Exception if the test fails
44       */
45      @Test
46      @Alerts("InvalidCharacterError/DOMException")
47      public void createElementWithAngleBrackets() throws Exception {
48          final String html = DOCTYPE_HTML
49              + "<html><head>\n"
50              + "<script>\n"
51              + LOG_TITLE_FUNCTION
52              + "  function test() {\n"
53              + "    try {\n"
54              + "      var select = document.createElement('<select>');\n"
55              + "      log(select.add == undefined);\n"
56              + "    }\n"
57              + "    catch(e) { logEx(e) }\n"
58              + "  }\n"
59              + "</script></head><body onload='test()'>\n"
60              + "</body></html>";
61  
62          loadPageVerifyTitle2(html);
63      }
64  
65      /**
66       * @throws Exception if the test fails
67       */
68      @Test
69      @Alerts("InvalidCharacterError/DOMException")
70      public void createElementWithHtml() throws Exception {
71          final String html = DOCTYPE_HTML
72              + "<html><head>\n"
73              + "<script>\n"
74              + LOG_TITLE_FUNCTION
75              + "  function test() {\n"
76              + "    try {\n"
77              + "      log(document.createElement('<div>').tagName);\n"
78              + "      var select = document.createElement(\"<select id='mySelect'><option>hello</option>\");\n"
79              + "      log(select.add == undefined);\n"
80              + "      log(select.id);\n"
81              + "      log(select.childNodes.length);\n"
82              + "      var option = document.createElement(\"<option id='myOption'>\");\n"
83              + "      log(option.tagName);\n"
84              + "      log(option.id);\n"
85              + "      log(option.childNodes.length);\n"
86              + "    }\n"
87              + "    catch(e) { logEx(e) }\n"
88              + "  }\n"
89              + "</script></head><body onload='test()'>\n"
90              + "</body></html>";
91  
92          loadPageVerifyTitle2(html);
93      }
94  
95      /**
96       * Dedicated test for 3410657.
97       *
98       * @throws Exception if the test fails
99       */
100     @Test
101     @Alerts("false")
102     public void createElementPrototype() throws Exception {
103         final String html = DOCTYPE_HTML
104             + "<html><head>\n"
105             + "<script>\n"
106             + LOG_TITLE_FUNCTION
107             + "  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function() {\n"
108             + "    try {\n"
109             + "      var el = document.createElement('<input name=\"x\">');\n"
110             + "      return el.tagName.toLowerCase() === 'input' && el.name === 'x';\n"
111             + "    } catch (err) {\n"
112             + "      return false;\n"
113             + "    }\n"
114             + "  })();\n"
115             + "  log(HAS_EXTENDED_CREATE_ELEMENT_SYNTAX);\n"
116             + "</script></head><body>\n"
117             + "</body></html>";
118 
119         loadPageVerifyTitle2(html);
120     }
121 
122     /**
123      * @throws Exception if the test fails
124      */
125     @Test
126     @Alerts("true")
127     public void appendChild() throws Exception {
128         final String html = DOCTYPE_HTML
129             + "<html><head>\n"
130             + "<script>\n"
131             + LOG_TITLE_FUNCTION
132             + "function test() {\n"
133             + "  var span = document.createElement('SPAN');\n"
134             + "  var div = document.getElementById('d');\n"
135             + "  div.appendChild(span);\n"
136             + "  log(span === div.childNodes[0]);\n"
137             + "}\n"
138             + "</script></head><body onload='test()'>\n"
139             + "<div id='d'></div>\n"
140             + "</body></html>";
141 
142         loadPageVerifyTitle2(html);
143     }
144 
145     /**
146      * @throws Exception if the test fails
147      */
148     @Test
149     @Alerts("1")
150     public void getElementByTagNameNS_includesHtml() throws Exception {
151         final String html = DOCTYPE_HTML
152             + "<html><head>\n"
153             + "<script>\n"
154             + LOG_TITLE_FUNCTION
155             + "  function doTest() {\n"
156             + "    log(document.getElementsByTagNameNS('*', 'html').length);\n"
157             + "  }\n"
158             + "</script>\n"
159             + "</head>\n"
160             + "<body onload='doTest()'>\n"
161             + "  <p>hello world</p>\n"
162             + "</body></html>";
163 
164         loadPageVerifyTitle2(html);
165     }
166 
167     /**
168      * @throws Exception if the test fails
169      */
170     @Test
171     @Alerts({"div1", "null", "2", "1"})
172     public void importNode_deep() throws Exception {
173         importNode(true);
174     }
175 
176     /**
177      * @throws Exception if the test fails
178      */
179     @Test
180     @Alerts({"div1", "null", "0"})
181     public void importNode_notDeep() throws Exception {
182         importNode(false);
183     }
184 
185     private void importNode(final boolean deep) throws Exception {
186         final String html = DOCTYPE_HTML
187             + "<html><head>\n"
188             + "<script>\n"
189             + LOG_TITLE_FUNCTION
190             + "  function test() {\n"
191             + "    var node = document.importNode(document.getElementById('div1'), " + deep + ");\n"
192             + "    log(node.id);\n"
193             + "    log(node.parentNode);\n"
194             + "    log(node.childNodes.length);\n"
195             + "    if (node.childNodes.length != 0)\n"
196             + "      log(node.childNodes[0].childNodes.length);\n"
197             + "  }\n"
198             + "</script></head><body onload='test()'>\n"
199             + "  <div id='div1'><div id='div1_1'><div id='div1_1_1'></div></div><div id='div1_2'></div></div>\n"
200             + "</body></html>";
201 
202         loadPageVerifyTitle2(html);
203     }
204 
205     /**
206      * Test for issue 3560821.
207      * @throws Exception if the test fails
208      */
209     @Test
210     @Alerts({"parent", "child"})
211     public void importNodeWithNamespace() throws Exception {
212         final MockWebConnection conn = getMockWebConnection();
213         conn.setDefaultResponse(
214                 "<?xml version=\"1.0\"?><html xmlns=\"http://www.w3.org/1999/xhtml\"><div id='child'> </div></html>",
215                 200, "OK", MimeType.TEXT_XML);
216 
217         final String html =
218             "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
219             + "<head><script>\n"
220             + LOG_TITLE_FUNCTION
221             + "function test() {\n"
222             + "  if (!document.evaluate) { log('evaluate not available'); return; }\n"
223             + "  var xmlhttp = new XMLHttpRequest();\n"
224             + "  xmlhttp.open(\"GET\",\"content.xhtml\",true);\n"
225             + "  xmlhttp.send();\n"
226             + "  xmlhttp.onreadystatechange = function() {\n"
227             + "    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {\n"
228             + "      var child = document.importNode(xmlhttp.responseXML.getElementById(\"child\"), true);\n"
229             + "      document.getElementById(\"parent\").appendChild(child);\n"
230             + "      var found = document.evaluate(\"//div[@id='parent']\", document, null,"
231             +                      "XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
232             + "      log(found.singleNodeValue.id);\n"
233             + "      found = document.evaluate(\"//div[@id='child']\", document, null,"
234             +                      "XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
235             + "      log(found.singleNodeValue.id);\n"
236             + "    }\n"
237             + " }\n"
238             + "}\n"
239             + "</script></head>\n"
240             + "<body onload='test()'>\n"
241             + "  <div id='parent'></div>\n"
242             + "</body></html>\n";
243 
244         loadPage2(html);
245         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
246     }
247 
248     /**
249      * Test for issue 3560821.
250      * @throws Exception if the test fails
251      */
252     @Test
253     @Alerts({"parent", "child", "child3"})
254     public void importNodesWithNamespace() throws Exception {
255         final MockWebConnection conn = getMockWebConnection();
256         conn.setDefaultResponse(
257                 "<?xml version=\"1.0\"?><html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
258                 + "<div id='child'><div id='child2'><div id='child3'>-</div></div></div></html>",
259                 200, "OK", MimeType.TEXT_XML);
260 
261         final String html =
262             "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
263             + "<head><script>\n"
264             + LOG_TITLE_FUNCTION
265             + "function test() {\n"
266             + "  if (!document.evaluate) { log('evaluate not available'); return; }\n"
267             + "  var xmlhttp = new XMLHttpRequest();\n"
268             + "  xmlhttp.open(\"GET\",\"content.xhtml\",true);\n"
269             + "  xmlhttp.send();\n"
270             + "  xmlhttp.onreadystatechange = function() {\n"
271             + "    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {\n"
272             + "      var child = document.importNode(xmlhttp.responseXML.getElementById(\"child\"), true);\n"
273             + "      document.getElementById(\"parent\").appendChild(child);\n"
274             + "      var found = document.evaluate(\"//div[@id='parent']\", document, null,"
275             +                      "XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
276             + "      log(found.singleNodeValue.id);\n"
277             + "      found = document.evaluate(\"//div[@id='child']\", document, null,"
278             +                      "XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
279             + "      log(found.singleNodeValue.id);\n"
280             + "      found = document.evaluate(\"//div[@id='child3']\", document, null,"
281             +                      "XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n"
282             + "      log(found.singleNodeValue.id);\n"
283             + "    }\n"
284             + "  }\n"
285             + "}\n"
286             + "</script></head>\n"
287             + "<body onload='test()'>\n"
288             + "  <div id='parent'></div>\n"
289             + "</body></html>\n";
290 
291         loadPage2(html);
292         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
293     }
294 
295     /**
296      * @throws Exception if the test fails
297      */
298     @Test
299     @Alerts({"div1", "null", "null"})
300     public void adoptNode() throws Exception {
301         final String html = DOCTYPE_HTML
302             + "<html><head><script>\n"
303             + LOG_TITLE_FUNCTION
304             + "  function test() {\n"
305             + "    var newDoc = document.implementation.createHTMLDocument('something');\n"
306             + "    var node = newDoc.adoptNode(document.getElementById('div1'));\n"
307             + "    log(node.id);\n"
308             + "    log(node.parentNode);\n"
309             + "    log(document.getElementById('div1'));\n"
310             + "  }\n"
311             + "</script></head><body onload='test()'>\n"
312             + "  <div id='div1'><div id='div1_1'></div></div>\n"
313             + "</body></html>";
314 
315         loadPageVerifyTitle2(html);
316     }
317 
318     /**
319      * @throws Exception if the test fails
320      */
321     @Test
322     @Alerts({"null", "text1"})
323     public void activeElement() throws Exception {
324         final String html = DOCTYPE_HTML
325             + "<html><head><script>\n"
326             + "  alert(document.activeElement);\n"
327             + "  function test() {\n"
328             + "    alert(document.activeElement.id);\n"
329             + "  }\n"
330             + "</script></head>\n"
331             + "<body>\n"
332             + "  <input id='text1' onclick='test()'>\n"
333             + "</body></html>";
334         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
335 
336         final WebDriver driver = loadPage2(html);
337         verifyAlerts(driver, getExpectedAlerts()[0]);
338         Thread.sleep(100);
339         driver.findElement(By.id("text1")).click();
340         verifyAlerts(driver, getExpectedAlerts()[1]);
341     }
342 
343     /**
344      * Regression test for issue 1568.
345      * @throws Exception if the test fails
346      */
347     @Test
348     @Alerts({"[object HTMLBodyElement]", "§§URL§§#", "§§URL§§#"})
349     public void activeElement_iframe() throws Exception {
350         final String html = DOCTYPE_HTML
351                 + "<html>\n"
352                 + "<head></head>\n"
353                 + "<body>\n"
354 
355                 + "  <a id='insert' "
356                         + "onclick=\"insertText("
357                         + "'<html><head></head><body>first frame text</body></html>');\" href=\"#\">\n"
358                         + "insert text to frame</a>\n"
359                 + "  <a id= 'update' "
360                         + "onclick=\"insertText("
361                         + "'<html><head></head><body>another frame text</body></html>');\" href=\"#\">\n"
362                         + "change frame text again</a><br>\n"
363                 + "  <iframe id='innerFrame' name='innerFrame' src='frame1.html'></iframe>\n"
364 
365                 + "  <script>\n"
366                 + "    alert(document.activeElement);\n"
367 
368                 + "    function insertText(text) {\n"
369                 + "      with (innerFrame.document) {\n"
370                 + "        open();\n"
371                 + "        writeln(text);\n"
372                 + "        close();\n"
373                 + "      }\n"
374                 + "      alert(document.activeElement);\n"
375                 + "    }\n"
376                 + "  </script>\n"
377                 + "</body>\n"
378                 + "</html>";
379         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
380 
381         getMockWebConnection().setResponse(new URL("http://example.com/frame1.html"), "");
382 
383         final WebDriver driver = loadPage2(html);
384 
385         expandExpectedAlertsVariables(URL_FIRST);
386         verifyAlerts(driver, getExpectedAlerts()[0]);
387 
388         driver.findElement(By.id("insert")).click();
389         verifyAlerts(driver, getExpectedAlerts()[1]);
390 
391         driver.switchTo().frame(driver.findElement(By.id("innerFrame")));
392         assertEquals("first frame text", driver.findElement(By.tagName("body")).getText());
393 
394         driver.switchTo().defaultContent();
395         driver.findElement(By.id("update")).click();
396         verifyAlerts(driver, getExpectedAlerts()[2]);
397 
398         driver.switchTo().frame(driver.findElement(By.id("innerFrame")));
399         assertEquals("another frame text", driver.findElement(By.tagName("body")).getText());
400     }
401 
402     /**
403      * Verifies that when we create a text node and append it to an existing DOM node,
404      * its <tt>outerHTML</tt>, <tt>innerHTML</tt> and <tt>innerText</tt> properties are
405      * properly escaped.
406      * @throws Exception if the test fails
407      */
408     @Test
409     @Alerts({"<p>a & b</p> &amp; \u0162 \" '",
410              "<p>a & b</p> &amp; \u0162 \" '",
411              "<div id=\"div\">&lt;p&gt;a &amp; b&lt;/p&gt; &amp;amp; \u0162 \" '</div>",
412              "&lt;p&gt;a &amp; b&lt;/p&gt; &amp;amp; \u0162 \" '",
413              "<p>a & b</p> &amp; \u0162 \" '"})
414     public void createTextNodeWithHtml() throws Exception {
415         final String html = DOCTYPE_HTML
416             + "<html>\n"
417             + "<body onload='test()'>\n"
418             + "<script>\n"
419             + LOG_TITLE_FUNCTION
420             + "  function test() {\n"
421             + "    var node = document.createTextNode('<p>a & b</p> &amp; \\u0162 \" \\'');\n"
422             + "    log(node.data);\n"
423             + "    log(node.nodeValue);\n"
424             + "    var div = document.getElementById('div');\n"
425             + "    div.appendChild(node);\n"
426             + "    log(div.outerHTML);\n"
427             + "    log(div.innerHTML);\n"
428             + "    log(div.innerText);\n"
429             + "  }\n"
430             + "</script>\n"
431             + "<div id='div'></div>\n"
432             + "</body></html>";
433 
434         loadPageVerifyTitle2(html);
435     }
436 
437     /**
438      * @throws Exception if an error occurs
439      */
440     @Test
441     @Alerts({"true", "true"})
442     public void queryCommandEnabled() throws Exception {
443         final String html = DOCTYPE_HTML
444             + "<html><body onload='x()'><iframe name='f' id='f'></iframe>\n"
445             + "<script>\n"
446             + LOG_TITLE_FUNCTION
447             + "function x() {\n"
448             + "  var d = window.frames['f'].document;\n"
449             + "  try { log(d.queryCommandEnabled('SelectAll')); } catch(e) { logEx(e); }\n"
450             + "  try { log(d.queryCommandEnabled('sElectaLL')); } catch(e) { logEx(e); }\n"
451             + "}\n"
452             + "</script></body></html>";
453 
454         loadPageVerifyTitle2(html);
455     }
456 
457 
458     /**
459      * @throws Exception if an error occurs
460      */
461     @Test
462     @Alerts(DEFAULT = {"true", "true", "true"},
463             FF = {"false", "false", "false"},
464             FF_ESR = {"false", "false", "false"})
465     @HtmlUnitNYI(FF = {"true", "true", "true"},
466             FF_ESR = {"true", "true", "true"})
467     public void queryCommandEnabledDesignMode() throws Exception {
468         final String html = DOCTYPE_HTML
469             + "<html><body onload='x()'><iframe name='f' id='f'></iframe>\n"
470             + "<script>\n"
471             + LOG_TITLE_FUNCTION
472             + "function x() {\n"
473             + "  var d = window.frames['f'].document;\n"
474             + "  d.designMode = 'on';\n"
475             + "  log(d.queryCommandEnabled('SelectAll'));\n"
476             + "  log(d.queryCommandEnabled('selectall'));\n"
477             + "  log(d.queryCommandEnabled('SeLeCtALL'));\n"
478             + "}\n"
479             + "</script></body></html>";
480 
481         loadPageVerifyTitle2(html);
482     }
483 
484     /**
485      * @throws Exception if the test fails
486      */
487     @Test
488     @Alerts({"bar", "null", "null"})
489     public void getElementById() throws Exception {
490         final String html = DOCTYPE_HTML
491             + "<html><head>\n"
492             + "<script>\n"
493             + LOG_TITLE_FUNCTION
494             + "function doTest() {\n"
495             + "  log(top.document.getElementById('input1').value);\n"
496             + "  log(document.getElementById(''));\n"
497             + "  log(document.getElementById('non existing'));\n"
498             + "}\n"
499             + "</script></head><body onload='doTest()'>\n"
500             + "<form id='form1'>\n"
501             + "<input id='input1' name='foo' type='text' value='bar' />\n"
502             + "</form>\n"
503             + "</body></html>";
504 
505         loadPageVerifyTitle2(html);
506     }
507 
508 
509     /**
510      * @throws Exception if the test fails
511      */
512     @Test
513     @Alerts({"zero", "udef"})
514     public void getElementByIdNull() throws Exception {
515         final String html = DOCTYPE_HTML
516             + "<html><head>\n"
517             + "<script>\n"
518             + LOG_TITLE_FUNCTION
519             + "function doTest() {\n"
520             + "  log(top.document.getElementById(null).name);\n"
521             + "  log(top.document.getElementById(undefined).name);\n"
522             + "}\n"
523             + "</script></head>\n"
524             + "<body onload='doTest()'>\n"
525             + "<form id='form1'>\n"
526             + "<input id='undefined' name='udef' type='text' value='u' />\n"
527             + "<input id='null' name='zero' type='text' value='n' />\n"
528             + "</form>\n"
529             + "</body></html>";
530 
531         loadPageVerifyTitle2(html);
532     }
533 
534     /**
535      * @throws Exception if the test fails
536      */
537     @Test
538     @Alerts({"bar", "null"})
539     public void getElementById_resetId() throws Exception {
540         final String html = DOCTYPE_HTML
541             + "<html><head>\n"
542             + "<script>\n"
543             + LOG_TITLE_FUNCTION
544             + "function doTest() {\n"
545             + "  var input1 = top.document.getElementById('input1');\n"
546             + "  input1.id = 'newId';\n"
547             + "  log(top.document.getElementById('newId').value);\n"
548             + "  log(top.document.getElementById('input1'));\n"
549             + "}\n"
550             + "</script></head><body onload='doTest()'>\n"
551             + "<form id='form1'>\n"
552             + "<input id='input1' name='foo' type='text' value='bar' />\n"
553             + "</form>\n"
554             + "</body></html>";
555 
556         loadPageVerifyTitle2(html);
557     }
558 
559     /**
560      * @throws Exception if the test fails
561      */
562     @Test
563     @Alerts("bar")
564     public void getElementById_setNewId() throws Exception {
565         final String html = DOCTYPE_HTML
566             + "<html><head>\n"
567             + "<script>\n"
568             + LOG_TITLE_FUNCTION
569             + "function doTest() {\n"
570             + "  var div1 = document.getElementById('div1');\n"
571             + "  div1.firstChild.id = 'newId';\n"
572             + "  log(document.getElementById('newId').value);\n"
573             + "}\n"
574             + "</script></head><body onload='doTest()'>\n"
575             + "<form id='form1'>\n"
576             + "<div id='div1'><input name='foo' type='text' value='bar'></div>\n"
577             + "</form>\n"
578             + "</body></html>";
579 
580         loadPageVerifyTitle2(html);
581     }
582 
583     /**
584      * Regression test for bug 740665.
585      * @throws Exception if the test fails
586      */
587     @Test
588     @Alerts("id1")
589     public void getElementById_divId() throws Exception {
590         final String html = DOCTYPE_HTML
591             + "<html><head>\n"
592             + "<script>\n"
593             + LOG_TITLE_FUNCTION
594             + "function doTest() {\n"
595             + "  var element = document.getElementById('id1');\n"
596             + "  log(element.id);\n"
597             + "}\n"
598             + "</script></head><body onload='doTest()'>\n"
599             + "<div id='id1'></div></body></html>";
600 
601         loadPageVerifyTitle2(html);
602     }
603 
604     /**
605      * Regression test for bug 740665.
606      * @throws Exception if the test fails
607      */
608     @Test
609     @Alerts("script1")
610     public void getElementById_scriptId() throws Exception {
611         final String html = DOCTYPE_HTML
612             + "<html><head>\n"
613             + "<script id='script1'>\n"
614             + LOG_TITLE_FUNCTION
615             + "function doTest() {\n"
616             + "  log(top.document.getElementById('script1').id);\n"
617             + "}\n"
618             + "</script></head><body onload='doTest()'>\n"
619             + "</body></html>";
620 
621         loadPageVerifyTitle2(html);
622     }
623 
624     /**
625      * @throws Exception if the test fails
626      */
627     @Test
628     @Alerts({"first", "newest"})
629     public void getElementById_alwaysFirstOneInDocumentOrder() throws Exception {
630         final String html = DOCTYPE_HTML
631             + "<html><body>\n"
632             + "<span id='it' class='first'></span>\n"
633             + "<span id='it' class='second'></span>\n"
634             + "<script>\n"
635             + LOG_TITLE_FUNCTION
636             + "log(document.getElementById('it').className);\n"
637             + "var s = document.createElement('span');\n"
638             + "s.id = 'it';\n"
639             + "s.className = 'newest';\n"
640             + "document.body.insertBefore(s, document.body.firstChild);\n"
641             + "log(document.getElementById('it').className);\n"
642             + "</script></body></html>";
643 
644         loadPageVerifyTitle2(html);
645     }
646 
647     /**
648      * @throws Exception if the test fails
649      */
650     @Test
651     public void createStyleSheet() throws Exception {
652         final String html = DOCTYPE_HTML
653             + "<html><head>\n"
654             + "<script>\n"
655             + LOG_TITLE_FUNCTION
656             + "  function doTest() {\n"
657             + "    if (document.createStyleSheet) {\n"
658             + "      document.createStyleSheet('style.css');\n"
659             + "      for (var si = 0; si < document.styleSheets.length; si++) {\n"
660             + "        var sheet = document.styleSheets[si];\n"
661             + "        log(sheet.href);\n"
662             + "        log(sheet.owningElement.tagName);\n"
663             + "      }\n"
664             + "    }\n"
665             + "  }\n"
666             + "</script></head>\n"
667             + "<body onload='doTest()'>\n"
668             + "  <div id='id1'></div>\n"
669             + "</body></html>";
670 
671         loadPageVerifyTitle2(html);
672     }
673 
674     /**
675      * @throws Exception if the test fails
676      */
677     @Test
678     public void createStyleSheet_emptyUrl() throws Exception {
679         final String html = DOCTYPE_HTML
680             + "<html><head>\n"
681             + LOG_TITLE_FUNCTION
682             + "<script>\n"
683             + "  function doTest() {\n"
684             + "    if (document.createStyleSheet) {\n"
685             + "      document.createStyleSheet(null);\n"
686             + "      document.createStyleSheet('');\n"
687             + "      for (var si = 0; si < document.styleSheets.length; si++) {\n"
688             + "        var sheet = document.styleSheets[si];\n"
689             + "        log(sheet.href);\n"
690             + "      }\n"
691             + "    }\n"
692             + "  }\n"
693             + "</script></head>\n"
694             + "<body onload='doTest()'>\n"
695             + "  <div id='id1'></div>\n"
696             + "</body></html>";
697 
698         loadPageVerifyTitle2(html);
699     }
700 
701     /**
702      * @throws Exception if the test fails
703      */
704     @Test
705     public void createStyleSheet_insertAt() throws Exception {
706         final String html = DOCTYPE_HTML
707             + "<html><head>\n"
708             + "<script>\n"
709             + LOG_TITLE_FUNCTION
710             + "  function doTest() {\n"
711             + "    if (document.createStyleSheet) {\n"
712             + "      document.createStyleSheet('minus1.css', -1);\n"
713             + "      document.createStyleSheet('zero.css', 0);\n"
714             + "      document.createStyleSheet('dotseven.css', 0.7);\n"
715             + "      document.createStyleSheet('seven.css', 7);\n"
716             + "      document.createStyleSheet('none.css');\n"
717             + "      for (var si = 0; si < document.styleSheets.length; si++) {\n"
718             + "        var sheet = document.styleSheets[si];\n"
719             + "        log(sheet.href);\n"
720             + "      }\n"
721             + "    }\n"
722             + "  }\n"
723             + "</script></head>\n"
724             + "<body onload='doTest()'>\n"
725             + "  <div id='id1'></div>\n"
726             + "</body></html>";
727 
728         loadPageVerifyTitle2(html);
729     }
730 
731     /**
732      * @throws Exception if the test fails
733      */
734     @Test
735     @Alerts({"Initial State:loading", "Changed:interactive", "Changed:complete"})
736     public void readyStateEventListener() throws Exception {
737         final String html = DOCTYPE_HTML
738             + "<html><head>\n"
739             + "<script>\n"
740             + LOG_TITLE_FUNCTION
741             + "</script></head>\n"
742             + "<body>\n"
743             + "<script>\n"
744             + "    log('Initial State:' + document.readyState);\n"
745             + "    document.addEventListener('readystatechange', function() {\n"
746             + "        log('Changed:' + document.readyState);\n"
747             + "    });\r\n"
748             + "</script>"
749             + "</body></html>";
750 
751         loadPageVerifyTitle2(html);
752     }
753 }