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.xml;
16  
17  import static java.nio.charset.StandardCharsets.ISO_8859_1;
18  
19  import java.net.URL;
20  
21  import org.htmlunit.WebDriverTestCase;
22  import org.htmlunit.junit.annotation.Alerts;
23  import org.htmlunit.junit.annotation.HtmlUnitNYI;
24  import org.htmlunit.util.MimeType;
25  import org.junit.jupiter.api.Test;
26  import org.openqa.selenium.By;
27  import org.openqa.selenium.WebDriver;
28  
29  /**
30   * Tests for {@link XMLDocument}.
31   *
32   * @author Ahmed Ashour
33   * @author Marc Guillemot
34   * @author Chuck Dumont
35   * @author Frank Danek
36   * @author Ronald Brill
37   */
38  public class XMLDocumentTest extends WebDriverTestCase {
39  
40      private static final String LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION_NAME = "loadXMLDocumentFromFile";
41  
42      /** Helper. */
43      public static final String LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION = ""
44              + "  function " + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION_NAME + "(file) {\n"
45              + "    xhttp = new XMLHttpRequest();\n"
46              + "    xhttp.open(\"GET\", file, false);\n"
47              + "    xhttp.send();\n"
48              + "    return xhttp.responseXML;\n"
49              + "  }\n";
50  
51      /** Helper. */
52      public static final String LOAD_NATIVE_XML_DOCUMENT_FROM_FILE_FUNCTION = ""
53              + "  function " + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION_NAME + "(file) {\n"
54              + "    xhttp = new XMLHttpRequest();\n"
55              + "    xhttp.open(\"GET\", file, false);\n"
56              + "    xhttp.send();\n"
57              + "    return xhttp.responseXML;\n"
58              + "  }\n";
59  
60      /**
61       * Helper.
62       * @param file the file parameter
63       * @return xml helper
64       */
65      public static String callLoadXMLDocumentFromFile(final String file) {
66          return LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION_NAME + "(" + file + ")";
67      }
68  
69      private static final String LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION_NAME = "loadXMLDocumentFromString";
70  
71      /** Helper. */
72      public static final String LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION = ""
73              + "  function " + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION_NAME + "(xml) {\n"
74              + "    var parser = new DOMParser();\n"
75              + "    return parser.parseFromString(xml,\"text/xml\");\n"
76              + "  }\n";
77  
78      /**
79       * Helper.
80       * @param string the parameter
81       * @return xml helper
82       */
83      public static String callLoadXMLDocumentFromString(final String string) {
84          return LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION_NAME + "(" + string + ")";
85      }
86  
87      private static final String SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION_NAME = "serializeXMLDocumentToString";
88  
89      /** Helper. */
90      public static final String SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION = ""
91              + "  function " + SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION_NAME + "(doc) {\n"
92              + "    return new XMLSerializer().serializeToString(doc);\n"
93              + "  }\n";
94  
95      /** Helper. */
96      public static final String SERIALIZE_NATIVE_XML_DOCUMENT_TO_STRING_FUNCTION = ""
97              + "  function " + SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION_NAME + "(doc) {\n"
98              + "    serializer = new XMLSerializer();\n"
99              + "    return serializer.serializeToString(doc);\n"
100             + "  }\n";
101 
102     /**
103      * Helper.
104      * @param doc the doc parameter
105      * @return xml helper
106      */
107     public static String callSerializeXMLDocumentToString(final String doc) {
108         return SERIALIZE_XML_DOCUMENT_TO_STRING_FUNCTION_NAME + "(" + doc + ")";
109     }
110 
111     /**
112      * @throws Exception if the test fails
113      */
114     @Test
115     @Alerts({"undefined", "undefined"})
116     public void async() throws Exception {
117         final String html = DOCTYPE_HTML
118             + "<html><head>\n"
119             + "<script>\n"
120             + LOG_TITLE_FUNCTION
121             + "  function test() {\n"
122             + "    var doc = document.implementation.createDocument('', '', null);\n"
123             + "    log(document.async);\n"
124             + "    log(doc.async);\n"
125             + "  }\n"
126             + "</script></head>\n"
127             + "<body onload='test()'>\n"
128             + "</body></html>";
129         loadPageVerifyTitle2(html);
130     }
131 
132     /**
133      * @throws Exception if the test fails
134      */
135     @Test
136     @Alerts("TypeError")
137     public void load() throws Exception {
138         final String html = DOCTYPE_HTML
139             + "<html><head>\n"
140             + "<script>\n"
141             + LOG_TITLE_FUNCTION
142             + "  function test() {\n"
143             + "    var doc = document.implementation.createDocument('', '', null);\n"
144             + "    doc.async = false;\n"
145             + "    try {\n"
146             + "      log(doc.load('" + URL_SECOND + "'));\n"
147             + "      log(doc.documentElement.nodeName);\n"
148             + "      log(doc.childNodes[0].nodeName);\n"
149             + "      log(doc.childNodes[0].childNodes.length);\n"
150             + "      log(doc.childNodes[0].childNodes[0].nodeName);\n"
151             + "      log(doc.getElementsByTagName('books').item(0).attributes.length);\n"
152             + "    } catch(e) { logEx(e); }\n"
153             + "  }\n"
154             + "</script></head>\n"
155             + "<body onload='test()'>\n"
156             + "</body></html>";
157 
158         final String xml
159             = "<books>\n"
160             + "  <book>\n"
161             + "    <title>Immortality</title>\n"
162             + "    <author>John Smith</author>\n"
163             + "  </book>\n"
164             + "</books>";
165 
166         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
167         loadPageVerifyTitle2(html);
168     }
169 
170     /**
171      * @throws Exception if the test fails
172      */
173     @Test
174     @Alerts("TypeError")
175     // TODO what is the difference to load()?
176     public void load_relativeURL() throws Exception {
177         final String html = DOCTYPE_HTML
178             + "<html><head>\n"
179             + "<script>\n"
180             + LOG_TITLE_FUNCTION
181             + "  function test() {\n"
182             + "    var doc = document.implementation.createDocument('', '', null);\n"
183             + "    doc.async = false;\n"
184             + "    try {\n"
185             + "      log(doc.load('" + URL_SECOND + "'));\n"
186             + "      log(doc.documentElement.nodeName);\n"
187             + "      log(doc.childNodes[0].nodeName);\n"
188             + "      log(doc.childNodes[0].childNodes.length);\n"
189             + "      log(doc.childNodes[0].childNodes[0].nodeName);\n"
190             + "      log(doc.getElementsByTagName('books').item(0).attributes.length);\n"
191             + "    } catch(e) { logEx(e); }\n"
192             + "  }\n"
193             + "</script></head>\n"
194             + "<body onload='test()'>\n"
195             + "</body></html>";
196 
197         final String xml
198             = "<books>\n"
199             + "  <book>\n"
200             + "    <title>Immortality</title>\n"
201             + "    <author>John Smith</author>\n"
202             + "  </book>\n"
203             + "</books>";
204 
205         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
206         loadPageVerifyTitle2(html);
207     }
208 
209     /**
210      * @throws Exception if the test fails
211      */
212     @Test
213     @Alerts("undefined")
214     public void preserveWhiteSpace() throws Exception {
215         final String html = DOCTYPE_HTML
216             + "<html><head>\n"
217             + "<script>\n"
218             + LOG_TITLE_FUNCTION
219             + "  function test() {\n"
220             + "    var doc = document.implementation.createDocument('', '', null);\n"
221             + "    log(doc.preserveWhiteSpace);\n"
222             + "  }\n"
223             + "</script></head>\n"
224             + "<body onload='test()'>\n"
225             + "</body></html>";
226         loadPageVerifyTitle2(html);
227     }
228 
229     /**
230      * @throws Exception if the test fails
231      */
232     @Test
233     @Alerts("TypeError")
234     public void setProperty() throws Exception {
235         final String html = DOCTYPE_HTML
236             + "<html><head>\n"
237             + "<script>\n"
238             + LOG_TITLE_FUNCTION
239             + "  function test() {\n"
240             + "    var doc = document.implementation.createDocument('', '', null);\n"
241             + "    try {\n"
242             + "      doc.setProperty('SelectionNamespaces', \"xmlns:xsl='http://www.w3.org/1999/XSL/Transform'\");\n"
243             + "      doc.setProperty('SelectionLanguage', 'XPath');\n"
244             + "    } catch(e) { logEx(e); }\n"
245             + "  }\n"
246             + "</script></head><body onload='test()'>\n"
247             + "</body></html>";
248         loadPageVerifyTitle2(html);
249     }
250 
251     /**
252      * @throws Exception if the test fails
253      */
254     @Test
255     @Alerts("TypeError")
256     public void selectNodes() throws Exception {
257         final String html = DOCTYPE_HTML
258             + "<html><head>\n"
259             + "<script>\n"
260             + LOG_TITLE_FUNCTION
261             + "  function test() {\n"
262             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
263             + "    try {\n"
264             + "      var nodes = doc.selectNodes('/books');\n"
265             + "      log(nodes.length);\n"
266             + "      log(nodes[0].tagName);\n"
267             + "    } catch(e) { logEx(e); }\n"
268             + "  }\n"
269             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
270             + "</script></head>\n"
271             + "<body onload='test()'>\n"
272             + "</body></html>";
273 
274         final String xml
275             = "<books>\n"
276             + "  <book>\n"
277             + "    <title>Immortality</title>\n"
278             + "    <author>John Smith</author>\n"
279             + "  </book>\n"
280             + "</books>";
281 
282         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
283         loadPageVerifyTitle2(html);
284     }
285 
286     /**
287      * @throws Exception if the test fails
288      */
289     @Test
290     @Alerts("TypeError")
291     public void selectNodes_caseSensitive() throws Exception {
292         final String html = DOCTYPE_HTML
293             + "<html><head>\n"
294             + "<script>\n"
295             + LOG_TITLE_FUNCTION
296             + "  function test() {\n"
297             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
298             + "    try {\n"
299             + "      log(doc.selectNodes('/bOoKs').length);\n"
300             + "      log(doc.selectNodes('/books').length);\n"
301             + "    } catch(e) { logEx(e); }\n"
302             + "  }\n"
303             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
304             + "</script></head>\n"
305             + "<body onload='test()'>\n"
306             + "</body></html>";
307 
308         final String xml
309             = "<books>\n"
310             + "  <book>\n"
311             + "    <title>Immortality</title>\n"
312             + "    <author>John Smith</author>\n"
313             + "  </book>\n"
314             + "</books>";
315 
316         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
317         loadPageVerifyTitle2(html);
318     }
319 
320     /**
321      * @throws Exception if the test fails
322      */
323     @Test
324     @Alerts("TypeError")
325     public void selectNodes_namespace() throws Exception {
326         final String html = DOCTYPE_HTML
327             + "<html><head>\n"
328             + "<script>\n"
329             + LOG_TITLE_FUNCTION
330             + "  function test() {\n"
331             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
332             + "    try {\n"
333             + "      log(doc.selectNodes('//ns1:title').length);\n"
334             + "      log(doc.selectNodes('//ns2:title').length);\n"
335             + "    } catch(e) { logEx(e); }\n"
336             + "  }\n"
337             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
338             + "</script></head>\n"
339             + "<body onload='test()'>\n"
340             + "</body></html>";
341         final String xml
342             = "<ns1:books xmlns:ns1=\"http://one\">\n"
343             + "  <ns2:book xmlns:ns2=\"http://two\">\n"
344             + "    <ns2:title>Immortality</ns2:title>\n"
345             + "    <ns2:author>John Smith</ns2:author>\n"
346             + "  </ns2:book>\n"
347             + "  <ns1:book>\n"
348             + "    <ns1:title>The Hidden Secrets</ns1:title>\n"
349             + "    <ns1:author>William Adams</ns1:author>\n"
350             + "  </ns1:book>\n"
351             + "  <ns1:book>\n"
352             + "    <ns1:title>So What?</ns1:title>\n"
353             + "    <ns1:author>Tony Walas</ns1:author>\n"
354             + "  </ns1:book>\n"
355             + "</ns1:books>";
356 
357         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
358         loadPageVerifyTitle2(html);
359     }
360 
361     /**
362      * @throws Exception if the test fails
363      */
364     @Test
365     @Alerts("TypeError")
366     public void selectNodes_nextNodeAndReset() throws Exception {
367         final String html = DOCTYPE_HTML
368             + "<html><head>\n"
369             + "<script>\n"
370             + LOG_TITLE_FUNCTION
371             + "  function test() {\n"
372             + "    try {\n"
373             + "      var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
374             + "      var nodes = doc.selectNodes('//book');\n"
375             + "      log(nodes.nextNode().nodeName);\n"
376             + "      log(nodes.nextNode());\n"
377             + "      nodes.reset();\n"
378             + "      log(nodes.nextNode().nodeName);\n"
379             + "      log(nodes.nextNode());\n"
380             + "    } catch(e) { logEx(e); }\n"
381             + "  }\n"
382             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
383             + "</script></head>\n"
384             + "<body onload='test()'>foo</body></html>";
385 
386         final String xml
387             = "<books>\n"
388             + "  <book>\n"
389             + "    <title>Immortality</title>\n"
390             + "    <author>John Smith</author>\n"
391             + "  </book>\n"
392             + "</books>";
393 
394         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
395         loadPageVerifyTitle2(html);
396     }
397 
398     /**
399      * Test that element.selectNodes("/tagName") searches from root of the tree, not from that specific element.
400      * @throws Exception if the test fails
401      */
402     @Test
403     @Alerts({"book", "exception /title", "TypeError", "exception title", "TypeError"})
404     public void selectNodes_fromRoot() throws Exception {
405         final String html = DOCTYPE_HTML
406             + "<html><head>\n"
407             + "<script>\n"
408             + LOG_TITLE_FUNCTION
409             + "  function test() {\n"
410             + "    try {\n"
411             + "      var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
412             + "      var child = doc.documentElement.firstChild;\n"
413             + "      log(child.tagName);\n"
414 
415             + "      try {\n"
416             + "        log(child.selectNodes('/title').length);\n"
417             + "      } catch(e) { log('exception /title'); logEx(e); }\n"
418 
419             + "      try {\n"
420             + "        log(child.selectNodes('title').length);\n"
421             + "      } catch(e) { log('exception title'); logEx(e); }\n"
422             + "    } catch(e) { logEx(e); }\n"
423             + "  }\n"
424             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
425             + "</script></head>\n"
426             + "<body onload='test()'>foo</body></html>";
427 
428         final String xml = "<books><book><title>Immortality</title><author>John Smith</author></book></books>";
429 
430         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
431         loadPageVerifyTitle2(html);
432     }
433 
434     /**
435      * @throws Exception if the test fails
436      */
437     @Test
438     @Alerts("TypeError")
439     public void selectSingleNode() throws Exception {
440         final String html = DOCTYPE_HTML
441             + "<html><head>\n"
442             + "<script>\n"
443             + LOG_TITLE_FUNCTION
444             + "  function test() {\n"
445             + "    var text='<book/>';\n"
446             + "    try {\n"
447             + "      var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
448             + "      log(doc.selectNodes('*')[0].nodeName);\n"
449             + "      log(doc.selectNodes('/')[0].nodeName);\n"
450             + "      log(doc.selectSingleNode('*').nodeName);\n"
451             + "      log(doc.selectNodes('*')[0].selectSingleNode('/').nodeName);\n"
452             + "    } catch(e) { logEx(e); }\n"
453             + "  }\n"
454             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
455             + "</script></head><body onload='test()'>\n"
456             + "</body></html>";
457         loadPageVerifyTitle2(html);
458     }
459 
460     /**
461      * @throws Exception if the test fails
462      */
463     @Test
464     @Alerts("someprefix:test")
465     public void loadXML_Namespace() throws Exception {
466         final String html = DOCTYPE_HTML
467             + "<html><head>\n"
468             + "<script>\n"
469             + LOG_TITLE_FUNCTION
470             + "  function test() {\n"
471             + "    var text='<someprefix:test xmlns:someprefix=\"http://myNS\"/>';\n"
472             + "    var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
473             + "    log(doc.documentElement.tagName);\n"
474             + "  }\n"
475             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
476             + "</script></head>\n"
477             + "<body onload='test()'>\n"
478             + "</body></html>";
479         loadPageVerifyTitle2(html);
480     }
481 
482     /**
483      * Tests "xml:space" attribute.
484      *
485      * Xalan team response:<br>
486      * "See the DOM Level 3 recommendation for discussion of this. XPath returns the start of the XPath text node,
487      * which spans multiple DOM nodes. It is the DOM user's responsibility to gather the additional nodes,
488      * either manually or by retrieving wholeText rather than value.<br>
489      * This is unavoidable since DOM and XPath define the concept of "node" differently."
490      *
491      * @throws Exception if the test fails
492      */
493     @Test
494     @Alerts("7")
495     public void loadXML_XMLSpaceAttribute() throws Exception {
496         final String html = DOCTYPE_HTML
497             + "<html><head>\n"
498             + "<script>\n"
499             + LOG_TITLE_FUNCTION
500             + "  function test() {\n"
501             + "    var text='<root xml:space=\\'preserve\\'>This t"
502             + "<elem>ext has</elem> <![CDATA[ CDATA ]]>in<elem /> it</root>';\n"
503             + "    var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
504             + "    log(doc.documentElement.childNodes.length);\n"
505             + "  }\n"
506             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
507             + "</script></head>\n"
508             + "<body onload='test()'>\n"
509             + "</body></html>";
510 
511         loadPageVerifyTitle2(html);
512     }
513 
514     /**
515      * @throws Exception if the test fails
516      */
517     @Test
518     @Alerts("ReferenceError")
519     public void parseError() throws Exception {
520         final String html = DOCTYPE_HTML
521             + "<html><head>\n"
522             + "<script>\n"
523             + LOG_TITLE_FUNCTION
524             + "  function test() {\n"
525             + "    try {\n"
526             + "      var doc = new ActiveXObject('Microsoft.XMLDOM');\n"
527             + "      log(doc.documentElement == null);\n"
528             + "      log(doc.parseError.errorCode === 0);\n"
529             + "      log(doc.parseError.filepos === 0);\n"
530             + "      log(doc.parseError.line === 0);\n"
531             + "      log(doc.parseError.linepos === 0);\n"
532             + "      log(doc.parseError.reason === '');\n"
533             + "      log(doc.parseError.srcText === '');\n"
534             + "      log(doc.parseError.url === '');\n"
535             + "      doc.async = false;\n"
536             + "      log(doc.load('" + URL_SECOND + "'));\n"
537             + "      log(doc.documentElement == null);\n"
538             + "      log(doc.parseError.errorCode !== 0);\n"
539             + "      log(doc.parseError.filepos !== 0);\n"
540             + "      log(doc.parseError.line !== 0);\n"
541             + "      log(doc.parseError.linepos !== 0);\n"
542             + "      log(doc.parseError.reason !== '');\n"
543             + "      log(doc.parseError.srcText !== '');\n"
544             + "      log(doc.parseError.url !== '');\n"
545             + "    } catch(e) { logEx(e); }\n"
546             + "  }\n"
547             + "</script></head>\n"
548             + "<body onload='test()'>\n"
549             + "</body></html>";
550 
551         final String xml
552             = "<root>\n"
553             + "  <element>\n"
554             + "</root>";
555 
556         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
557         loadPageVerifyTitle2(html);
558     }
559 
560     /**
561      * @throws Exception if the test fails
562      */
563     @Test
564     @Alerts("http://myNS")
565     public void createNSResolver() throws Exception {
566         final String html = DOCTYPE_HTML
567             + "<html><head>\n"
568             + "<script>\n"
569             + LOG_TITLE_FUNCTION
570             + "  function test() {\n"
571             + "    var text='<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\\n';\n"
572             + "    text += '<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://myNS\">\\n';\n"
573             + "    text += '  <xsl:template match=\"/\">\\n';\n"
574             + "    text += '  <html>\\n';\n"
575             + "    text += '    <body>\\n';\n"
576             + "    text += '    </body>\\n';\n"
577             + "    text += '  </html>\\n';\n"
578             + "    text += '  </xsl:template>\\n';\n"
579             + "    text += '</xsl:stylesheet>';\n"
580             + "    var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
581             + "    if (doc.createNSResolver) {\n"
582             + "      log(doc.createNSResolver(doc.documentElement).lookupNamespaceURI('xsl'));\n"
583             + "    }\n"
584             + "  }\n"
585             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
586             + "</script></head>\n"
587             + "<body onload='test()'>\n"
588             + "</body></html>";
589         loadPageVerifyTitle2(html);
590     }
591 
592     /**
593      * @throws Exception if the test fails
594      */
595     @Test
596     @Alerts("TypeError")
597     public void xmlInsideHtml() throws Exception {
598         final String html = DOCTYPE_HTML
599             + "<html><head>\n"
600             + "<script>\n"
601             + LOG_TITLE_FUNCTION
602             + "  function test() {\n"
603             + "    try {\n"
604             + "      log(messageTableHeaders.documentElement.nodeName);\n"
605             + "    } catch(e) {logEx(e); }\n"
606             + "  }\n"
607             + "</script>\n"
608             + "</head>\n"
609             + "<body onload='test()'>\n"
610             + "  <xml id='messageTableHeaders'>\n"
611             + "    <columns>\n"
612             + "      <column name='_checkbox'/>\n"
613             + "      <column name='itemStatus'/>\n"
614             + "    </columns>\n"
615             + "  </xml>\n"
616             + "</body></html>";
617         loadPageVerifyTitle2(html);
618     }
619 
620     /**
621      * @throws Exception if the test fails
622      */
623     @Test
624     @Alerts("true")
625     public void instanceOf() throws Exception {
626         final String html = DOCTYPE_HTML
627             + "<html><head>\n"
628             + "<script>\n"
629             + LOG_TITLE_FUNCTION
630             + "  function test() {\n"
631             + "    var x = " + callLoadXMLDocumentFromString("'<x/>'") + ";\n"
632             + "    try {\n"
633             + "      log(x instanceof XMLDocument);\n"
634             + "    }catch(e) { logEx(e) }\n"
635             + "  }\n"
636             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
637             + "</script>\n"
638             + "</head>\n"
639             + "<body onload='test()'>\n"
640             + "  <xml id='messageTableHeaders'>\n"
641             + "    <columns>\n"
642             + "      <column name='_checkbox'/>\n"
643             + "      <column name='itemStatus'/>\n"
644             + "    </columns>\n"
645             + "  </xml>\n"
646             + "</body></html>";
647         loadPageVerifyTitle2(html);
648     }
649 
650     /**
651      * @throws Exception if the test fails
652      */
653     @Test
654     @Alerts("button")
655     public void evaluate() throws Exception {
656         final String html = DOCTYPE_HTML
657             + "<html><head>\n"
658             + "<script>\n"
659             + LOG_TITLE_FUNCTION
660             + "  function test() {\n"
661             + "    var s = '<toolbar><button id=\"compose_button\"/></toolbar>';\n"
662             + "    var xDoc = " + callLoadXMLDocumentFromString("s") + ";\n"
663             + "    if (xDoc.evaluate) {\n"
664             + "      var r = xDoc.evaluate(\"button[@id='compose_button']\", xDoc.firstChild, null, 9, null);\n"
665             + "      log(r.singleNodeValue.tagName);\n"
666             + "    }\n"
667             + "  }\n"
668             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
669             + "</script></head>\n"
670             + "<body onload='test()'>\n"
671             + "</body></html>";
672         loadPageVerifyTitle2(html);
673     }
674 
675     /**
676      * @throws Exception if the test fails
677      */
678     @Test
679     @Alerts({"same doc: false", "in first: 3", "book", "ownerDocument: doc1", "getRootNode(): doc1",
680              "in 2nd: 3", "ownerDocument: doc2", "getRootNode(): doc2",
681              "first child ownerDocument: doc2", "first child getRootNode(): doc2", "in first: 2", "in 2nd: 4",
682              "ownerDocument: doc1", "getRootNode(): doc1", "in first: 2", "in 2nd: 3",
683              "ownerDocument: doc2", "getRootNode(): doc2", "in first: 1", "in 2nd: 4"})
684     public void moveChildBetweenDocuments() throws Exception {
685         final String html = DOCTYPE_HTML
686             + "<html><head>\n"
687             + "<script>\n"
688             + LOG_TITLE_FUNCTION
689             + "function test() {\n"
690             + "  var doc1 = " + callLoadXMLDocumentFromFile("'foo.xml'") + ";\n"
691             + "  var doc2 = " + callLoadXMLDocumentFromFile("'foo.xml'") + ";\n"
692             + "  log('same doc: ' + (doc1 == doc2));\n"
693             + "  var doc1Root = doc1.firstChild;\n"
694             + "  log('in first: ' + doc1Root.childNodes.length);\n"
695             + "  var doc1RootOriginalFirstChild = doc1Root.firstChild;\n"
696             + "  log(doc1RootOriginalFirstChild.tagName);\n"
697 
698             + "  var hasRootNode = doc1RootOriginalFirstChild.getRootNode !== undefined;\n"
699             + "  log('ownerDocument: ' + (doc1RootOriginalFirstChild.ownerDocument === doc1 ? 'doc1' : 'doc2'));\n"
700             + "  hasRootNode ? log('getRootNode(): ' "
701                                 + "+ (doc1RootOriginalFirstChild.getRootNode() === doc1 ? 'doc1' : 'doc2'))"
702                                 + " : log('-');\n"
703             + "\n"
704             + "  var doc2Root = doc2.firstChild;\n"
705             + "  log('in 2nd: ' + doc2Root.childNodes.length);\n"
706             + "  doc2Root.appendChild(doc1RootOriginalFirstChild);\n"
707             + "  log('ownerDocument: ' + (doc1RootOriginalFirstChild.ownerDocument === doc1 ? 'doc1' : 'doc2'));\n"
708             + "  hasRootNode ? log('getRootNode(): ' "
709                                 + "+ (doc1RootOriginalFirstChild.getRootNode() === doc1 ? 'doc1' : 'doc2'))"
710                                 + " : log('-');\n"
711             + "  log('first child ownerDocument: ' + "
712                     + "(doc1RootOriginalFirstChild.firstChild.ownerDocument === doc1 ? 'doc1' : 'doc2'));\n"
713             + "  hasRootNode ? log('first child getRootNode(): ' + "
714                     + "(doc1RootOriginalFirstChild.firstChild.getRootNode() === doc1 ? 'doc1' : 'doc2')) : log('-');\n"
715             + "  log('in first: ' + doc1Root.childNodes.length);\n"
716             + "  log('in 2nd: ' + doc2Root.childNodes.length);\n"
717             + "\n"
718             + "  doc1Root.replaceChild(doc1RootOriginalFirstChild, doc1Root.firstChild);\n"
719             + "  log('ownerDocument: ' + (doc1RootOriginalFirstChild.ownerDocument === doc1 ? 'doc1' : 'doc2'));\n"
720             + "  hasRootNode ? log('getRootNode(): ' "
721                                 + "+ (doc1RootOriginalFirstChild.getRootNode() === doc1 ? 'doc1' : 'doc2'))"
722                                 + " : log('-');\n"
723             + "  log('in first: ' + doc1Root.childNodes.length);\n"
724             + "  log('in 2nd: ' + doc2Root.childNodes.length);\n"
725             + "\n"
726             + "  doc2Root.insertBefore(doc1RootOriginalFirstChild, doc2Root.firstChild);\n"
727             + "  log('ownerDocument: ' + (doc1RootOriginalFirstChild.ownerDocument === doc1 ? 'doc1' : 'doc2'));\n"
728             + "  hasRootNode ? log('getRootNode(): ' "
729                                 + "+ (doc1RootOriginalFirstChild.getRootNode() === doc1 ? 'doc1' : 'doc2'))"
730                                 + " : log('-');\n"
731             + "  log('in first: ' + doc1Root.childNodes.length);\n"
732             + "  log('in 2nd: ' + doc2Root.childNodes.length);\n"
733             + "\n"
734             + "}\n"
735             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
736             + "</script></head>\n"
737             + "<body onload='test()'>\n"
738             + "</body></html>";
739 
740         final String xml = "<order><book><title/></book><cd/><dvd/></order>";
741 
742         getMockWebConnection().setResponse(new URL(URL_FIRST, "foo.xml"), xml, MimeType.TEXT_XML);
743         loadPageVerifyTitle2(html);
744     }
745 
746     /**
747      * @throws Exception if the test fails
748      */
749     @Test
750     @Alerts({"1", "0", "1", "0"})
751     public void getElementsByTagName() throws Exception {
752         final String html = DOCTYPE_HTML
753             + "<html><head>\n"
754             + "<script>\n"
755             + LOG_TITLE_FUNCTION
756             + "  function test() {\n"
757             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
758             + "    log(doc.getElementsByTagName('book').length);\n"
759             + "    log(doc.getElementsByTagName('soap:book').length);\n"
760             + "    var elem = doc.getElementsByTagName('book')[0];\n"
761             + "    log(elem.getElementsByTagName('title').length);\n"
762             + "    log(elem.getElementsByTagName('soap:title').length);\n"
763             + "  }\n"
764             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
765             + "</script></head>\n"
766             + "<body onload='test()'>\n"
767             + "</body></html>";
768 
769         final String xml
770             = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\n"
771             + "  <books xmlns='http://www.example.com/ns1'>\n"
772             + "    <book>\n"
773             + "      <title>Immortality</title>\n"
774             + "      <author>John Smith</author>\n"
775             + "    </book>\n"
776             + "  </books>\n"
777             + "</soap:Envelope>";
778 
779         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
780         loadPageVerifyTitle2(html);
781     }
782 
783     /**
784      * @throws Exception if the test fails
785      */
786     @Test
787     @Alerts({"0", "1", "0", "1"})
788     public void getElementsByTagNameWithNamespace() throws Exception {
789         final String html = DOCTYPE_HTML
790             + "<html><head>\n"
791             + "<script>\n"
792             + LOG_TITLE_FUNCTION
793             + "  function test() {\n"
794             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
795             + "    log(doc.getElementsByTagName('book').length);\n"
796             + "    log(doc.getElementsByTagName('soap:book').length);\n"
797             + "    if (doc.getElementsByTagName('soap:book').length != 0) {\n"
798             + "      var elem = doc.getElementsByTagName('soap:book')[0];\n"
799             + "      log(elem.getElementsByTagName('title').length);\n"
800             + "      log(elem.getElementsByTagName('soap:title').length);\n"
801             + "    }\n"
802             + "  }\n"
803             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
804             + "</script></head>\n"
805             + "<body onload='test()'>\n"
806             + "</body></html>";
807 
808         final String xml
809             = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\n"
810             + "  <books xmlns='http://www.example.com/ns1'>\n"
811             + "    <soap:book>\n"
812             + "      <soap:title>Immortality</soap:title>\n"
813             + "      <author>John Smith</author>\n"
814             + "    </soap:book>\n"
815             + "  </books>\n"
816             + "</soap:Envelope>";
817 
818         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
819         loadPageVerifyTitle2(html);
820     }
821 
822     /**
823      * @throws Exception if the test fails
824      */
825     @Test
826     @Alerts({"false", "false", "true", "false"})
827     // XML ID handling not yet correctly implemented
828     public void getElementById_xml() throws Exception {
829         final String html = DOCTYPE_HTML
830             + "<html><head>\n"
831             + "<script>\n"
832             + LOG_TITLE_FUNCTION
833             + "  function test() {\n"
834             + "    var text='<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n'\n"
835             + "      + '<!DOCTYPE idTest [\\n'\n"
836             + "      + '    <!ATTLIST item xId ID #IMPLIED>\\n'\n"
837             + "      + ']>\\n'\n"
838             + "      + '<idTest>\\n'\n"
839             + "      + '    <item xId=\"item1\" />\\n'\n"
840             + "      + '    <item xml:id=\"item2\" />\\n'\n"
841             + "      + '    <item id=\"item3\" />\\n'\n"
842             + "      + '    <item ID=\"item4\" />\\n'\n"
843             + "      + '</idTest>';\n"
844             + "    try {\n"
845             + "      var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
846             + "      log(doc.getElementById('item1') != null);\n"
847             + "      log(doc.getElementById('item2') != null);\n"
848             + "      log(doc.getElementById('item3') != null);\n"
849             + "      log(doc.getElementById('item4') != null);\n"
850             + "    } catch(e) { logEx(e); }\n"
851             + "  }\n"
852             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
853             + "</script></head>\n"
854             + "<body onload='test()'>\n"
855             + "</body></html>";
856         loadPageVerifyTitle2(html);
857     }
858 
859     /**
860      * @throws Exception if the test fails
861      */
862     @Test
863     @Alerts({"true", "true"})
864     // XML ID handling not yet correctly implemented
865     public void getElementById_html() throws Exception {
866         final String html = DOCTYPE_HTML
867             + "<html><head>\n"
868             + "<script>\n"
869             + LOG_TITLE_FUNCTION
870             + "  function test() {\n"
871             + "    var text='<form id=\"form1\">\\n'\n"
872             + "      + '    <div id=\"div1\"></div>\\n'\n"
873             + "      + '</form>';\n"
874             + "    try {\n"
875             + "      var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
876             + "      log(doc.getElementById('form1') != null);\n"
877             + "      log(doc.getElementById('div1') != null);\n"
878             + "    } catch(e) { logEx(e); }\n"
879             + "  }\n"
880             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
881             + "</script></head>\n"
882             + "<body onload='test()'>\n"
883             + "</body></html>";
884         loadPageVerifyTitle2(html);
885     }
886 
887     /**
888      * @throws Exception if the test fails
889      */
890     @Test
891     @Alerts({"true", "true"})
892     public void getElementById_xhtml() throws Exception {
893         final String html = DOCTYPE_HTML
894             + "<html><head>\n"
895             + "<script>\n"
896             + LOG_TITLE_FUNCTION
897             + "  function test() {\n"
898             + "    var text='<form xmlns=\"http://www.w3.org/1999/xhtml\" id=\"form1\">\\n'\n"
899             + "      + '    <div id=\"div1\"></div>\\n'\n"
900             + "      + '</form>';\n"
901             + "    try {\n"
902             + "      var doc = " + callLoadXMLDocumentFromString("text") + ";\n"
903             + "      log(doc.getElementById('form1') != null);\n"
904             + "      log(doc.getElementById('div1') != null);\n"
905             + "    } catch(e) { logEx(e); }\n"
906             + "  }\n"
907             + LOAD_XML_DOCUMENT_FROM_STRING_FUNCTION
908             + "</script></head>\n"
909             + "<body onload='test()'>\n"
910             + "</body></html>";
911         loadPageVerifyTitle2(html);
912     }
913 
914     /**
915      * @throws Exception if the test fails
916      */
917     @Test
918     @Alerts("0")
919     public void xpathWithNamespaces() throws Exception {
920         final String html = DOCTYPE_HTML
921             + "<html><head>\n"
922             + "<script>\n"
923             + LOG_TITLE_FUNCTION
924             + "  function test() {\n"
925             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
926             + "    try {\n"
927             + "      log(doc.selectNodes('//soap:book').length);\n"
928             + "    } catch(e) {\n"
929             + "      try {\n"
930             + "      log(doc.evaluate('count(//book)', doc.documentElement, "
931             + "null, XPathResult.NUMBER_TYPE, null).numberValue);\n"
932             + "      } catch(e) {\n"
933             + "        logEx(e);\n"
934             + "      }\n"
935             + "    }\n"
936             + "  }\n"
937             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
938             + "</script></head>\n"
939             + "<body onload='test()'>\n"
940             + "</body></html>";
941 
942         final String xml
943             = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\n"
944             + "  <books xmlns='http://www.example.com/ns1'>\n"
945             + "    <soap:book>\n"
946             + "      <title>Immortality</title>\n"
947             + "      <author>John Smith</author>\n"
948             + "    </soap:book>\n"
949             + "  </books>\n"
950             + "</soap:Envelope>";
951 
952         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
953         loadPageVerifyTitle2(html);
954     }
955 
956     /**
957      * @throws Exception if the test fails
958      */
959     @Test
960     @Alerts({})
961     public void selectionNamespaces() throws Exception {
962         final String html = DOCTYPE_HTML
963             + "<html><head>\n"
964             + "<script>\n"
965             + LOG_TITLE_FUNCTION
966             + "  var selectionNamespaces = 'xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
967                             + "xmlns:ns1=\"http://www.example.com/ns1\"';\n"
968             + "  function test() {\n"
969             + "  if ('ActiveXObject' in window) {\n"
970             + "    var doc = new ActiveXObject('Microsoft.XMLDOM');\n"
971             + "    doc.setProperty('SelectionNamespaces', selectionNamespaces);\n"
972             + "    doc.async = false;\n"
973             + "    doc.load('" + URL_SECOND + "');\n"
974             + "    try {\n"
975             + "      log(doc.selectNodes('/s:Envelope/ns1:books/s:book').length);\n"
976             + "    } catch(e) {\n"
977             + "      log(doc.evaluate('count(//book)', doc.documentElement, "
978             + "null, XPathResult.NUMBER_TYPE, null).numberValue);\n"
979             + "    }}\n"
980             + "  }\n"
981             + "</script></head>\n"
982             + "<body onload='test()'>\n"
983             + "</body></html>";
984 
985         final String xml
986             = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>\n"
987             + "  <books xmlns='http://www.example.com/ns1'>\n"
988             + "    <soap:book>\n"
989             + "      <title>Immortality</title>\n"
990             + "      <author>John Smith</author>\n"
991             + "    </soap:book>\n"
992             + "  </books>\n"
993             + "</soap:Envelope>";
994 
995         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
996         loadPageVerifyTitle2(html);
997     }
998 
999     /**
1000      * @throws Exception if the test fails
1001      */
1002     @Test
1003     @Alerts("nodeFromID not available")
1004     public void nodeFromID() throws Exception {
1005         final String html = DOCTYPE_HTML
1006             + "<html><head>\n"
1007             + "<script>\n"
1008             + LOG_TITLE_FUNCTION
1009             + "  function test() {\n"
1010             + "    var doc = " + callLoadXMLDocumentFromFile("'" + URL_SECOND + "'") + ";\n"
1011             + "    try {\n"
1012             + "      log('nodeFromID ' + doc.nodeFromID('target'));\n"
1013             + "    } catch(e) {\n"
1014             + "      log('nodeFromID not available');\n"
1015             + "    }\n"
1016             + "  }\n"
1017             + LOAD_XML_DOCUMENT_FROM_FILE_FUNCTION
1018             + "</script></head>\n"
1019             + "<body onload='test()'>\n"
1020             + "</body></html>";
1021 
1022         final String xml
1023             = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
1024             + "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
1025             + "  <body>\n"
1026             + "    <div id=\"target\"></div>\n"
1027             + "  </body>\n"
1028             + "</html>";
1029 
1030         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1031         loadPageVerifyTitle2(html);
1032     }
1033 
1034     /**
1035      * @throws Exception if the test fails
1036      */
1037     @Test
1038     @Alerts({"[object XMLDocument]", "OK"})
1039     public void test() throws Exception {
1040         final String html = DOCTYPE_HTML
1041             + "<html><head>\n"
1042             + "<script>\n"
1043             + LOG_TITLE_FUNCTION
1044             + "  function test() {\n"
1045             + "    var ifr = document.getElementById('ifr');\n"
1046             + "    ifr.onload = function() {\n"
1047             + "      var xml = ifr.contentWindow.document;\n"
1048             + "      log(xml);\n"
1049             + "      log(xml.getElementsByTagName('status')[0].textContent);\n"
1050             + "    };\n"
1051             + "    ifr.src = '" + URL_SECOND + "';\n"
1052             + "  }\n"
1053             + "</script></head>\n"
1054             + "<body onload='test()'>\n"
1055             + "  <iframe id='ifr'></iframe>\n"
1056             + "</body></html>";
1057 
1058         final String xml
1059             = "<response>\n"
1060             + "  <status>OK</status>\n"
1061             + "</response>";
1062 
1063         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1064         loadPageVerifyTitle2(html);
1065     }
1066 
1067     /**
1068      * @throws Exception if the test fails
1069      */
1070     @Test
1071     @Alerts("[object HTMLDocument]")
1072     public void html() throws Exception {
1073         final String svg
1074             = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1075             + "<svg xmlns=\"http://www.w3.org/2000/svg\">\n"
1076             + "  <rect id=\"rect\" width=\"50\" height=\"50\" fill=\"green\" onclick=\"alert(document)\"/>\n"
1077             + "</svg>";
1078         final WebDriver driver = loadPage2(svg);
1079         driver.findElement(By.id("rect")).click();
1080 
1081         verifyAlerts(driver, getExpectedAlerts());
1082     }
1083 
1084     /**
1085      * @throws Exception if the test fails
1086      */
1087     @Test
1088     @Alerts("[object XMLDocument]")
1089     @HtmlUnitNYI(CHROME = "Cannot find elements by id",
1090             EDGE = "Cannot find elements by id",
1091             FF = "Cannot find elements by id",
1092             FF_ESR = "Cannot find elements by id")
1093     public void svg() throws Exception {
1094         final String svg
1095             = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
1096             + "<svg xmlns=\"http://www.w3.org/2000/svg\">\n"
1097             + "  <rect id=\"rect\" width=\"50\" height=\"50\" fill=\"green\" onclick=\"alert(document)\"/>\n"
1098             + "</svg>";
1099 
1100         final WebDriver driver = loadPage2(svg, URL_FIRST, MimeType.TEXT_XML, ISO_8859_1);
1101         try {
1102             driver.findElement(By.id("rect")).click();
1103             verifyAlerts(driver, getExpectedAlerts());
1104         }
1105         catch (final IllegalStateException e) {
1106             assertTrue(e.getMessage(), e.getMessage().startsWith(getExpectedAlerts()[0]));
1107         }
1108     }
1109 
1110     /**
1111      * @throws Exception if the test fails
1112      */
1113     @Test
1114     @Alerts({"myAttr", ""})
1115     public void createAttributeNameValue() throws Exception {
1116         final String html = DOCTYPE_HTML
1117             + "<html>\n"
1118             + "<head>\n"
1119             + "<script>\n"
1120             + LOG_TITLE_FUNCTION
1121             + "  function test() {\n"
1122             + "    var doc = document.implementation.createDocument('', '', null);\n"
1123             + "    var node = doc.createAttribute('myAttr');\n"
1124             + "    log(node.name);\n"
1125             + "    log(node.value);\n"
1126             + "  }\n"
1127             + "</script></head><body onload='test()'>\n"
1128             + "  <div id='tester'></div>\n"
1129             + "</body></html>";
1130 
1131         loadPageVerifyTitle2(html);
1132     }
1133 
1134     /**
1135      * @throws Exception if the test fails
1136      */
1137     @Test
1138     @Alerts("about:blank")
1139     public void url() throws Exception {
1140         final String html = DOCTYPE_HTML
1141             + "<html>\n"
1142             + "<head>\n"
1143             + "<script>\n"
1144             + LOG_TITLE_FUNCTION
1145             + "  function test() {\n"
1146             + "    var doc = document.implementation.createDocument('', '', null);\n"
1147             + "    log(doc.URL);\n"
1148             + "  }\n"
1149             + "</script></head>\n"
1150             + "<body onload='test()'>\n"
1151             + "  <div id='tester'></div>\n"
1152             + "</body></html>";
1153 
1154         expandExpectedAlertsVariables(URL_FIRST);
1155         loadPageVerifyTitle2(html);
1156     }
1157 
1158     /**
1159      * @throws Exception if the test fails
1160      */
1161     @Test
1162     @Alerts("[object XMLDocument]")
1163     public void string() throws Exception {
1164         final String html = DOCTYPE_HTML
1165             + "<html>\n"
1166             + "<head>\n"
1167             + "<script>\n"
1168             + LOG_TITLE_FUNCTION
1169             + "  function test() {\n"
1170             + "    var doc = document.implementation.createDocument('', '', null);\n"
1171             + "    log(doc);\n"
1172             + "  }\n"
1173             + "</script></head>\n"
1174             + "<body onload='test()'>\n"
1175             + "  <div id='tester'></div>\n"
1176             + "</body></html>";
1177 
1178         loadPageVerifyTitle2(html);
1179     }
1180 }