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