View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.javascript.host.dom;
16  
17  import org.htmlunit.WebDriverTestCase;
18  import org.htmlunit.junit.annotation.Alerts;
19  import org.htmlunit.util.MimeType;
20  import org.junit.jupiter.api.Test;
21  import org.openqa.selenium.WebDriver;
22  
23  /**
24   * Tests for {@link DOMImplementation}.
25   *
26   * @author Ahmed Ashour
27   * @author Marc Guillemot
28   * @author Frank Danek
29   * @author Ronald Brill
30   * @author Adam Afeltowicz
31   */
32  public class DOMImplementationTest extends WebDriverTestCase {
33  
34      /**
35       * @throws Exception if the test fails
36       */
37      @Test
38      @Alerts({"Core 1.0: true", "Core 2.0: true", "Core 3.0: true"})
39      public void hasFeature_Core() throws Exception {
40          hasFeature("Core", "['1.0', '2.0', '3.0']");
41      }
42  
43      /**
44       * @throws Exception if the test fails
45       */
46      @Test
47      @Alerts({"HTML 1.0: true", "HTML 2.0: true", "HTML 3.0: true"})
48      public void hasFeature_HTML() throws Exception {
49          hasFeature("HTML", "['1.0', '2.0', '3.0']");
50      }
51  
52      /**
53       * @throws Exception if the test fails
54       */
55      @Test
56      @Alerts({"XML 1.0: true", "XML 2.0: true", "XML 3.0: true"})
57      public void hasFeature_XML() throws Exception {
58          hasFeature("XML", "['1.0', '2.0', '3.0']");
59      }
60  
61      /**
62       * @throws Exception if the test fails
63       */
64      @Test
65      @Alerts({"XHTML 1.0: true", "XHTML 2.0: true", "XHTML 3.0: true"})
66      public void hasFeature_XHTML() throws Exception {
67          hasFeature("XHTML", "['1.0', '2.0', '3.0']");
68      }
69  
70      /**
71       * @throws Exception if the test fails
72       */
73      @Test
74      @Alerts({"Views 1.0: true", "Views 2.0: true", "Views 3.0: true"})
75      public void hasFeature_Views() throws Exception {
76          hasFeature("Views", "['1.0', '2.0', '3.0']");
77      }
78  
79      /**
80       * @throws Exception if the test fails
81       */
82      @Test
83      @Alerts({"StyleSheets 1.0: true", "StyleSheets 2.0: true", "StyleSheets 3.0: true"})
84      public void hasFeature_StyleSheets() throws Exception {
85          hasFeature("StyleSheets", "['1.0', '2.0', '3.0']");
86      }
87  
88      /**
89       * @throws Exception if the test fails
90       */
91      @Test
92      @Alerts({"CSS 1.0: true", "CSS 2.0: true", "CSS 3.0: true"})
93      public void hasFeature_CSS() throws Exception {
94          hasFeature("CSS", "['1.0', '2.0', '3.0']");
95      }
96  
97      /**
98       * @throws Exception if the test fails
99       */
100     @Test
101     @Alerts({"CSS2 1.0: true", "CSS2 2.0: true", "CSS2 3.0: true"})
102     public void hasFeature_CSS2() throws Exception {
103         hasFeature("CSS2", "['1.0', '2.0', '3.0']");
104     }
105 
106     /**
107      * @throws Exception if the test fails
108      */
109     @Test
110     @Alerts({"CSS3 1.0: true", "CSS3 2.0: true", "CSS3 3.0: true"})
111     public void hasFeature_CSS3() throws Exception {
112         hasFeature("CSS3", "['1.0', '2.0', '3.0']");
113     }
114 
115     /**
116      * @throws Exception if the test fails
117      */
118     @Test
119     @Alerts({"Events 1.0: true", "Events 2.0: true", "Events 3.0: true"})
120     public void hasFeature_Events() throws Exception {
121         hasFeature("Events", "['1.0', '2.0', '3.0']");
122     }
123 
124     /**
125      * @throws Exception if the test fails
126      */
127     @Test
128     @Alerts({"UIEvents 1.0: true", "UIEvents 2.0: true", "UIEvents 3.0: true"})
129     public void hasFeature_UIEvents() throws Exception {
130         hasFeature("UIEvents", "['1.0', '2.0', '3.0']");
131     }
132 
133     /**
134      * @throws Exception if the test fails
135      */
136     @Test
137     @Alerts({"MouseEvents 1.0: true", "MouseEvents 2.0: true", "MouseEvents 3.0: true"})
138     public void hasFeature_MouseEvents() throws Exception {
139         hasFeature("MouseEvents", "['1.0', '2.0', '3.0']");
140     }
141 
142     /**
143      * @throws Exception if the test fails
144      */
145     @Test
146     @Alerts({"TextEvents 1.0: true", "TextEvents 2.0: true", "TextEvents 3.0: true"})
147     public void hasFeature_TextEvents() throws Exception {
148         hasFeature("TextEvents", "['1.0', '2.0', '3.0']");
149     }
150 
151     /**
152      * @throws Exception if the test fails
153      */
154     @Test
155     @Alerts({"KeyboardEvents 1.0: true", "KeyboardEvents 2.0: true", "KeyboardEvents 3.0: true"})
156     public void hasFeature_KeyboardEvents() throws Exception {
157         hasFeature("KeyboardEvents", "['1.0', '2.0', '3.0']");
158     }
159 
160     /**
161      * @throws Exception if the test fails
162      */
163     @Test
164     @Alerts({"MutationEvents 1.0: true", "MutationEvents 2.0: true", "MutationEvents 3.0: true"})
165     public void hasFeature_MutationEvents() throws Exception {
166         hasFeature("MutationEvents", "['1.0', '2.0', '3.0']");
167     }
168 
169     /**
170      * @throws Exception if the test fails
171      */
172     @Test
173     @Alerts({"MutationNameEvents 1.0: true", "MutationNameEvents 2.0: true", "MutationNameEvents 3.0: true"})
174     public void hasFeature_MutationNameEvents() throws Exception {
175         hasFeature("MutationNameEvents", "['1.0', '2.0', '3.0']");
176     }
177 
178     /**
179      * @throws Exception if the test fails
180      */
181     @Test
182     @Alerts({"HTMLEvents 1.0: true", "HTMLEvents 2.0: true", "HTMLEvents 3.0: true"})
183     public void hasFeature_HTMLEvents() throws Exception {
184         hasFeature("HTMLEvents", "['1.0', '2.0', '3.0']");
185     }
186 
187     /**
188      * @throws Exception if the test fails
189      */
190     @Test
191     @Alerts({"Range 1.0: true", "Range 2.0: true", "Range 3.0: true"})
192     public void hasFeature_Range() throws Exception {
193         hasFeature("Range", "['1.0', '2.0', '3.0']");
194     }
195 
196     /**
197      * @throws Exception if the test fails
198      */
199     @Test
200     @Alerts({"Traversal 1.0: true", "Traversal 2.0: true", "Traversal 3.0: true"})
201     public void hasFeature_Traversal() throws Exception {
202         hasFeature("Traversal", "['1.0', '2.0', '3.0']");
203     }
204 
205     /**
206      * @throws Exception if the test fails
207      */
208     @Test
209     @Alerts({"LS 1.0: true", "LS 2.0: true", "LS 3.0: true"})
210     public void hasFeature_LS() throws Exception {
211         hasFeature("LS", "['1.0', '2.0', '3.0']");
212     }
213 
214     /**
215      * @throws Exception if the test fails
216      */
217     @Test
218     @Alerts({"LS-Async 1.0: true", "LS-Async 2.0: true", "LS-Async 3.0: true"})
219     public void hasFeature_LSAsync() throws Exception {
220         hasFeature("LS-Async", "['1.0', '2.0', '3.0']");
221     }
222 
223     /**
224      * @throws Exception if the test fails
225      */
226     @Test
227     @Alerts({"Validation 1.0: true", "Validation 2.0: true", "Validation 3.0: true"})
228     public void hasFeature_Validation() throws Exception {
229         hasFeature("Validation", "['1.0', '2.0', '3.0']");
230     }
231 
232     /**
233      * @throws Exception if the test fails
234      */
235     @Test
236     @Alerts({"XPath 1.0: true", "XPath 2.0: true", "XPath 3.0: true"})
237     public void hasFeature_XPath() throws Exception {
238         hasFeature("XPath", "['1.0', '2.0', '3.0']");
239     }
240 
241     /**
242      * @throws Exception if the test fails
243      */
244     @Test
245     @Alerts({"http://www.w3.org/TR/SVG11/feature#BasicStructure 1.0: true",
246              "http://www.w3.org/TR/SVG11/feature#BasicStructure 1.1: true",
247              "http://www.w3.org/TR/SVG11/feature#BasicStructure 1.2: true"})
248     public void hasFeature_SVG_BasicStructure() throws Exception {
249         hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "['1.0', '1.1', '1.2']");
250     }
251 
252     /**
253      * @throws Exception if the test fails
254      */
255     @Test
256     @Alerts({"http://www.w3.org/TR/SVG11/feature#Shape 1.0: true",
257              "http://www.w3.org/TR/SVG11/feature#Shape 1.1: true",
258              "http://www.w3.org/TR/SVG11/feature#Shape 1.2: true"})
259     public void hasFeature_SVG_Shape() throws Exception {
260         hasFeature("http://www.w3.org/TR/SVG11/feature#Shape", "['1.0', '1.1', '1.2']");
261     }
262 
263     private void hasFeature(final String feature, final String versions) throws Exception {
264         final String html = DOCTYPE_HTML
265             + "<html><head>\n"
266             + "<script>\n"
267             + LOG_TITLE_FUNCTION
268             + "  function test() {\n"
269             + "    var feature = '" + feature + "';\n"
270             + "    var versions = " + versions + ";\n"
271             + "    for (var j = 0; j < versions.length; j++) {\n"
272             + "      var version = versions[j];\n"
273             + "      log(feature + ' ' + version + ': ' + document.implementation.hasFeature(feature, version));\n"
274             + "    }\n"
275             + "  }\n"
276             + "</script>\n"
277             + "</head>\n"
278             + "<body onload='test()'></body></html>";
279 
280         loadPageVerifyTitle2(html);
281     }
282 
283     /**
284      * @throws Exception if the test fails
285      */
286     @Test
287     @Alerts("[object XMLDocument]")
288     public void createDocument() throws Exception {
289         final String html = DOCTYPE_HTML
290             + "<html><head><script>\n"
291             + LOG_TITLE_FUNCTION
292             + "  function test() {\n"
293             + "    log(document.implementation.createDocument('', '', null));\n"
294             + "  }\n"
295             + "</script></head><body onload='test()'>\n"
296             + "</body></html>";
297 
298         loadPageVerifyTitle2(html);
299     }
300 
301     /**
302      * @throws Exception if the test fails
303      */
304     @Test
305     @Alerts({"mydoc", "null", "mydoc", "null"})
306     public void createDocument_qualifiedName() throws Exception {
307         final String html = DOCTYPE_HTML
308             + "<html><head><script>\n"
309             + LOG_TITLE_FUNCTION
310             + "  function test() {\n"
311             + "    var doc = document.implementation.createDocument('', 'mydoc', null);\n"
312             + "    log(doc.documentElement.tagName);\n"
313             + "    log(doc.documentElement.prefix);\n"
314             + "    log(doc.documentElement.localName);\n"
315             + "    log(doc.documentElement.namespaceURI);\n"
316             + "  }\n"
317             + "</script></head><body onload='test()'>\n"
318             + "</body></html>";
319 
320         loadPageVerifyTitle2(html);
321     }
322 
323     /**
324      * @throws Exception if the test fails
325      */
326     @Test
327     @Alerts({"mydoc", "null", "mydoc", "http://mynamespace"})
328     public void createDocument_namespaceAndQualifiedName() throws Exception {
329         final String html = DOCTYPE_HTML
330             + "<html><head><script>\n"
331             + LOG_TITLE_FUNCTION
332             + "  function test() {\n"
333             + "    var doc = document.implementation.createDocument('http://mynamespace', 'mydoc', null);\n"
334             + "    log(doc.documentElement.tagName);\n"
335             + "    log(doc.documentElement.prefix);\n"
336             + "    log(doc.documentElement.localName);\n"
337             + "    log(doc.documentElement.namespaceURI);\n"
338             + "  }\n"
339             + "</script></head><body onload='test()'>\n"
340             + "</body></html>";
341 
342         loadPageVerifyTitle2(html);
343     }
344 
345     /**
346      * @throws Exception if the test fails
347      */
348     @Test
349     @Alerts({"m:mydoc", "m", "mydoc", "http://mynamespace"})
350     public void createDocument_namespaceAndQualifiedNameWithPrefix() throws Exception {
351         final String html = DOCTYPE_HTML
352             + "<html><head><script>\n"
353             + LOG_TITLE_FUNCTION
354             + "  function test() {\n"
355             + "    var doc = document.implementation.createDocument('http://mynamespace', 'm:mydoc', null);\n"
356             + "    log(doc.documentElement.tagName);\n"
357             + "    log(doc.documentElement.prefix);\n"
358             + "    log(doc.documentElement.localName);\n"
359             + "    log(doc.documentElement.namespaceURI);\n"
360             + "  }\n"
361             + "</script></head><body onload='test()'>\n"
362             + "</body></html>";
363 
364         loadPageVerifyTitle2(html);
365     }
366 
367     /**
368      * @throws Exception if the test fails
369      */
370     @Test
371     @Alerts({"[object HTMLDocument]", "undefined"})
372     public void createHTMLDocument() throws Exception {
373         final String html = DOCTYPE_HTML
374                 + "<html>\n"
375                 + "<head>\n"
376                 + "  <script>\n"
377                 + LOG_TITLE_FUNCTION
378                 + "  function test() {\n"
379                 + "    try {\n"
380                 + "      var doc = document.implementation.createHTMLDocument();\n"
381                 + "      log(doc);\n"
382                 + "      log(doc.window);\n"
383                 + "    } catch(e) { logEx(e); }\n"
384                 + "  }\n"
385                 + "</script>\n"
386                 + "</head>\n"
387                 + "<body onload='test()'>\n"
388                 + "</body></html>";
389 
390         loadPageVerifyTitle2(html);
391     }
392 
393     /**
394      * @throws Exception if the test fails
395      */
396     @Test
397     @Alerts({"[object HTMLDocument]", "newdoctitle"})
398     public void createHTMLDocument_title() throws Exception {
399         final String html = DOCTYPE_HTML
400                 + "<html>\n"
401                 + "<head>\n"
402                 + "  <script>\n"
403                 + LOG_TITLE_FUNCTION
404                 + "  function test() {\n"
405                 + "    try {\n"
406                 + "      var doc = document.implementation.createHTMLDocument('newdoctitle');\n"
407                 + "      log(doc);\n"
408                 + "      log(doc.title);\n"
409                 + "    } catch(e) { logEx(e); }\n"
410                 + "  }\n"
411                 + "</script>\n"
412                 + "</head>\n"
413                 + "<body onload='test()'>\n"
414                 + "</body></html>";
415 
416         loadPageVerifyTitle2(html);
417     }
418 
419     /**
420      * @throws Exception if the test fails
421      */
422     @Test
423     @Alerts({"[object HTMLDocument]", ""})
424     public void createHTMLDocument_titleEmpty() throws Exception {
425         final String html = DOCTYPE_HTML
426                 + "<html>\n"
427                 + "<head>\n"
428                 + "  <script>\n"
429                 + LOG_TITLE_FUNCTION
430                 + "  function test() {\n"
431                 + "    try {\n"
432                 + "      var doc = document.implementation.createHTMLDocument('');\n"
433                 + "      log(doc);\n"
434                 + "      log(doc.title);\n"
435                 + "    } catch(e) { logEx(e); }\n"
436                 + "  }\n"
437                 + "</script>\n"
438                 + "</head>\n"
439                 + "<body onload='test()'>\n"
440                 + "</body></html>";
441 
442         loadPageVerifyTitle2(html);
443     }
444 
445     /**
446      * @throws Exception if the test fails
447      */
448     @Test
449     @Alerts("2")
450     public void createHTMLDocument_jQuery() throws Exception {
451         final String html = DOCTYPE_HTML
452                 + "<html>\n"
453                 + "<head>\n"
454                 + "  <script>\n"
455                 + LOG_TITLE_FUNCTION
456                 + "  function test() {\n"
457                 + "    try {\n"
458                 + "      var doc = document.implementation.createHTMLDocument('');\n"
459                 + "      doc.body.innerHTML = '<form></form><form></form>';\n"
460                 + "      log(doc.body.childNodes.length);\n"
461                 + "    } catch(e) { logEx(e); }\n"
462                 + "  }\n"
463                 + "</script>\n"
464                 + "</head>\n"
465                 + "<body onload='test()'>\n"
466                 + "</body></html>";
467 
468         loadPageVerifyTitle2(html);
469     }
470 
471     /**
472      * @throws Exception if the test fails
473      */
474     @Test
475     @Alerts("createdElement")
476     public void createHTMLDocument_createElement() throws Exception {
477         final String html = DOCTYPE_HTML
478                 + "<html>\n"
479                 + "<head>\n"
480                 + "  <script>\n"
481                 + LOG_TITLE_FUNCTION
482                 + "  function test() {\n"
483                 + "    try {\n"
484                 + "      var doc = document.implementation.createHTMLDocument('');\n"
485                 + "      var p = doc.createElement('p');\n"
486                 + "      p.innertHTML = 'createdElement';\n"
487                 + "      log(p.innertHTML);\n"
488                 + "    } catch(e) { logEx(e); }\n"
489                 + "  }\n"
490                 + "</script>\n"
491                 + "</head>\n"
492                 + "<body onload='test()'>\n"
493                 + "</body></html>";
494 
495         loadPageVerifyTitle2(html);
496     }
497 
498     /**
499      * @throws Exception if the test fails
500      */
501     @Test
502     @Alerts({"<html><head></head><body></body></html>",
503              "<html><head><title></title></head><body></body></html>",
504              "<html><head><title>abc</title></head><body></body></html>"})
505     public void createHTMLDocument_htmlCode() throws Exception {
506         final String html = DOCTYPE_HTML
507                 + "<html>\n"
508                 + "<head>\n"
509                 + "  <script>\n"
510                 + LOG_TITLE_FUNCTION
511                 + "  function test() {\n"
512                 + "    try {\n"
513                 + "      var doc = document.implementation.createHTMLDocument();\n"
514                 + "      log(doc.documentElement.outerHTML);\n"
515                 + "    } catch(e) { logEx(e); }\n"
516 
517                 + "    try {\n"
518                 + "      var doc = document.implementation.createHTMLDocument('');\n"
519                 + "      log(doc.documentElement.outerHTML);\n"
520                 + "    } catch(e) { logEx(e); }\n"
521 
522                 + "    try {\n"
523                 + "      var doc = document.implementation.createHTMLDocument('abc');\n"
524                 + "      log(doc.documentElement.outerHTML);\n"
525                 + "    } catch(e) { logEx(e); }\n"
526                 + "  }\n"
527                 + "</script>\n"
528                 + "</head>\n"
529                 + "<body onload='test()'>\n"
530                 + "</body></html>";
531 
532         loadPageVerifyTitle2(html);
533     }
534 
535     /**
536      * @throws Exception if the test fails
537      */
538     @Test
539     @Alerts("<html><head><title>test</title></head>"
540             + "<body><p>This is a new paragraph.</p></body></html>")
541     public void createHTMLDocumentAddParagraph() throws Exception {
542         final String html = DOCTYPE_HTML
543                 + "<html>\n"
544                 + "<head>\n"
545                 + "  <script>\n"
546                 + LOG_TITLE_FUNCTION
547                 + "  function test() {\n"
548                 + "    try {\n"
549                 + "      var doc = document.implementation.createHTMLDocument('test');\n"
550                 + "      var p = doc.createElement('p');\n"
551                 + "      p.innerHTML = 'This is a new paragraph.';\n"
552                 + "      doc.body.appendChild(p);"
553                 + "      log(doc.documentElement.outerHTML);\n"
554                 + "    } catch(e) { logEx(e); }\n"
555                 + "  }\n"
556                 + "</script>\n"
557                 + "</head>\n"
558                 + "<body onload='test()'>\n"
559                 + "</body></html>";
560 
561         loadPageVerifyTitle2(html);
562     }
563 
564     /**
565      * @throws Exception if the test fails
566      */
567     @Test
568     @Alerts("<html><head><title>test</title></head><body><p>Hello</p></body></html>")
569     public void createHTMLDocumentInnerAddParagraph() throws Exception {
570         final String html = DOCTYPE_HTML
571                 + "<html>\n"
572                 + "<head>\n"
573                 + "  <script>\n"
574                 + LOG_TITLE_FUNCTION
575                 + "  function test() {\n"
576                 + "    try {\n"
577                 + "      var doc = document.implementation.createHTMLDocument('test');\n"
578                 + "      doc.body.innerHTML = '<p>Hello</p>';\n"
579                 + "      log(doc.documentElement.outerHTML);\n"
580                 + "    } catch(e) { logEx(e); }\n"
581                 + "  }\n"
582                 + "</script>\n"
583                 + "</head>\n"
584                 + "<body onload='test()'>\n"
585                 + "</body></html>";
586 
587         loadPageVerifyTitle2(html);
588     }
589 
590     /**
591      * @throws Exception if the test fails
592      */
593     @Test
594     @Alerts("<html><head><title>test</title></head><body><img src=\"x\" onerror=\"log(1)\"></body></html>")
595     public void createHTMLDocumentInnerAddImg() throws Exception {
596         final String html = DOCTYPE_HTML
597                 + "<html>\n"
598                 + "<head>\n"
599                 + "  <script>\n"
600                 + LOG_TITLE_FUNCTION
601                 + "  function test() {\n"
602                 + "    try {\n"
603                 + "      var doc = document.implementation.createHTMLDocument('test');\n"
604                 + "      doc.body.innerHTML = '<img src=\"x\" onerror=\"log(1)\">';\n"
605                 + "      log(doc.documentElement.outerHTML);\n"
606                 + "    } catch(e) { logEx(e); }\n"
607                 + "  }\n"
608                 + "</script>\n"
609                 + "</head>\n"
610                 + "<body onload='test()'>\n"
611                 + "</body></html>";
612 
613         loadPageVerifyTitle2(html);
614     }
615 
616     /**
617      * @throws Exception if the test fails
618      */
619     @Test
620     @Alerts("before1")
621     public void createHTMLDocumentInnerAddImgAddDocToIframe() throws Exception {
622         final String html = DOCTYPE_HTML
623                 + "<html>\n"
624                 + "<head>\n"
625                 + "  <script>\n"
626                 + "  function test() {\n"
627                 + "    try {\n"
628                 + "      var frame = document.getElementById('theFrame');\n"
629 
630                 + "      var doc = document.implementation.createHTMLDocument('test');\n"
631                 + "      doc.body.innerHTML = '<img src=\"x\" onerror=\"window.parent.document.title += 1\">';\n"
632 
633                          // Copy the new HTML document into the frame
634                 + "      var destDocument = frame.contentDocument;\n"
635                 + "      var srcNode = doc.documentElement;\n"
636                 + "      var newNode = destDocument.importNode(srcNode, true);\n"
637                 + "      destDocument.replaceChild(newNode, destDocument.documentElement);\n"
638                 + "      window.parent.document.title += 'before';"
639 
640                 + "    } catch(e) { window.parent.document.title += 'exception'; }\n"
641                 + "  }\n"
642                 + "</script>\n"
643                 + "</head>\n"
644                 + "<body onload='test()'>\n"
645                 + "  <iframe id='theFrame' src='about:blank' />"
646                 + "</body></html>";
647 
648         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
649 
650         final WebDriver driver = loadPage2(html);
651         assertTitle(driver, getExpectedAlerts()[0]);
652     }
653 
654     /**
655      * Can be removed if the one before works.
656      * @throws Exception if the test fails
657      */
658     @Test
659     @Alerts("before import;after import;1")
660     public void createHTMLDocumentInnerAddImgAddDocToIframe1() throws Exception {
661         final String html = DOCTYPE_HTML
662                 + "<html>\n"
663                 + "<head>\n"
664                 + "  <script>\n"
665                 + "  function test() {\n"
666                 + "    try {\n"
667                 + "      var frame = document.getElementById('theFrame');\n"
668 
669                 + "      var doc = document.implementation.createHTMLDocument('test');\n"
670                 + "      doc.body.innerHTML = '<img src=\"x\" onerror=\"window.parent.document.title += 1\">';\n"
671 
672                          // Copy the new HTML document into the frame
673                 + "      var destDocument = frame.contentDocument;\n"
674                 + "      var srcNode = doc.documentElement;\n"
675                 + "      document.title += 'before import;';\n"
676                 + "      var newNode = destDocument.importNode(srcNode, true);\n"
677                 + "      document.title += 'after import;';\n"
678                 + "      destDocument.replaceChild(newNode, destDocument.documentElement);\n"
679 
680                 + "    } catch(e) { document.title += 'exception'; }\n"
681                 + "  }\n"
682                 + "</script>\n"
683                 + "</head>\n"
684                 + "<body onload='test()'>\n"
685                 + "  <iframe id='theFrame' src='about:blank' />"
686                 + "</body></html>";
687         getMockWebConnection().setDefaultResponse("Error: not found", 404, "Not Found", MimeType.TEXT_HTML);
688 
689         final WebDriver driver = loadPage2(html);
690         assertTitle(driver, getExpectedAlerts()[0]);
691     }
692 }