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