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.UTF_8;
18  
19  import java.io.BufferedReader;
20  import java.io.ByteArrayInputStream;
21  import java.io.ByteArrayOutputStream;
22  import java.io.IOException;
23  import java.io.InputStreamReader;
24  import java.net.URL;
25  import java.util.ArrayList;
26  import java.util.LinkedList;
27  import java.util.List;
28  import java.util.Locale;
29  import java.util.zip.GZIPOutputStream;
30  
31  import javax.servlet.http.HttpServlet;
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpServletResponse;
34  
35  import org.apache.commons.lang3.ArrayUtils;
36  import org.apache.commons.lang3.StringUtils;
37  import org.htmlunit.HttpHeader;
38  import org.htmlunit.WebDriverTestCase;
39  import org.htmlunit.WebRequest;
40  import org.htmlunit.junit.BrowserRunner;
41  import org.htmlunit.junit.annotation.Alerts;
42  import org.htmlunit.junit.annotation.HtmlUnitNYI;
43  import org.htmlunit.junit.annotation.Tries;
44  import org.htmlunit.util.MimeType;
45  import org.htmlunit.util.NameValuePair;
46  import org.junit.ComparisonFailure;
47  import org.junit.Test;
48  import org.junit.runner.RunWith;
49  import org.openqa.selenium.By;
50  import org.openqa.selenium.WebDriver;
51  
52  /**
53   * Tests for {@link XMLHttpRequest}.
54   *
55   * @author Daniel Gredler
56   * @author Marc Guillemot
57   * @author Ahmed Ashour
58   * @author Stuart Begg
59   * @author Sudhan Moghe
60   * @author Sebastian Cato
61   * @author Ronald Brill
62   * @author Frank Danek
63   * @author Jake Cobb
64   */
65  @RunWith(BrowserRunner.class)
66  public class XMLHttpRequestTest extends WebDriverTestCase {
67  
68      private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.UNSENT);
69      private static final String LOADING = String.valueOf(XMLHttpRequest.OPENED);
70      private static final String COMPLETED = String.valueOf(XMLHttpRequest.DONE);
71  
72      /**
73       * Tests synchronous use of XMLHttpRequest.
74       * @throws Exception if the test fails
75       */
76      @Test
77      @Tries(3)
78      public void syncUse() throws Exception {
79          final String html = DOCTYPE_HTML
80              + "<html>\n"
81              + "  <head>\n"
82              + "    <script>\n"
83              + LOG_TITLE_FUNCTION_NORMALIZE
84              + "      function testSync() {\n"
85              + "        var request = new XMLHttpRequest();\n"
86              + "        log(request.readyState);\n"
87              + "        log(request.responseType);\n"
88              + "        request.open('GET', '" + URL_SECOND + "', false);\n"
89              + "        log(request.readyState);\n"
90              + "        request.send('');\n"
91              + "        log(request.readyState);\n"
92              + "        log(request.responseText);\n"
93              + "      }\n"
94              + "    </script>\n"
95              + "  </head>\n"
96              + "  <body onload='testSync()'>\n"
97              + "  </body>\n"
98              + "</html>";
99  
100         final String xml =
101               "<xml>\n"
102             + "<content>blah</content>\n"
103             + "<content>blah2</content>\n"
104             + "</xml>";
105 
106         setExpectedAlerts(UNINITIALIZED, "", LOADING, COMPLETED, xml.replace("\n", "\\n"));
107         getMockWebConnection().setDefaultResponse(xml, MimeType.TEXT_XML);
108 
109         loadPageVerifyTitle2(html);
110     }
111 
112     /**
113      * Tests style object creation.
114      * @throws Exception if the test fails
115      */
116     @Test
117     @Alerts("[object XMLHttpRequest]")
118     public void creation() throws Exception {
119         final String html = DOCTYPE_HTML
120             + "<html>\n"
121             + "  <head>\n"
122             + "    <script>\n"
123             + LOG_TITLE_FUNCTION
124             + "        log(new XMLHttpRequest());\n"
125             + "    </script>\n"
126             + "  </head>\n"
127             + "  <body></body>\n"
128             + "</html>";
129         loadPageVerifyTitle2(html);
130     }
131 
132     /**
133      * @throws Exception if the test fails
134      */
135     @Test
136     @Alerts({"1: 0-", "2: ", "3: 200-OK"})
137     public void statusSync() throws Exception {
138         final String html = DOCTYPE_HTML
139             + "<html>\n"
140             + "  <head>\n"
141             + "<script>\n"
142             + LOG_TITLE_FUNCTION
143             + "  var xhr = new XMLHttpRequest();\n"
144 
145             + "  alertStatus('1: ');\n"
146             + "  xhr.open('GET', '/foo.xml', false);\n"
147             + "  log('2: ');\n"
148 
149             + "  xhr.send();\n"
150             + "  alertStatus('3: ');\n"
151 
152             + "  function alertStatus(prefix) {\n"
153             + "    var msg = prefix;\n"
154             + "    try {\n"
155             + "      msg = msg + xhr.status + '-';\n"
156             + "    } catch(e) { msg = msg + 'ex: status' + '-' }\n"
157             + "    try {\n"
158             + "      msg = msg + xhr.statusText;\n"
159             + "    } catch(e) { msg = msg + 'ex: statusText' }\n"
160             + "    log(msg);\n"
161             + "  }\n"
162             + "</script>\n"
163             + "  </head>\n"
164             + "  <body></body>\n"
165             + "</html>";
166 
167         getMockWebConnection().setDefaultResponse("<res></res>", MimeType.TEXT_XML);
168         loadPageVerifyTitle2(html);
169     }
170 
171     /**
172      * @throws Exception if the test fails
173      */
174     @Test
175     @Alerts({"1: 0-", "2: 0-", "#1: 0-", "3: 0-", "4: 0-", "#2: 200-OK", "#3: 200-OK", "#4: 200-OK"})
176     public void statusAsync() throws Exception {
177         final String html = DOCTYPE_HTML
178             + "<html>\n"
179             + "  <head>\n"
180             + "    <title>XMLHttpRequest Test</title>\n"
181             + "<script>\n"
182             + "  var xhr = new XMLHttpRequest();\n"
183 
184             + "  function test() {\n"
185             + "    try {\n"
186             + "      logStatus('1: ');\n"
187 
188             + "      xhr.onreadystatechange = onReadyStateChange;\n"
189             + "      logStatus('2: ');\n"
190 
191             + "      xhr.open('GET', '/foo.xml', true);\n"
192             + "      logStatus('3: ');\n"
193 
194             + "      xhr.send();\n"
195             + "      logStatus('4: ');\n"
196             + "    } catch(e) {\n"
197             + "      document.getElementById('log').value += e + '\\n';\n"
198             + "    }\n"
199             + "  }\n"
200 
201             + "  function onReadyStateChange() {\n"
202             + "    logStatus('#' + xhr.readyState + ': ');\n"
203             + "  }\n"
204 
205             + "  function logStatus(prefix) {\n"
206             + "    var msg = prefix;\n"
207             + "    try {\n"
208             + "      msg = msg + xhr.status + '-';\n"
209             + "    } catch(e) { msg = msg + 'ex: status' + '-' }\n"
210             + "    try {\n"
211             + "      msg = msg + xhr.statusText;\n"
212             + "    } catch(e) { msg = msg + 'ex: statusText' }\n"
213             + "    document.getElementById('log').value += msg + '\\n';\n"
214             + "  }\n"
215             + "</script>\n"
216             + "  </head>\n"
217             + "  <body onload='test()'>\n"
218             + "    <textarea id='log' cols='80' rows='40'></textarea>\n"
219             + "  </body>\n"
220             + "</html>";
221 
222         getMockWebConnection().setDefaultResponse("<res></res>", MimeType.TEXT_XML);
223         final WebDriver driver = loadPage2(html);
224 
225         final String expected = String.join("\n", getExpectedAlerts());
226         assertLog(driver, expected);
227     }
228 
229     private static void assertLog(final WebDriver driver, final String expected) throws InterruptedException {
230         final long maxWait = System.currentTimeMillis() + DEFAULT_WAIT_TIME.toMillis();
231         while (true) {
232             try {
233                 final String text = driver
234                                         .findElement(By.id("log"))
235                                         .getDomProperty("value")
236                                         .trim()
237                                         .replaceAll("\r", "");
238                 assertEquals(expected, text);
239                 return;
240             }
241             catch (final ComparisonFailure e) {
242                 if (System.currentTimeMillis() > maxWait) {
243                     throw e;
244                 }
245                 Thread.sleep(10);
246             }
247         }
248     }
249 
250     /**
251      * Checks that not passing the async flag to <code>open()</code>
252      * results in async execution.  If this gets interpreted as {@code false}
253      * then you will see the alert order 1-2-4-3 instead of 1-2-3-4.
254      * @throws Exception if the test fails
255      */
256     @Test
257     @Alerts({"#1", "#2", "#3", "#4"})
258     public void asyncIsDefault() throws Exception {
259         final String html = DOCTYPE_HTML
260             + "<html>\n"
261             + "<body>\n"
262             + "  <textarea id='log' cols='80' rows='40'></textarea>\n"
263 
264             + "<script>\n"
265             + "    function log(x) {\n"
266             + "      document.getElementById('log').value += x + '\\n';\n"
267             + "    }\n"
268 
269             + "var xhr = new XMLHttpRequest();\n"
270 
271             + "function onReadyStateChange() {\n"
272             + "  if( xhr.readyState == 4 ) {\n"
273             + "    log('#4');\n"
274             + "  }\n"
275             + "}\n"
276 
277             + "try {\n"
278             + "  log('#1');\n"
279             + "  xhr.onreadystatechange = onReadyStateChange;\n"
280             + "  xhr.open('GET', '/foo.xml');\n"
281             + "  log('#2');\n"
282             + "  xhr.send();\n"
283             + "  log('#3');\n"
284             + "} catch(e) { log(e); }\n"
285             + "</script>\n"
286             + "</body></html>";
287 
288         getMockWebConnection().setDefaultResponse("<res></res>", MimeType.TEXT_XML);
289         final WebDriver driver = loadPage2(html);
290 
291         final String expected = String.join("\n", getExpectedAlerts());
292         assertLog(driver, expected);
293     }
294 
295     /**
296      * @throws Exception if the test fails
297      */
298     @Test
299     @Alerts({"orsc1", "open-done", "send-done",
300              "orsc2", "orsc3", "orsc4", "4", "<a>b</a>", "[object XMLHttpRequest]"})
301     public void onload() throws Exception {
302         final String html = DOCTYPE_HTML
303             + "<html>\n"
304             + "  <head>\n"
305             + "    <script>\n"
306             + "      function log(x) {\n"
307             + "        document.getElementById('log').value += x + '\\n';\n"
308             + "      }\n"
309 
310             + "      function test() {\n"
311             + "        var xhr = new XMLHttpRequest();\n"
312 
313             + "        xhr.onreadystatechange = function() { log('orsc' + xhr.readyState); };\n"
314             + "        xhr.onload = function() { log(xhr.readyState); log(xhr.responseText); log(this); }\n"
315 
316             + "        xhr.open('GET', '/foo.xml', true);\n"
317             + "        log('open-done');\n"
318 
319             + "        xhr.send('');\n"
320             + "        log('send-done');\n"
321             + "      }\n"
322             + "    </script>\n"
323             + "  </head>\n"
324             + "  <body onload='test()'>\n"
325             + "    <textarea id='log' cols='80' rows='40'></textarea>\n"
326             + "  </body>\n"
327             + "</html>";
328 
329         final String xml = "<a>b</a>";
330 
331         getMockWebConnection().setDefaultResponse(xml, MimeType.TEXT_XML);
332         final WebDriver driver = loadPage2(html);
333 
334         final String expected = String.join("\n", getExpectedAlerts());
335         assertLog(driver, expected);
336     }
337 
338     /**
339      * @throws Exception if the test fails
340      */
341     @Test
342     @Alerts({"null", "null"})
343     public void responseHeaderBeforeSend() throws Exception {
344         final String html = DOCTYPE_HTML
345             + "<html>\n"
346             + "  <head>\n"
347             + "    <script>\n"
348             + LOG_TITLE_FUNCTION
349             + "        var request = new XMLHttpRequest();\n"
350 
351             + "        log(request.getResponseHeader('content-length'));\n"
352             + "        request.open('GET', '/foo.xml', false);\n"
353             + "        log(request.getResponseHeader('content-length'));\n"
354             + "    </script>\n"
355             + "  </head>\n"
356             + "  <body></body>\n"
357             + "</html>";
358         loadPageVerifyTitle2(html);
359     }
360 
361     /**
362      * Regression test for http://sourceforge.net/p/htmlunit/bugs/269/.
363      * @throws Exception if the test fails
364      */
365     @Test
366     public void relativeUrl() throws Exception {
367         final String html = DOCTYPE_HTML
368             + "<html>\n"
369             + "  <head>\n"
370             + "    <script>\n"
371             + LOG_TITLE_FUNCTION_NORMALIZE
372             + "      function testSync() {\n"
373             + "        var request = new XMLHttpRequest();\n"
374             + "        request.open('GET', '/foo.xml', false);\n"
375             + "        request.send('');\n"
376             + "        log(request.readyState);\n"
377             + "        log(request.responseText);\n"
378             + "      }\n"
379             + "    </script>\n"
380             + "  </head>\n"
381             + "  <body onload='testSync()'>\n"
382             + "  </body>\n"
383             + "</html>";
384 
385         final String xml =
386               "<xml>\n"
387             + "<content>blah</content>\n"
388             + "<content>blah2</content>\n"
389             + "</xml>";
390 
391         setExpectedAlerts(COMPLETED, xml.replace("\n", "\\n"));
392         getMockWebConnection().setDefaultResponse(xml, MimeType.TEXT_XML);
393         loadPageVerifyTitle2(html);
394     }
395 
396     /**
397      * @throws Exception if the test fails
398      */
399     @Test
400     @Alerts("bla bla")
401     public void responseText_NotXml() throws Exception {
402         final String html = DOCTYPE_HTML
403             + "<html><head>\n"
404             + "<script>\n"
405             + LOG_TITLE_FUNCTION
406             + "function test() {\n"
407             + "  var request = new XMLHttpRequest();\n"
408             + "  request.open('GET', 'foo.txt', false);\n"
409             + "  request.send('');\n"
410             + "  log(request.responseText);\n"
411             + "}\n"
412             + "</script>\n"
413             + "</head>\n"
414             + "<body onload='test()'></body></html>";
415 
416         getMockWebConnection().setDefaultResponse("bla bla", MimeType.TEXT_PLAIN);
417         loadPageVerifyTitle2(html);
418     }
419 
420     /**
421      * @throws Exception if the test fails
422      */
423     @Test
424     @Alerts("null")
425     public void responseXML_text_html() throws Exception {
426         responseXML("<html></html>", MimeType.TEXT_HTML, false, false);
427     }
428 
429     /**
430      * @throws Exception if the test fails
431      */
432     @Test
433     @Alerts("null")
434     public void responseXMLAsync_text_html() throws Exception {
435         responseXML("<html></html>", MimeType.TEXT_HTML, true, false);
436     }
437 
438     /**
439      * @throws Exception if the test fails
440      */
441     @Test
442     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
443     public void responseXMLAsyncDocument_text_html() throws Exception {
444         responseXML("<html></html>", MimeType.TEXT_HTML, true, true);
445     }
446 
447     /**
448      * @throws Exception if the test fails
449      */
450     @Test
451     @Alerts("null")
452     public void responseXML_text_html_empty() throws Exception {
453         responseXML("", MimeType.TEXT_HTML, false, false);
454     }
455 
456     /**
457      * @throws Exception if the test fails
458      */
459     @Test
460     @Alerts("null")
461     public void responseXMLAsync_text_html_empty() throws Exception {
462         responseXML("", MimeType.TEXT_HTML, true, false);
463     }
464 
465     /**
466      * @throws Exception if the test fails
467      */
468     @Test
469     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
470     public void responseXMLAsyncDocument_text_html_empty() throws Exception {
471         responseXML("", MimeType.TEXT_HTML, true, true);
472     }
473 
474     /**
475      * @throws Exception if the test fails
476      */
477     @Test
478     @Alerts("null")
479     public void responseXML_text_html_blank() throws Exception {
480         responseXML("    ", MimeType.TEXT_HTML, false, false);
481     }
482 
483     /**
484      * @throws Exception if the test fails
485      */
486     @Test
487     @Alerts("null")
488     public void responseXMLAsync_text_html_blank() throws Exception {
489         responseXML("    ", MimeType.TEXT_HTML, true, false);
490     }
491 
492     /**
493      * @throws Exception if the test fails
494      */
495     @Test
496     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
497     public void responseXMLAsyncDocument_text_html_blank() throws Exception {
498         responseXML("    ", MimeType.TEXT_HTML, true, true);
499     }
500 
501     /**
502      * @throws Exception if the test fails
503      */
504     @Test
505     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
506     public void responseXML_text_xml() throws Exception {
507         responseXML("<note/>", MimeType.TEXT_XML, false, false);
508     }
509 
510     /**
511      * @throws Exception if the test fails
512      */
513     @Test
514     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
515     public void responseXMLAsync_text_xml() throws Exception {
516         responseXML("<note/>", MimeType.TEXT_XML, true, false);
517     }
518 
519     /**
520      * @throws Exception if the test fails
521      */
522     @Test
523     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
524     public void responseXMLAsyncDocument_text_xml() throws Exception {
525         responseXML("<note/>", MimeType.TEXT_XML, true, true);
526     }
527 
528     /**
529      * @throws Exception if the test fails
530      */
531     @Test
532     @Alerts("null")
533     public void responseXML_text_xml_empty() throws Exception {
534         responseXML("", MimeType.TEXT_XML, false, false);
535     }
536 
537     /**
538      * @throws Exception if the test fails
539      */
540     @Test
541     @Alerts("null")
542     public void responseXMLAsync_text_xml_empty() throws Exception {
543         responseXML("", MimeType.TEXT_XML, true, false);
544     }
545 
546     /**
547      * @throws Exception if the test fails
548      */
549     @Test
550     @Alerts("null")
551     public void responseXMLAsyncDocument_text_xml_empty() throws Exception {
552         responseXML("", MimeType.TEXT_XML, true, true);
553     }
554 
555     /**
556      * @throws Exception if the test fails
557      */
558     @Test
559     @Alerts("null")
560     public void responseXML_text_xml_blank() throws Exception {
561         responseXML("    ", MimeType.TEXT_XML, false, false);
562     }
563 
564     /**
565      * @throws Exception if the test fails
566      */
567     @Test
568     @Alerts("null")
569     public void responseXMLAsync_text_xml_blank() throws Exception {
570         responseXML("    ", MimeType.TEXT_XML, true, false);
571     }
572 
573     /**
574      * @throws Exception if the test fails
575      */
576     @Test
577     @Alerts("null")
578     public void responseXMLAsyncDocument_text_xml_blank() throws Exception {
579         responseXML("    ", MimeType.TEXT_XML, true, true);
580     }
581 
582     /**
583      * @throws Exception if the test fails
584      */
585     @Test
586     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
587     public void responseXML_application_xml() throws Exception {
588         responseXML("<note/>", MimeType.APPLICATION_XML, false, false);
589     }
590 
591     /**
592      * @throws Exception if the test fails
593      */
594     @Test
595     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
596     public void responseXMLAsync_application_xml() throws Exception {
597         responseXML("<note/>", MimeType.APPLICATION_XML, true, false);
598     }
599 
600     /**
601      * @throws Exception if the test fails
602      */
603     @Test
604     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
605     public void responseXMLAsyncDocument_application_xml() throws Exception {
606         responseXML("<note/>", MimeType.APPLICATION_XML, true, true);
607     }
608 
609     /**
610      * @throws Exception if the test fails
611      */
612     @Test
613     @Alerts({"[object XMLDocument]", "[object Element]", "html", "§§URL§§foo"})
614     public void responseXML_application_xhtmlXml() throws Exception {
615         responseXML("<html/>", MimeType.APPLICATION_XHTML, false, false);
616     }
617 
618     /**
619      * @throws Exception if the test fails
620      */
621     @Test
622     @Alerts({"[object XMLDocument]", "[object Element]", "html", "§§URL§§foo"})
623     public void responseXMLAsync_application_xhtmlXml() throws Exception {
624         responseXML("<html/>", MimeType.APPLICATION_XHTML, true, false);
625     }
626 
627     /**
628      * @throws Exception if the test fails
629      */
630     @Test
631     @Alerts({"[object XMLDocument]", "[object Element]", "html", "§§URL§§foo"})
632     public void responseXMLAsyncDocument_application_xhtmlXml() throws Exception {
633         responseXML("<html/>", MimeType.APPLICATION_XHTML, true, true);
634     }
635 
636     /**
637      * @throws Exception if the test fails
638      */
639     @Test
640     @Alerts({"[object XMLDocument]", "[object SVGSVGElement]", "svg", "§§URL§§foo"})
641     @HtmlUnitNYI(CHROME = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
642             EDGE = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
643             FF = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
644             FF_ESR = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"})
645     public void responseXML_application_svgXml() throws Exception {
646         responseXML("<svg xmlns=\"http://www.w3.org/2000/svg\"/>", "image/svg+xml", false, false);
647     }
648 
649     /**
650      * @throws Exception if the test fails
651      */
652     @Test
653     @Alerts({"[object XMLDocument]", "[object SVGSVGElement]", "svg", "§§URL§§foo"})
654     @HtmlUnitNYI(CHROME = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
655             EDGE = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
656             FF = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
657             FF_ESR = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"})
658     public void responseXMLAsync_application_svgXml() throws Exception {
659         responseXML("<svg xmlns=\"http://www.w3.org/2000/svg\"/>", "image/svg+xml", true, false);
660     }
661 
662     /**
663      * @throws Exception if the test fails
664      */
665     @Test
666     @Alerts({"[object XMLDocument]", "[object SVGSVGElement]", "svg", "§§URL§§foo"})
667     @HtmlUnitNYI(CHROME = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
668             EDGE = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
669             FF = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
670             FF_ESR = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"})
671     public void responseXMLAsyncDocument_application_svgXml() throws Exception {
672         responseXML("<svg xmlns=\"http://www.w3.org/2000/svg\"/>", "image/svg+xml", true, true);
673     }
674 
675     private void responseXML(final String resp, final String mimeType,
676                     final boolean async, final boolean document) throws Exception {
677         String html = DOCTYPE_HTML
678             + "<html><head>\n"
679             + "<script>\n"
680             + LOG_TITLE_FUNCTION
681             + "  function test() {\n"
682             + "    var xhr = new XMLHttpRequest();\n";
683 
684         if (document) {
685             html +=  "    xhr.responseType = 'document';";
686         }
687         if (async) {
688             html += "    xhr.onreadystatechange = () => {\n"
689                     + "      if (xhr.readyState === 4) {\n"
690                     + "        let respXml = xhr.responseXML;\n"
691                     + "        log(respXml);\n"
692                     + "        if (respXml !== null) {\n"
693                     + "          log(respXml.documentElement);\n"
694                     + "          log(respXml.documentElement.tagName);\n"
695                     + "          log(respXml.documentElement.baseURI);\n"
696                     + "        }\n"
697                     + "      }\n"
698                     + "    }\n"
699                     + "    xhr.open('GET', 'foo', true);\n"
700                     + "    xhr.send('');\n";
701         }
702         else {
703             html += "    xhr.open('GET', 'foo', false);\n"
704                     + "    xhr.send('');\n"
705                     + "    let respXml = xhr.responseXML;\n"
706                     + "    log(respXml);\n"
707                     + "    if (respXml !== null) {\n"
708                     + "      log(respXml.documentElement);\n"
709                     + "      log(respXml.documentElement.tagName);\n"
710                     + "      log(respXml.documentElement.baseURI);\n"
711                     + "    }\n";
712         }
713 
714         html += "  }\n"
715                 + "</script></head><body onload='test()'>\n"
716                 + "</body></html>";
717 
718         getMockWebConnection().setDefaultResponse(resp, mimeType);
719         expandExpectedAlertsVariables(URL_FIRST);
720 
721         final WebDriver driver = loadPage2(html);
722         verifyTitle2(DEFAULT_WAIT_TIME.multipliedBy(2), driver, getExpectedAlerts());
723     }
724 
725     /**
726      * @throws Exception if the test fails
727      */
728     @Test
729     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
730     public void response_text_html() throws Exception {
731         response("<html></html>", MimeType.TEXT_HTML);
732     }
733 
734     /**
735      * @throws Exception if the test fails
736      */
737     @Test
738     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
739     public void response_text_html_empty() throws Exception {
740         response("", MimeType.TEXT_HTML);
741     }
742 
743     /**
744      * @throws Exception if the test fails
745      */
746     @Test
747     @Alerts({"[object HTMLDocument]", "[object HTMLHtmlElement]", "HTML", "§§URL§§foo"})
748     public void response_text_html_blank() throws Exception {
749         response("    ", MimeType.TEXT_HTML);
750     }
751 
752     /**
753      * @throws Exception if the test fails
754      */
755     @Test
756     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
757     public void response_text_xml() throws Exception {
758         response("<note/>", MimeType.TEXT_XML);
759     }
760 
761     /**
762      * @throws Exception if the test fails
763      */
764     @Test
765     @Alerts("null")
766     public void response_text_xml_empty() throws Exception {
767         response("", MimeType.TEXT_XML);
768     }
769 
770     /**
771      * @throws Exception if the test fails
772      */
773     @Test
774     @Alerts("null")
775     public void response_text_xml_blank() throws Exception {
776         response("    ", MimeType.TEXT_XML);
777     }
778 
779     /**
780      * @throws Exception if the test fails
781      */
782     @Test
783     @Alerts({"[object XMLDocument]", "[object Element]", "note", "§§URL§§foo"})
784     public void response_application_xml() throws Exception {
785         response("<note/>", MimeType.APPLICATION_XML);
786     }
787 
788     /**
789      * @throws Exception if the test fails
790      */
791     @Test
792     @Alerts({"[object XMLDocument]", "[object Element]", "html", "§§URL§§foo"})
793     public void responseAsyncDocument_application_xhtmlXml() throws Exception {
794         response("<html/>", MimeType.APPLICATION_XHTML);
795     }
796 
797     /**
798      * @throws Exception if the test fails
799      */
800     @Test
801     @Alerts({"[object XMLDocument]", "[object SVGSVGElement]", "svg", "§§URL§§foo"})
802     @HtmlUnitNYI(CHROME = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
803             EDGE = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
804             FF = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"},
805             FF_ESR = {"[object XMLDocument]", "[object SVGElement]", "svg", "§§URL§§foo"})
806     public void responseAsyncDocument_application_svgXml() throws Exception {
807         response("<svg xmlns=\"http://www.w3.org/2000/svg\"/>", "image/svg+xml");
808     }
809 
810     private void response(final String resp, final String mimeType) throws Exception {
811         final String html = DOCTYPE_HTML
812             + "<html><head>\n"
813             + "<script>\n"
814             + LOG_TITLE_FUNCTION
815             + "  function test() {\n"
816             + "    var xhr = new XMLHttpRequest();\n"
817             + "    xhr.responseType = 'document';"
818             + "    xhr.onreadystatechange = () => {\n"
819             + "      if (xhr.readyState === 4) {\n"
820             + "        let respXml = xhr.response;\n"
821             + "        log(respXml);\n"
822             + "        if (respXml !== null) {\n"
823             + "          log(respXml.documentElement);\n"
824             + "          log(respXml.documentElement.tagName);\n"
825             + "          log(respXml.documentElement.baseURI);\n"
826             + "        }\n"
827             + "      }\n"
828             + "    }\n"
829             + "    xhr.open('GET', 'foo', true);\n"
830             + "    xhr.send('');\n"
831             + "  }\n"
832             + "</script></head><body onload='test()'>\n"
833             + "</body></html>";
834 
835         getMockWebConnection().setDefaultResponse(resp, mimeType);
836         expandExpectedAlertsVariables(URL_FIRST);
837 
838         final WebDriver driver = loadPage2(html);
839         verifyTitle2(DEFAULT_WAIT_TIME.multipliedBy(2), driver, getExpectedAlerts());
840     }
841 
842     /**
843      * @throws Exception if the test fails
844      */
845     @Test
846     @Alerts("true")
847     public void responseXMLCalledTwoTimes() throws Exception {
848         final String html = DOCTYPE_HTML
849             + "<html><head>\n"
850             + "<script>\n"
851             + LOG_TITLE_FUNCTION
852             + "function test() {\n"
853             + "  var xhr = new XMLHttpRequest();\n"
854             + "  xhr.open('GET', 'foo', false);\n"
855             + "  xhr.send('');\n"
856             + "  let xml1 = xhr.responseXML;\n"
857             + "  let xml2 = xhr.responseXML;\n"
858             + "  log(xml1 === xml2);\n"
859             + "}\n"
860             + "</script>\n"
861             + "</head>\n"
862             + "<body onload='test()'></body></html>";
863 
864         getMockWebConnection().setDefaultResponse("<note/>", MimeType.TEXT_XML);
865 
866         final WebDriver driver = loadPage2(html);
867         verifyTitle2(DEFAULT_WAIT_TIME.multipliedBy(2), driver, getExpectedAlerts());
868     }
869 
870     /**
871      * @throws Exception if the test fails
872      */
873     @Test
874     @Alerts("true")
875     public void responseXMLAsyncCalledTwoTimes() throws Exception {
876         final String html = DOCTYPE_HTML
877             + "<html><head>\n"
878             + "<script>\n"
879             + LOG_TITLE_FUNCTION
880             + "function test() {\n"
881             + "  var xhr = new XMLHttpRequest();\n"
882             + "  xhr.onreadystatechange = () => {\n"
883             + "    if (xhr.readyState === 4) {\n"
884             + "      let xml1 = xhr.responseXML;\n"
885             + "      let xml2 = xhr.responseXML;\n"
886             + "      log(xml1 === xml2);\n"
887             + "    }\n"
888             + "  }\n"
889             + "  xhr.open('GET', 'foo', true);\n"
890             + "  xhr.send('');\n"
891             + "}\n"
892             + "</script>\n"
893             + "</head>\n"
894             + "<body onload='test()'></body></html>";
895 
896         getMockWebConnection().setDefaultResponse("<note/>", MimeType.TEXT_XML);
897 
898         final WebDriver driver = loadPage2(html);
899         verifyTitle2(DEFAULT_WAIT_TIME.multipliedBy(2), driver, getExpectedAlerts());
900     }
901 
902     /**
903      * @throws Exception if the test fails
904      */
905     @Test
906     @Alerts("true")
907     public void responseXMLDocumentXMLAsync() throws Exception {
908         final String html = DOCTYPE_HTML
909             + "<html><head>\n"
910             + "<script>\n"
911             + LOG_TITLE_FUNCTION
912             + "function test() {\n"
913             + "  var xhr = new XMLHttpRequest();\n"
914             + "  xhr.responseType = 'document';"
915             + "  xhr.onreadystatechange = () => {\n"
916             + "    if (xhr.readyState === 4) {\n"
917             + "      let xml1 = xhr.responseXML;\n"
918             + "      let xml2 = xhr.response;\n"
919             + "      log(xml1 === xml2);\n"
920             + "    }\n"
921             + "  }\n"
922             + "  xhr.open('GET', 'foo', true);\n"
923             + "  xhr.send('');\n"
924             + "}\n"
925             + "</script>\n"
926             + "</head>\n"
927             + "<body onload='test()'></body></html>";
928 
929         getMockWebConnection().setDefaultResponse("<note/>", MimeType.TEXT_XML);
930 
931         final WebDriver driver = loadPage2(html);
932         verifyTitle2(DEFAULT_WAIT_TIME.multipliedBy(2), driver, getExpectedAlerts());
933     }
934 
935     /**
936      * Regression test for IE specific properties attribute.text &amp; attribute.xml.
937      * @throws Exception if the test fails
938      */
939     @Test
940     @Alerts({"1", "someAttr", "undefined", "undefined"})
941     public void responseXML2() throws Exception {
942         final String html = DOCTYPE_HTML
943             + "<html><head>\n"
944             + "<script>\n"
945             + LOG_TITLE_FUNCTION
946             + "function test() {\n"
947             + "  var request = new XMLHttpRequest();\n"
948             + "  request.open('GET', 'foo.xml', false);\n"
949             + "  request.send('');\n"
950             + "  var childNodes = request.responseXML.childNodes;\n"
951             + "  log(childNodes.length);\n"
952             + "  var rootNode = childNodes[0];\n"
953             + "  log(rootNode.attributes[0].nodeName);\n"
954             + "  log(rootNode.attributes[0].text);\n"
955             + "  log(rootNode.attributes[0].xml);\n"
956             + "}\n"
957             + "</script>\n"
958             + "</head>\n"
959             + "<body onload='test()'></body></html>";
960 
961         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
962         getMockWebConnection().setResponse(urlPage2,
963             "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n",
964             MimeType.TEXT_XML);
965         loadPageVerifyTitle2(html);
966     }
967 
968     /**
969      * @throws Exception if the test fails
970      */
971     @Test
972     @Alerts("received: null")
973     public void responseXML_siteNotExisting() throws Exception {
974         final String html = DOCTYPE_HTML
975             + "<html><head>\n"
976             + "<script>\n"
977             + LOG_TITLE_FUNCTION
978             + "function test() {\n"
979             + "  var request = new XMLHttpRequest();\n"
980             + "try {\n"
981             + "  request.open('GET', 'http://this.doesnt.exist/foo.xml', false);\n"
982             + "  request.send('');\n"
983             + "} catch(e) {\n"
984             + "  log('received: ' + request.responseXML);\n"
985             + "}\n"
986             + "}\n"
987             + "</script>\n"
988             + "</head>\n"
989             + "<body onload='test()'></body></html>";
990 
991         loadPageVerifyTitle2(html);
992     }
993 
994     /**
995      * @throws Exception if the test fails
996      */
997     @Test
998     public void sendNull() throws Exception {
999         final String html = DOCTYPE_HTML
1000             + "<html><head>\n"
1001             + "<script>\n"
1002             + LOG_TITLE_FUNCTION
1003             + "function test() {\n"
1004             + "  var request = new XMLHttpRequest();\n"
1005             + "  request.open('GET', 'foo.txt', false);\n"
1006             + "  request.send(null);\n"
1007             + "}\n"
1008             + "</script>\n"
1009             + "</head>\n"
1010             + "<body onload='test()'></body></html>";
1011 
1012         getMockWebConnection().setDefaultResponse("");
1013         loadPageVerifyTitle2(html);
1014     }
1015 
1016     /**
1017      * Test calls to send('foo') for a GET. HtmlUnit 1.14 was incorrectly throwing an exception.
1018      * @throws Exception if the test fails
1019      */
1020     @Test
1021     public void sendGETWithContent() throws Exception {
1022         send("'foo'");
1023     }
1024 
1025     /**
1026      * Test calls to send() without any arguments.
1027      * @throws Exception if the test fails
1028      */
1029     @Test
1030     public void sendNoArg() throws Exception {
1031         send("");
1032     }
1033 
1034     /**
1035      * @throws Exception if the test fails
1036      */
1037     private void send(final String sendArg) throws Exception {
1038         final String html = DOCTYPE_HTML
1039             + "<html><head>\n"
1040             + "<script>\n"
1041             + LOG_TITLE_FUNCTION
1042             + "function test() {\n"
1043             + "  var request = new XMLHttpRequest();\n"
1044             + "  request.open('GET', 'foo.txt', false);\n"
1045             + "  request.send(" + sendArg + ");\n"
1046             + "}\n"
1047             + "</script>\n"
1048             + "</head>\n"
1049             + "<body onload='test()'></body></html>";
1050 
1051         getMockWebConnection().setDefaultResponse("");
1052         loadPageVerifyTitle2(html);
1053     }
1054 
1055     /**
1056      * Regression test for bug 1357412.
1057      * Response received by the XMLHttpRequest should not come in any window
1058      * @throws Exception if the test fails
1059      */
1060     @Test
1061     public void responseNotInWindow() throws Exception {
1062         final String html = DOCTYPE_HTML
1063             + "<html><head>\n"
1064             + "<script>\n"
1065             + LOG_TITLE_FUNCTION
1066             + "function test() {\n"
1067             + "  var request = new XMLHttpRequest();\n"
1068             + "  request.open('GET', 'foo.txt', false);\n"
1069             + "  request.send();\n"
1070             + "}\n"
1071             + "</script>\n"
1072             + "</head>\n"
1073             + "<body onload='test()'></body></html>";
1074 
1075         getMockWebConnection().setDefaultResponse("");
1076         final WebDriver driver = loadPageVerifyTitle2(html);
1077         assertEquals(URL_FIRST.toString(), driver.getCurrentUrl());
1078     }
1079 
1080     /**
1081      * @throws Exception if the test fails
1082      */
1083     @Test
1084     @Alerts({"true", "false"})
1085     public void overrideMimeType() throws Exception {
1086         final String html = DOCTYPE_HTML
1087             + "<html><head>\n"
1088             + "<script>\n"
1089             + LOG_TITLE_FUNCTION
1090             + "function test() {\n"
1091             + "try {\n"
1092             + "  var request = new XMLHttpRequest();\n"
1093             + "  request.open('GET', 'foo.xml.txt', false);\n"
1094             + "  request.send('');\n"
1095             + "  log(request.responseXML == null);\n"
1096             + "  request.open('GET', 'foo.xml.txt', false);\n"
1097             + "  request.overrideMimeType('text/xml');\n"
1098             + "  request.send('');\n"
1099             + "  log(request.responseXML == null);\n"
1100             + "} catch(e) { logEx(e); }\n"
1101             + "}\n"
1102             + "</script>\n"
1103             + "</head>\n"
1104             + "<body onload='test()'></body></html>";
1105 
1106         final URL urlPage2 = new URL(URL_FIRST, "foo.xml.txt");
1107         getMockWebConnection().setResponse(urlPage2,
1108             "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n",
1109             MimeType.TEXT_PLAIN);
1110         loadPageVerifyTitle2(html);
1111     }
1112 
1113     /**
1114      * @throws Exception if the test fails
1115      */
1116     @Test
1117     @Alerts({"true", "InvalidStateError/DOMException"})
1118     public void overrideMimeTypeAfterSend() throws Exception {
1119         final String html = DOCTYPE_HTML
1120             + "<html><head>\n"
1121             + "<script>\n"
1122             + LOG_TITLE_FUNCTION
1123             + "function test() {\n"
1124             + "  var request = new XMLHttpRequest();\n"
1125             + "  request.open('GET', 'foo.xml.txt', false);\n"
1126             + "  request.send('');\n"
1127             + "  log(request.responseXML == null);\n"
1128             + "  try {\n"
1129             + "    request.overrideMimeType('text/xml');\n"
1130             + "    log('overwritten');\n"
1131             + "  } catch(e) { logEx(e); }\n"
1132             + "}\n"
1133             + "</script>\n"
1134             + "</head>\n"
1135             + "<body onload='test()'></body></html>";
1136 
1137         final URL urlPage2 = new URL(URL_FIRST, "foo.xml.txt");
1138         getMockWebConnection().setResponse(urlPage2,
1139             "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n",
1140             MimeType.TEXT_PLAIN);
1141         loadPageVerifyTitle2(html);
1142     }
1143 
1144     /**
1145      * @throws Exception if the test fails
1146      */
1147     @Test
1148     @Alerts("27035")
1149     public void overrideMimeType_charset() throws Exception {
1150         final String html = DOCTYPE_HTML
1151             + "<html><head>\n"
1152             + "<script>\n"
1153             + LOG_TITLE_FUNCTION
1154             + "function test() {\n"
1155             + "try {\n"
1156             + "  var request = new XMLHttpRequest();\n"
1157             + "  request.open('GET', '" + URL_SECOND + "', false);\n"
1158             + "  request.overrideMimeType('text/plain; charset=GBK');\n"
1159             + "  request.send('');\n"
1160             + "  log(request.responseText.charCodeAt(0));\n"
1161             + "} catch(e) { logEx(e); }\n"
1162             + "}\n"
1163             + "</script>\n"
1164             + "</head>\n"
1165             + "<body onload='test()'></body></html>";
1166 
1167         getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", MimeType.TEXT_PLAIN, UTF_8);
1168         loadPageVerifyTitle2(html);
1169     }
1170 
1171     /**
1172      * @throws Exception if the test fails
1173      */
1174     @Test
1175     @Alerts("27035")
1176     public void overrideMimeType_charset_upper_case() throws Exception {
1177         final String html = DOCTYPE_HTML
1178             + "<html><head>\n"
1179             + "<script>\n"
1180             + LOG_TITLE_FUNCTION
1181             + "function test() {\n"
1182             + "try {\n"
1183             + "  var request = new XMLHttpRequest();\n"
1184             + "  request.open('GET', '" + URL_SECOND + "', false);\n"
1185             + "  request.overrideMimeType('text/plain; chaRSet=GBK');\n"
1186             + "  request.send('');\n"
1187             + "  log(request.responseText.charCodeAt(0));\n"
1188             + "} catch(e) { logEx(e); }\n"
1189             + "}\n"
1190             + "</script>\n"
1191             + "</head>\n"
1192             + "<body onload='test()'></body></html>";
1193 
1194         getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", MimeType.TEXT_PLAIN, UTF_8);
1195         loadPageVerifyTitle2(html);
1196     }
1197 
1198     /**
1199      * @throws Exception if the test fails
1200      */
1201     @Test
1202     @Alerts("40644")
1203     public void overrideMimeType_charset_empty() throws Exception {
1204         final String html = DOCTYPE_HTML
1205             + "<html><head>\n"
1206             + "<script>\n"
1207             + LOG_TITLE_FUNCTION
1208             + "function test() {\n"
1209             + "try {\n"
1210             + "  var request = new XMLHttpRequest();\n"
1211             + "  request.open('GET', '" + URL_SECOND + "', false);\n"
1212             + "  request.overrideMimeType('text/plain; charset=');\n"
1213             + "  request.send('');\n"
1214             + "  log(request.responseText.charCodeAt(0));\n"
1215             + "} catch(e) { logEx(e); }\n"
1216             + "}\n"
1217             + "</script>\n"
1218             + "</head>\n"
1219             + "<body onload='test()'></body></html>";
1220 
1221         getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", MimeType.TEXT_PLAIN, UTF_8);
1222         loadPageVerifyTitle2(html);
1223     }
1224 
1225     /**
1226      * @throws Exception if the test fails
1227      */
1228     @Test
1229     @Alerts("40644")
1230     public void overrideMimeType_charset_wrong() throws Exception {
1231         final String html = DOCTYPE_HTML
1232             + "<html><head>\n"
1233             + "<script>\n"
1234             + LOG_TITLE_FUNCTION
1235             + "function test() {\n"
1236             + "  try {\n"
1237             + "    var request = new XMLHttpRequest();\n"
1238             + "    request.open('GET', '" + URL_SECOND + "', false);\n"
1239             + "    request.overrideMimeType('text/plain; charset=abcdefg');\n"
1240             + "    request.send('');\n"
1241             + "    var text = request.responseText;\n"
1242             + "    for (var i = 0; i < text.length; i++) {\n"
1243             + "      log(text.charCodeAt(i));\n"
1244             + "    }\n"
1245             + "  } catch(e) { logEx(e); }\n"
1246             + "}\n"
1247             + "</script>\n"
1248             + "</head>\n"
1249             + "<body onload='test()'></body></html>";
1250 
1251         getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", MimeType.TEXT_PLAIN, UTF_8);
1252         loadPageVerifyTitle2(html);
1253     }
1254 
1255     /**
1256      * Regression test for bug 410.
1257      * http://sourceforge.net/p/htmlunit/bugs/410/
1258      * Caution: the problem appeared with JDK 1.4 but not with JDK 1.5 as String contains a
1259      * replace(CharSequence, CharSequence) method in this version
1260      * @throws Exception if the test fails
1261      */
1262     @Test
1263     @Alerts({"ibcdefg", "xxxxxfg"})
1264     public void replaceOnTextData() throws Exception {
1265         final String html = DOCTYPE_HTML
1266             + "<html>\n"
1267             + "  <head>\n"
1268             + "    <script>\n"
1269             + LOG_TITLE_FUNCTION
1270             + "      var request;\n"
1271             + "      function testReplace() {\n"
1272             + "        request = new XMLHttpRequest();\n"
1273             + "        request.onreadystatechange = onReadyStateChange;\n"
1274             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
1275             + "        request.send('');\n"
1276             + "      }\n"
1277             + "      function onReadyStateChange() {\n"
1278             + "        if (request.readyState == 4){\n"
1279             + "          var theXML = request.responseXML;\n"
1280             + "          var theDoc = theXML.documentElement;\n"
1281             + "          var theElements = theDoc.getElementsByTagName('update');\n"
1282             + "          var theUpdate = theElements[0];\n"
1283             + "          var theData = theUpdate.firstChild.data;\n"
1284             + "          theResult = theData.replace('a','i');\n"
1285             + "          log(theResult);\n"
1286             + "          theResult = theData.replace('abcde', 'xxxxx');\n"
1287             + "          log(theResult);\n"
1288             + "        }\n"
1289             + "      }\n"
1290             + "    </script>\n"
1291             + "  </head>\n"
1292             + "  <body onload='testReplace()'>\n"
1293             + "  </body>\n"
1294             + "</html>";
1295 
1296         final String xml =
1297               "<updates>\n"
1298             + "<update>abcdefg</update>\n"
1299             + "<update>hijklmn</update>\n"
1300             + "</updates>";
1301 
1302         getMockWebConnection().setDefaultResponse(xml, MimeType.TEXT_XML);
1303         loadPageVerifyTitle2(html);
1304     }
1305 
1306     /**
1307      * Tests that the <tt>Referer</tt> header is set correctly.
1308      * @throws Exception if the test fails
1309      */
1310     @Test
1311     public void refererHeader() throws Exception {
1312         final String html = DOCTYPE_HTML
1313             + "<html><head><script>\n"
1314             + "function test() {\n"
1315             + "  req = new XMLHttpRequest();\n"
1316             + "  req.open('post', 'foo.xml', false);\n"
1317             + "  req.send('');\n"
1318             + "}\n"
1319             + "</script></head>\n"
1320             + "<body onload='test()'></body></html>";
1321 
1322         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1323         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1324         loadPage2(html);
1325 
1326         final WebRequest request = getMockWebConnection().getLastWebRequest();
1327         assertEquals(urlPage2, request.getUrl());
1328         assertEquals(URL_FIRST.toExternalForm(), request.getAdditionalHeaders().get(HttpHeader.REFERER));
1329     }
1330 
1331     /**
1332      * Tests that the <tt>origin</tt> header is set correctly.
1333      * @throws Exception if the test fails
1334      */
1335     @Test
1336     @Alerts("null")
1337     public void originHeaderGet() throws Exception {
1338         final String html = DOCTYPE_HTML
1339             + "<html><head><script>\n"
1340             + "function test() {\n"
1341             + "  req = new XMLHttpRequest();\n"
1342             + "  req.open('get', 'foo.xml', false);\n"
1343             + "  req.send('');\n"
1344             + "}\n"
1345             + "</script></head>\n"
1346             + "<body onload='test()'></body></html>";
1347 
1348         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1349         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1350         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1351         loadPage2(html);
1352 
1353         final WebRequest request = getMockWebConnection().getLastWebRequest();
1354         assertEquals(urlPage2, request.getUrl());
1355         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1356         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1357     }
1358 
1359     /**
1360      * Tests that the <tt>origin</tt> header is set correctly.
1361      * @throws Exception if the test fails
1362      */
1363     @Test
1364     @Alerts("§§URL§§")
1365     public void originHeaderPost() throws Exception {
1366         final String html = DOCTYPE_HTML
1367             + "<html><head><script>\n"
1368             + "function test() {\n"
1369             + "  req = new XMLHttpRequest();\n"
1370             + "  req.open('post', 'foo.xml', false);\n"
1371             + "  req.send('');\n"
1372             + "}\n"
1373             + "</script></head>\n"
1374             + "<body onload='test()'></body></html>";
1375 
1376         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1377         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1378         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1379         loadPage2(html);
1380 
1381         final WebRequest request = getMockWebConnection().getLastWebRequest();
1382         assertEquals(urlPage2, request.getUrl());
1383         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1384         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1385     }
1386 
1387     /**
1388      * Tests that the <tt>origin</tt> header is set correctly.
1389      * @throws Exception if the test fails
1390      */
1391     @Test
1392     @Alerts("§§URL§§")
1393     public void originHeaderPut() throws Exception {
1394         final String html = DOCTYPE_HTML
1395             + "<html><head><script>\n"
1396             + "function test() {\n"
1397             + "  req = new XMLHttpRequest();\n"
1398             + "  req.open('put', 'foo.xml', false);\n"
1399             + "  req.send('');\n"
1400             + "}\n"
1401             + "</script></head>\n"
1402             + "<body onload='test()'></body></html>";
1403 
1404         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1405         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1406         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1407         loadPage2(html);
1408 
1409         final WebRequest request = getMockWebConnection().getLastWebRequest();
1410         assertEquals(urlPage2, request.getUrl());
1411         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1412         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1413     }
1414 
1415     /**
1416      * Tests that the <tt>origin</tt> header is set correctly.
1417      * @throws Exception if the test fails
1418      */
1419     @Test
1420     @Alerts("§§URL§§")
1421     public void originHeaderDelete() throws Exception {
1422         final String html = DOCTYPE_HTML
1423             + "<html><head><script>\n"
1424             + "function test() {\n"
1425             + "  req = new XMLHttpRequest();\n"
1426             + "  req.open('delete', 'foo.xml', false);\n"
1427             + "  req.send('');\n"
1428             + "}\n"
1429             + "</script></head>\n"
1430             + "<body onload='test()'></body></html>";
1431 
1432         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1433         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1434         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1435         loadPage2(html);
1436 
1437         final WebRequest request = getMockWebConnection().getLastWebRequest();
1438         assertEquals(urlPage2, request.getUrl());
1439         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1440         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1441     }
1442 
1443     /**
1444      * Tests that the <tt>origin</tt> header is set correctly.
1445      * @throws Exception if the test fails
1446      */
1447     @Test
1448     @Alerts({"§§URL§§/", "null", "null"})
1449     @HtmlUnitNYI(CHROME = {"§§URL§§/foo.xml", "null", "null"},
1450             EDGE = {"§§URL§§/foo.xml", "null", "null"},
1451             FF = {"§§URL§§/foo.xml", "null", "null"},
1452             FF_ESR = {"§§URL§§/foo.xml", "null", "null"})
1453     public void originHeaderPatch() throws Exception {
1454         final String html = DOCTYPE_HTML
1455             + "<html><head><script>\n"
1456             + "function test() {\n"
1457             + "  req = new XMLHttpRequest();\n"
1458             + "  req.open('patch', 'foo.xml', false);\n"
1459             + "  req.send('');\n"
1460             + "}\n"
1461             + "</script></head>\n"
1462             + "<body onload='test()'></body></html>";
1463 
1464         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1465         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1466         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1467         loadPage2(html);
1468 
1469         expandExpectedAlertsVariables(URL_FIRST);
1470 
1471         final WebRequest request = getMockWebConnection().getLastWebRequest();
1472         assertEquals(getExpectedAlerts()[0], request.getUrl());
1473         assertEquals(getExpectedAlerts()[1],
1474                         "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1475         assertEquals(getExpectedAlerts()[2],
1476                         "" + request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1477     }
1478 
1479     /**
1480      * Tests that the <tt>origin</tt> header is set correctly.
1481      * @throws Exception if the test fails
1482      */
1483     @Test
1484     @Alerts("null")
1485     public void originHeaderTrace() throws Exception {
1486         final String html = DOCTYPE_HTML
1487             + "<html><head><script>\n"
1488             + "function test() {\n"
1489             + "  req = new XMLHttpRequest();\n"
1490             + "  req.open('trace', 'foo.xml', false);\n"
1491             + "  req.send('');\n"
1492             + "}\n"
1493             + "</script></head>\n"
1494             + "<body onload='test()'></body></html>";
1495 
1496         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1497         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1498         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1499         loadPage2(html);
1500 
1501         final WebRequest request = getMockWebConnection().getLastWebRequest();
1502         assertEquals(URL_FIRST, request.getUrl());
1503         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1504         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1505     }
1506 
1507     /**
1508      * Tests that the <tt>origin</tt> header is set correctly.
1509      * @throws Exception if the test fails
1510      */
1511     @Test
1512     @Alerts("null")
1513     public void originHeaderHead() throws Exception {
1514         final String html = DOCTYPE_HTML
1515             + "<html><head><script>\n"
1516             + "function test() {\n"
1517             + "  req = new XMLHttpRequest();\n"
1518             + "  req.open('head', 'foo.xml', false);\n"
1519             + "  req.send('');\n"
1520             + "}\n"
1521             + "</script></head>\n"
1522             + "<body onload='test()'></body></html>";
1523 
1524         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1525         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1526         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1527         loadPage2(html);
1528 
1529         final WebRequest request = getMockWebConnection().getLastWebRequest();
1530         assertEquals(urlPage2, request.getUrl());
1531         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1532         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1533     }
1534 
1535     /**
1536      * Tests that the <tt>origin</tt> header is set correctly.
1537      * @throws Exception if the test fails
1538      */
1539     @Test
1540     @Alerts("§§URL§§")
1541     public void originHeaderOptions() throws Exception {
1542         final String html = DOCTYPE_HTML
1543             + "<html><head><script>\n"
1544             + "function test() {\n"
1545             + "  req = new XMLHttpRequest();\n"
1546             + "  req.open('options', 'foo.xml', false);\n"
1547             + "  req.send('');\n"
1548             + "}\n"
1549             + "</script></head>\n"
1550             + "<body onload='test()'></body></html>";
1551 
1552         final URL urlPage2 = new URL(URL_FIRST, "foo.xml");
1553         getMockWebConnection().setResponse(urlPage2, "<foo/>\n", MimeType.TEXT_XML);
1554         expandExpectedAlertsVariables(urlPage2.getProtocol() + "://" + urlPage2.getHost() + ":" + urlPage2.getPort());
1555         loadPage2(html);
1556 
1557         final WebRequest request = getMockWebConnection().getLastWebRequest();
1558         assertEquals(urlPage2, request.getUrl());
1559         assertEquals(getExpectedAlerts()[0], "" + request.getAdditionalHeaders().get(HttpHeader.ORIGIN));
1560         assertEquals(null, request.getAdditionalHeaders().get(HttpHeader.ACCESS_CONTROL_ALLOW_ORIGIN));
1561     }
1562 
1563     /**
1564      * Test for bug
1565      * <a href="https://sourceforge.net/tracker/?func=detail&atid=448266&aid=1784330&group_id=47038">issue 515</a>.
1566      * @throws Exception if an error occurs
1567      */
1568     @Test
1569     @Alerts("ActiveXObject not available")
1570     public void caseInsensitivityActiveXConstructor() throws Exception {
1571         final String html = DOCTYPE_HTML
1572             + "<html><head>\n"
1573             + "<script>\n"
1574             + LOG_TITLE_FUNCTION
1575             + "function test() {\n"
1576             + "  try {\n"
1577             + "    var req = new ActiveXObject('MSXML2.XmlHttp');\n"
1578             + "    log(req.readyState);\n"
1579 
1580             + "    var req = new ActiveXObject('msxml2.xMLhTTp');\n"
1581             + "    log(req.readyState);\n"
1582             + "  } catch(e) { log('ActiveXObject not available'); }\n"
1583             + "}\n"
1584             + "</script></head>\n"
1585             + "<body onload='test()'></body></html>";
1586 
1587         loadPageVerifyTitle2(html);
1588     }
1589 
1590     /**
1591      * @throws Exception if the test fails
1592      */
1593     @Test
1594     @Alerts("selectNodes not available")
1595     public void responseXML_selectNodesIE() throws Exception {
1596         final String html = DOCTYPE_HTML
1597             + "<html>\n"
1598             + "  <head>\n"
1599             + "    <script>\n"
1600             + LOG_TITLE_FUNCTION
1601             + "      function test() {\n"
1602             + "        var request = new XMLHttpRequest();\n"
1603             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
1604             + "        request.send('');\n"
1605             + "        if (!request.responseXML.selectNodes) { log('selectNodes not available'); return }\n"
1606             + "        log(request.responseXML.selectNodes('//content').length);\n"
1607             + "      }\n"
1608             + "    </script>\n"
1609             + "  </head>\n"
1610             + "  <body onload='test()'>\n"
1611             + "  </body>\n"
1612             + "</html>";
1613 
1614         final String xml =
1615               "<xml>\n"
1616             + "<content>blah</content>\n"
1617             + "<content>blah2</content>\n"
1618             + "</xml>";
1619 
1620         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1621         loadPageVerifyTitle2(html);
1622     }
1623 
1624     /**
1625      * @throws Exception if the test fails
1626      */
1627     @Test
1628     @Alerts({"[object Element]", "myID", "blah", "span", "[object XMLDocument]", "[object XMLDocument]"})
1629     public void responseXML_getElementById2() throws Exception {
1630         final String html = DOCTYPE_HTML
1631             + "<html>\n"
1632             + "  <head>\n"
1633             + "    <script>\n"
1634             + LOG_TITLE_FUNCTION
1635             + "      function test() {\n"
1636             + "        var request = new XMLHttpRequest();\n"
1637             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
1638             + "        request.send('');\n"
1639             + "        if (request.responseXML.getElementById) {\n"
1640             + "          log(request.responseXML.getElementById('id1'));\n"
1641             + "          log(request.responseXML.getElementById('myID').id);\n"
1642             + "          log(request.responseXML.getElementById('myID').innerHTML);\n"
1643             + "          log(request.responseXML.getElementById('myID').tagName);\n"
1644             + "          log(request.responseXML.getElementById('myID').ownerDocument);\n"
1645             + "          if (request.responseXML.getElementById('myID').getRootNode) {\n"
1646             + "            log(request.responseXML.getElementById('myID').getRootNode());\n"
1647             + "          } else log('-');\n"
1648             + "        } else  {\n"
1649             + "          log('responseXML.getElementById not available');\n"
1650             + "        }\n"
1651             + "      }\n"
1652             + "    </script>\n"
1653             + "  </head>\n"
1654             + "  <body onload='test()'>\n"
1655             + "  </body>\n"
1656             + "</html>";
1657 
1658         final String xml =
1659               "<xml>\n"
1660             + "<content id='id1'>blah</content>\n"
1661             + "<content>blah2</content>\n"
1662             + "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
1663             + "<span id='myID'>blah</span>\n"
1664             + "<script src='foo.js'></script>\n"
1665             + "</html>\n"
1666             + "</xml>";
1667 
1668         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1669         loadPageVerifyTitle2(html);
1670     }
1671 
1672     /**
1673      * @throws Exception if the test fails
1674      */
1675     @Test
1676     @Alerts({"[object Element]", "[object Element]", "[object HTMLBodyElement]",
1677              "[object HTMLSpanElement]", "[object XMLDocument]", "[object XMLDocument]", "undefined"})
1678     public void responseXML_getElementById() throws Exception {
1679         final String html = DOCTYPE_HTML
1680             + "<html>\n"
1681             + "  <head>\n"
1682             + "    <script>\n"
1683             + LOG_TITLE_FUNCTION
1684             + "      function test() {\n"
1685             + "        var request = new XMLHttpRequest();\n"
1686             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
1687             + "        request.send('');\n"
1688             + "        var doc = request.responseXML;\n"
1689             + "        log(doc.documentElement);\n"
1690             + "        log(doc.documentElement.childNodes[0]);\n"
1691             + "        log(doc.documentElement.childNodes[1]);\n"
1692             + "        if (doc.getElementById) {\n"
1693             + "          log(doc.getElementById('out'));\n"
1694             + "          log(doc.getElementById('out').ownerDocument);\n"
1695             + "          if (doc.getElementById('out').getRootNode) {\n"
1696             + "            log(doc.getElementById('out').getRootNode());\n"
1697             + "          } else log('-');\n"
1698             + "        }\n"
1699             + "        log(doc.documentElement.childNodes[1].xml);\n"
1700             + "      }\n"
1701             + "    </script>\n"
1702             + "  </head>\n"
1703             + "  <body onload='test()'>\n"
1704             + "  </body>\n"
1705             + "</html>";
1706 
1707         final String xml = DOCTYPE_HTML
1708             + "<html>"
1709             + "<head>"
1710             + "</head>"
1711             + "<body xmlns='http://www.w3.org/1999/xhtml'>"
1712             + "<span id='out'>Hello Bob Dole!</span>"
1713             + "</body>"
1714             + "</html>";
1715 
1716         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1717         loadPageVerifyTitle2(html);
1718     }
1719 
1720     /**
1721      * Verifies that the default encoding for an XMLHttpRequest is UTF-8.
1722      * @throws Exception if an error occurs
1723      */
1724     @Test
1725     @Alerts("ol\u00E9")
1726     public void defaultEncodingIsUTF8() throws Exception {
1727         final String html = DOCTYPE_HTML
1728             + "<html>\n"
1729             + "  <head>\n"
1730             + "    <script>\n"
1731             + LOG_TITLE_FUNCTION
1732             + "      function test() {\n"
1733             + "        var request = new XMLHttpRequest();\n"
1734             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
1735             + "        request.send('');\n"
1736             + "        log(request.responseText);\n"
1737             + "      }\n"
1738             + "    </script>\n"
1739             + "  </head>\n"
1740             + "  <body onload='test()'>\n"
1741             + "  </body>\n"
1742             + "</html>";
1743 
1744         final String response = "ol\u00E9";
1745         final byte[] responseBytes = response.getBytes(UTF_8);
1746 
1747         getMockWebConnection().setResponse(URL_SECOND, responseBytes, 200, "OK", MimeType.TEXT_HTML,
1748             new ArrayList<>());
1749         loadPageVerifyTitle2(html);
1750     }
1751 
1752     /**
1753      * Custom servlet which streams content to the client little by little.
1754      */
1755     public static final class StreamingServlet extends HttpServlet {
1756         /** {@inheritDoc} */
1757         @Override
1758         protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
1759             resp.setStatus(200);
1760             resp.addHeader(HttpHeader.CONTENT_TYPE, MimeType.TEXT_HTML);
1761             try {
1762                 for (int i = 0; i < 10; i++) {
1763                     resp.getOutputStream().print(String.valueOf(i));
1764                     resp.flushBuffer();
1765                     Thread.sleep(150);
1766                 }
1767             }
1768             catch (final InterruptedException e) {
1769                 throw new RuntimeException(e);
1770             }
1771         }
1772     }
1773 
1774     /**
1775      * Servlet for testing XMLHttpRequest basic authentication.
1776      */
1777     public static final class BasicAuthenticationServlet extends HttpServlet {
1778 
1779         /**
1780          * {@inheritDoc}
1781          */
1782         @Override
1783         protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
1784             handleRequest(req, resp);
1785         }
1786 
1787         /**
1788          * {@inheritDoc}
1789          */
1790         @Override
1791         protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
1792             handleRequest(req, resp);
1793         }
1794 
1795         private static void handleRequest(final HttpServletRequest req, final HttpServletResponse resp)
1796                     throws IOException {
1797             final String authHdr = req.getHeader("Authorization");
1798             if (null == authHdr) {
1799                 resp.setStatus(401);
1800                 resp.setHeader("WWW-Authenticate", "Basic realm=\"someRealm\"");
1801             }
1802             else {
1803                 final String[] authHdrTokens = authHdr.split("\\s+");
1804                 String authToken = "";
1805                 if (authHdrTokens.length == 2) {
1806                     authToken += authHdrTokens[0] + ':' + authHdrTokens[1];
1807                 }
1808 
1809                 resp.setStatus(200);
1810                 resp.addHeader(HttpHeader.CONTENT_TYPE, MimeType.TEXT_PLAIN);
1811                 resp.getOutputStream().print(authToken);
1812                 resp.flushBuffer();
1813             }
1814         }
1815     }
1816 
1817     /**
1818      * @throws Exception if the test fails
1819      */
1820     @Test
1821     @Alerts("myID")
1822     public void responseXML_html_select() throws Exception {
1823         final String html = DOCTYPE_HTML
1824             + "<html>\n"
1825             + "  <head>\n"
1826             + "    <script>\n"
1827             + LOG_TITLE_FUNCTION
1828             + "      function test() {\n"
1829             + "        try {\n"
1830             + "          var request = new XMLHttpRequest();\n"
1831             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
1832             + "          request.send('');\n"
1833             + "          log(request.responseXML.getElementById('myID').id);\n"
1834             + "        } catch(e) { logEx(e); }\n"
1835             + "      }\n"
1836             + "    </script>\n"
1837             + "  </head>\n"
1838             + "  <body onload='test()'>\n"
1839             + "  </body>\n"
1840             + "</html>";
1841 
1842         final String xml =
1843               "<xml>\n"
1844             + "<content id='id1'>blah</content>\n"
1845             + "<content>blah2</content>\n"
1846             + "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
1847             + "<select id='myID'><option>One</option></select>\n"
1848             + "</html>\n"
1849             + "</xml>";
1850 
1851         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1852         loadPageVerifyTitle2(html);
1853     }
1854 
1855     /**
1856      * @throws Exception if the test fails
1857      */
1858     @Test
1859     @Alerts("myInput")
1860     public void responseXML_html_form() throws Exception {
1861         final String html = DOCTYPE_HTML
1862             + "<html>\n"
1863             + "  <head>\n"
1864             + "    <script>\n"
1865             + LOG_TITLE_FUNCTION
1866             + "      function test() {\n"
1867             + "        try {\n"
1868             + "          var request = new XMLHttpRequest();\n"
1869             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
1870             + "          request.send('');\n"
1871             + "          log(request.responseXML.getElementById('myID').myInput.name);\n"
1872             + "        } catch(e) { logEx(e); }\n"
1873             + "      }\n"
1874             + "    </script>\n"
1875             + "  </head>\n"
1876             + "  <body onload='test()'>\n"
1877             + "  </body>\n"
1878             + "</html>";
1879 
1880         final String xml =
1881               "<xml>\n"
1882             + "<content id='id1'>blah</content>\n"
1883             + "<content>blah2</content>\n"
1884             + "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
1885             + "<form id='myID'><input name='myInput'/></form>\n"
1886             + "</html>\n"
1887             + "</xml>";
1888 
1889         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
1890         loadPageVerifyTitle2(html);
1891     }
1892 
1893     /**
1894      * @throws Exception if an error occurs
1895      */
1896     @Test
1897     @Alerts("ActiveXObject not available")
1898     public void caseSensitivity_activeX() throws Exception {
1899         final String html = DOCTYPE_HTML
1900             + "<html><head>\n"
1901             + "<script>\n"
1902             + LOG_TITLE_FUNCTION
1903             + "function test() {\n"
1904             + "  try {\n"
1905             + "    var req = new ActiveXObject('MSXML2.XmlHttp');\n"
1906             + "    log(req.readyState);\n"
1907             + "    log(req.reAdYsTaTe);\n"
1908             + "  } catch(e) { log('ActiveXObject not available'); }\n"
1909             + "}\n"
1910             + "</script></head>\n"
1911             + "<body onload='test()'></body></html>";
1912         loadPageVerifyTitle2(html);
1913     }
1914 
1915     /**
1916      * @throws Exception if an error occurs
1917      */
1918     @Test
1919     @Alerts({"0", "undefined"})
1920     public void caseSensitivity_XMLHttpRequest() throws Exception {
1921         final String html = DOCTYPE_HTML
1922             + "<html><head>\n"
1923             + "<script>\n"
1924             + LOG_TITLE_FUNCTION
1925             + "function test() {\n"
1926             + "  try {\n"
1927             + "    var req = new XMLHttpRequest();\n"
1928             + "    log(req.readyState);\n"
1929             + "    log(req.reAdYsTaTe);\n"
1930             + "  } catch(e) { logEx(e); }\n"
1931             + "}\n"
1932             + "</script></head>\n"
1933             + "<body onload='test()'></body></html>";
1934         loadPageVerifyTitle2(html);
1935     }
1936 
1937     /**
1938      * @throws Exception if the test fails
1939      */
1940     @Test
1941     public void isAuthorizedHeader() throws Exception {
1942         assertTrue(XMLHttpRequest.isAuthorizedHeader("Foo"));
1943         assertTrue(XMLHttpRequest.isAuthorizedHeader(HttpHeader.CONTENT_TYPE));
1944 
1945         final String[] headers = {"accept-charset", HttpHeader.ACCEPT_ENCODING_LC,
1946             HttpHeader.CONNECTION_LC, HttpHeader.CONTENT_LENGTH_LC, HttpHeader.COOKIE_LC, "cookie2",
1947             "content-transfer-encoding", "date",
1948             "expect", HttpHeader.HOST_LC, "keep-alive", HttpHeader.REFERER_LC,
1949             "te", "trailer", "transfer-encoding", "upgrade",
1950             HttpHeader.USER_AGENT_LC, "via" };
1951         for (final String header : headers) {
1952             assertFalse(XMLHttpRequest.isAuthorizedHeader(header));
1953             assertFalse(XMLHttpRequest.isAuthorizedHeader(header.toUpperCase(Locale.ROOT)));
1954         }
1955         assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-"));
1956         assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-Control"));
1957         assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-Hack"));
1958         assertFalse(XMLHttpRequest.isAuthorizedHeader("Sec-"));
1959         assertFalse(XMLHttpRequest.isAuthorizedHeader("Sec-Hack"));
1960     }
1961 
1962     /**
1963      * Test case for Bug #1623.
1964      *
1965      * @throws Exception if the test fails
1966      */
1967     @Test
1968     @Alerts({"39", "27035", "65533", "39"})
1969     public void overrideMimeType_charset_all() throws Exception {
1970         final String html = DOCTYPE_HTML
1971             + "<html><head>\n"
1972             + "<script>\n"
1973             + LOG_TITLE_FUNCTION
1974             + "function test() {\n"
1975             + "try {\n"
1976             + "  var request = new XMLHttpRequest();\n"
1977             + "  request.open('GET', '" + URL_SECOND + "', false);\n"
1978             + "  request.overrideMimeType('text/plain; charset=GBK');\n"
1979             + "  request.send('');\n"
1980             + "  for (var i = 0; i < request.responseText.length; i++) {\n"
1981             + "    log(request.responseText.charCodeAt(i));\n"
1982             + "  }\n"
1983             + "} catch(e) { logEx(e); }\n"
1984             + "}\n"
1985             + "</script>\n"
1986             + "</head>\n"
1987             + "<body onload='test()'></body></html>";
1988 
1989         getMockWebConnection().setResponse(URL_SECOND, "'\u9EC4'", MimeType.TEXT_PLAIN, UTF_8);
1990         loadPageVerifyTitle2(html);
1991     }
1992 
1993     /**
1994      * @throws Exception if the test fails
1995      */
1996     @Test
1997     public void java_encoding() throws Exception {
1998         // Chrome and FF return the last apostrophe, see overrideMimeType_charset_all()
1999         // but Java and other tools (e.g. Notpad++) return only 3 characters, not 4
2000         // this method is not a test case, but rather to show the behavior of java
2001 
2002         final String string = "'\u9EC4'";
2003         final ByteArrayInputStream bais = new ByteArrayInputStream(string.getBytes(UTF_8));
2004         try (BufferedReader reader = new BufferedReader(new InputStreamReader(bais, "GBK"))) {
2005             final String output = reader.readLine();
2006             assertNotNull(output);
2007             assertEquals(39, output.codePointAt(0));
2008             assertEquals(27035, output.codePointAt(1));
2009             assertEquals(65533, output.codePointAt(2));
2010             assertEquals(39, output.codePointAt(3));
2011         }
2012     }
2013 
2014     /**
2015      * @throws Exception if the test fails
2016      */
2017     @Test
2018     @Alerts("[object ProgressEvent]")
2019     public void loadParameter() throws Exception {
2020         final String html = DOCTYPE_HTML
2021             + "<html>\n"
2022             + "  <head>\n"
2023             + "    <script>\n"
2024             + LOG_TITLE_FUNCTION
2025             + "      function someLoad(e) {\n"
2026             + "        log(e);\n"
2027             + "      }\n"
2028             + "      function test() {\n"
2029             + "        try {\n"
2030             + "          var request = new XMLHttpRequest();\n"
2031             + "          request.onload = someLoad;\n"
2032             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
2033             + "          request.send('');\n"
2034             + "        } catch(e) { logEx(e); }\n"
2035             + "      }\n"
2036             + "    </script>\n"
2037             + "  </head>\n"
2038             + "  <body onload='test()'>\n"
2039             + "  </body>\n"
2040             + "</html>";
2041 
2042         final String xml = "<abc></abc>";
2043 
2044         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2045         loadPageVerifyTitle2(html);
2046     }
2047 
2048     /**
2049      * @throws Exception if the test fails
2050      */
2051     @Test
2052     @Alerts({"someLoad [object ProgressEvent]", "load", "false", "11", "0"})
2053     public void addEventListener() throws Exception {
2054         final String html = DOCTYPE_HTML
2055             + "<html>\n"
2056             + "  <head>\n"
2057             + "    <script>\n"
2058             + LOG_TITLE_FUNCTION
2059             + "      function someLoad(event) {\n"
2060             + "        log('someLoad ' + event);\n"
2061             + "        log(event.type);\n"
2062             + "        log(event.lengthComputable);\n"
2063             + "        log(event.loaded);\n"
2064             + "        log(event.total);\n"
2065             + "      }\n"
2066             + "      function test() {\n"
2067             + "        try {\n"
2068             + "          var request = new XMLHttpRequest();\n"
2069             + "          request.addEventListener('load', someLoad, false);\n"
2070             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
2071             + "          request.send('');\n"
2072             + "        } catch(e) { logEx(e); }\n"
2073             + "      }\n"
2074             + "    </script>\n"
2075             + "  </head>\n"
2076             + "  <body onload='test()'>\n"
2077             + "  </body>\n"
2078             + "</html>";
2079 
2080         final String xml = "<abc></abc>";
2081 
2082         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2083         loadPageVerifyTitle2(html);
2084     }
2085 
2086     /**
2087      * @throws Exception if the test fails
2088      */
2089     @Test
2090     @Alerts({"someLoad [object ProgressEvent]", "load", "false", "11", "0"})
2091     public void addEventListenerDetails() throws Exception {
2092         final String html = DOCTYPE_HTML
2093             + "<html>\n"
2094             + "  <head>\n"
2095             + "    <script>\n"
2096             + LOG_TITLE_FUNCTION
2097             + "      function someLoad(event) {\n"
2098             + "        log('someLoad ' + event);\n"
2099             + "        log(event.type);\n"
2100             + "        log(event.lengthComputable);\n"
2101             + "        log(event.loaded);\n"
2102             + "        log(event.total);\n"
2103             + "      }\n"
2104             + "      function test() {\n"
2105             + "        try {\n"
2106             + "          var request = new XMLHttpRequest();\n"
2107             + "          request.addEventListener('load', someLoad, false);\n"
2108             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
2109             + "          request.send('');\n"
2110             + "        } catch(e) { logEx(e); }\n"
2111             + "      }\n"
2112             + "    </script>\n"
2113             + "  </head>\n"
2114             + "  <body onload='test()'>\n"
2115             + "  </body>\n"
2116             + "</html>";
2117 
2118         final String xml = "<abc></abc>";
2119 
2120         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2121         loadPageVerifyTitle2(html);
2122     }
2123 
2124     /**
2125      * @throws Exception if the test fails
2126      */
2127     @Test
2128     @Alerts("function")
2129     @HtmlUnitNYI(CHROME = "undefined",
2130             EDGE = "undefined",
2131             FF = "undefined",
2132             FF_ESR = "undefined")
2133     public void addEventListenerCaller() throws Exception {
2134         final String html = DOCTYPE_HTML
2135             + "<html>\n"
2136             + "  <head>\n"
2137             + "    <script>\n"
2138             + LOG_TITLE_FUNCTION
2139             + "      function someLoad(event) {\n"
2140             + "        var caller = arguments.callee.caller;\n"
2141             + "        log(typeof caller == 'function' ? 'function' : caller);\n"
2142             + "      }\n"
2143             + "      function test() {\n"
2144             + "        try {\n"
2145             + "          var request = new XMLHttpRequest();\n"
2146             + "          request.addEventListener('load', someLoad, false);\n"
2147             + "          request.open('GET', '" + URL_SECOND + "', false);\n"
2148             + "          request.send('');\n"
2149             + "        } catch(e) { logEx(e); }\n"
2150             + "      }\n"
2151             + "    </script>\n"
2152             + "  </head>\n"
2153             + "  <body onload='test()'>\n"
2154             + "  </body>\n"
2155             + "</html>";
2156 
2157         final String xml = "<abc></abc>";
2158 
2159         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2160         loadPageVerifyTitle2(html);
2161     }
2162 
2163     /**
2164      * @throws Exception if the test fails
2165      */
2166     @Test
2167     @Alerts("[object XMLHttpRequestUpload]")
2168     public void upload() throws Exception {
2169         final String html = DOCTYPE_HTML
2170             + "<html>\n"
2171             + "  <head>\n"
2172             + "    <script>\n"
2173             + LOG_TITLE_FUNCTION
2174             + "      function test() {\n"
2175             + "        try {\n"
2176             + "          var request = new XMLHttpRequest();\n"
2177             + "          log(request.upload);\n"
2178             + "        } catch(e) { logEx(e); }\n"
2179             + "      }\n"
2180             + "    </script>\n"
2181             + "  </head>\n"
2182             + "  <body onload='test()'>\n"
2183             + "  </body>\n"
2184             + "</html>";
2185 
2186         loadPageVerifyTitle2(html);
2187     }
2188 
2189     /**
2190      * Tests asynchronous use of XMLHttpRequest, using Mozilla style object creation.
2191      * @throws Exception if the test fails
2192      */
2193     @Test
2194     @Alerts({"0", "1", "2", "3", "4"})
2195     public void asyncUse() throws Exception {
2196         final String html = DOCTYPE_HTML
2197             + "<html>\n"
2198             + "  <head>\n"
2199             + "    <script>\n"
2200             + LOG_TITLE_FUNCTION_NORMALIZE
2201             + "      var request;\n"
2202             + "      function testAsync() {\n"
2203             + "        request = new XMLHttpRequest();\n"
2204             + "        request.onreadystatechange = onReadyStateChange;\n"
2205             + "        log(request.readyState);\n"
2206             + "        request.open('GET', '" + URL_SECOND + "', true);\n"
2207             + "        request.send('');\n"
2208             + "      }\n"
2209             + "      function onReadyStateChange() {\n"
2210             + "        log(request.readyState);\n"
2211             + "        if (request.readyState == 4)\n"
2212             + "          log(request.responseText);\n"
2213             + "      }\n"
2214             + "    </script>\n"
2215             + "  </head>\n"
2216             + "  <body onload='testAsync()'>\n"
2217             + "  </body>\n"
2218             + "</html>";
2219 
2220         final String xml =
2221               "<xml2>\n"
2222             + "<content2>sdgxsdgx</content2>\n"
2223             + "<content2>sdgxsdgx2</content2>\n"
2224             + "</xml2>";
2225 
2226         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2227         setExpectedAlerts(ArrayUtils.add(getExpectedAlerts(), xml.replace("\n", "\\n")));
2228         loadPage2(html);
2229         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
2230     }
2231 
2232     /**
2233      * @throws Exception if the test fails
2234      */
2235     @Test
2236     @Alerts(DEFAULT = {"[object Object]", "undefined", "undefined",
2237                        "function() { return !0 }",
2238                        "function set onreadystatechange() { [native code] }",
2239                        "true", "true"},
2240             FF = {"[object Object]", "undefined", "undefined",
2241                   "function() { return !0 }",
2242                   "function onreadystatechange() { [native code] }",
2243                   "true", "true"},
2244             FF_ESR = {"[object Object]", "undefined", "undefined",
2245                       "function() { return !0 }",
2246                       "function onreadystatechange() { [native code] }",
2247                       "true", "true"})
2248     @HtmlUnitNYI(CHROME = {"[object Object]", "undefined", "undefined",
2249                            "function() { return !0 }",
2250                            "function onreadystatechange() { [native code] }",
2251                            "true", "true"},
2252             EDGE = {"[object Object]", "undefined", "undefined",
2253                     "function() { return !0 }",
2254                     "function onreadystatechange() { [native code] }",
2255                     "true", "true"})
2256     public void defineProperty() throws Exception {
2257         final String html = DOCTYPE_HTML
2258             + "<html>\n"
2259             + "  <head>\n"
2260             + "    <script>\n"
2261             + LOG_TITLE_FUNCTION
2262             + "      var request;\n"
2263             + "      function test() {\n"
2264             + "        Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', {\n"
2265             + "                                 enumerable: !0,\n"
2266             + "                                 configurable: !0,\n"
2267             + "                                 get: function() { return !0 }\n"
2268             + "                             });\n"
2269             + "        var desc = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'onreadystatechange');\n"
2270             + "        log(desc);\n"
2271             + "        log(desc.value);\n"
2272             + "        log(desc.writable);\n"
2273             + "        log(desc.get);\n"
2274             + "        log(desc.set);\n"
2275             + "        log(desc.configurable);\n"
2276             + "        log(desc.enumerable);\n"
2277             + "      }\n"
2278             + "    </script>\n"
2279             + "  </head>\n"
2280             + "  <body onload='test()'>\n"
2281             + "  </body>\n"
2282             + "</html>";
2283 
2284         loadPageVerifyTitle2(html);
2285     }
2286 
2287     /**
2288      * Test case for https://stackoverflow.com/questions/44349339/htmlunit-ecmaerror-typeerror.
2289      *
2290      * @throws Exception if the test fails
2291      */
2292     @Test
2293     @Alerts("[object XMLHttpRequest]")
2294     public void defineProperty2() throws Exception {
2295         final String html = DOCTYPE_HTML
2296             + "<html>\n"
2297             + "  <head>\n"
2298             + "    <script>\n"
2299             + LOG_TITLE_FUNCTION
2300             + "      var request;\n"
2301             + "      function test() {\n"
2302             + "        var t = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, 'onreadystatechange');\n"
2303             + "        var res = Object.defineProperty(XMLHttpRequest.prototype, 'onreadystatechange', t);\n"
2304             + "        log(res);\n"
2305             + "      }\n"
2306             + "    </script>\n"
2307             + "  </head>\n"
2308             + "  <body onload='test()'>\n"
2309             + "  </body>\n"
2310             + "</html>";
2311 
2312         loadPageVerifyTitle2(html);
2313     }
2314 
2315     /**
2316      * @throws Exception if the test fails
2317      */
2318     @Test
2319     @Alerts("application/json")
2320     public void enctypeBlob() throws Exception {
2321         final String html = DOCTYPE_HTML
2322             + "<html>\n"
2323             + "<head>\n"
2324             + "<script>\n"
2325             + LOG_TITLE_FUNCTION
2326             + "function doTest() {\n"
2327             + "  try {\n"
2328             + "    var debug = {hello: 'world'};\n"
2329             + "    var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});\n"
2330 
2331             + "    var xhr = new XMLHttpRequest();\n"
2332             + "    xhr.open('post', '/test2', false);\n"
2333             + "    xhr.send(blob);\n"
2334             + "    log('done');\n"
2335             + "  } catch(e) { logEx(e); }\n"
2336             + "}\n"
2337             + "</script>\n"
2338             + "</head>\n"
2339             + "<body onload='doTest()'>\n"
2340             + "</body>\n"
2341             + "</html>";
2342 
2343         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2344 
2345         final WebDriver driver = loadPage2(html);
2346         verifyTitle2(driver, new String[] {"done"});
2347 
2348         String headerValue = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2349             .get(HttpHeader.CONTENT_TYPE);
2350         // Can't test equality for multipart/form-data as it will have the form:
2351         // multipart/form-data; boundary=---------------------------42937861433140731107235900
2352         headerValue = StringUtils.substringBefore(headerValue, ";");
2353         assertEquals(getExpectedAlerts()[0], "" + headerValue);
2354     }
2355 
2356     /**
2357      * @throws Exception if the test fails
2358      */
2359     @Test
2360     @Alerts("null")
2361     @HtmlUnitNYI(CHROME = "text/plain",
2362             EDGE = "text/plain",
2363             FF = "text/plain",
2364             FF_ESR = "text/plain")
2365     public void enctypeBufferSource() throws Exception {
2366         final String html = DOCTYPE_HTML
2367             + "<html>\n"
2368             + "<head>\n"
2369             + "<script>\n"
2370             + LOG_TITLE_FUNCTION
2371             + "function doTest() {\n"
2372             + "  try {\n"
2373             + "    var typedArray = new Int8Array(8);\n"
2374             + "    var xhr = new XMLHttpRequest();\n"
2375             + "    xhr.open('post', '/test2', false);\n"
2376             + "    xhr.send(typedArray);\n"
2377             + "    log('done');\n"
2378             + "  } catch(e) { logEx(e); }\n"
2379             + "}\n"
2380             + "</script>\n"
2381             + "</head>\n"
2382             + "<body onload='doTest()'>\n"
2383             + "</body>\n"
2384             + "</html>";
2385 
2386         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2387 
2388         final WebDriver driver = loadPage2(html);
2389         verifyTitle2(driver, new String[] {"done"});
2390 
2391         String headerValue = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2392             .get(HttpHeader.CONTENT_TYPE);
2393         // Can't test equality for multipart/form-data as it will have the form:
2394         // multipart/form-data; boundary=---------------------------42937861433140731107235900
2395         headerValue = StringUtils.substringBefore(headerValue, ";");
2396         assertEquals(getExpectedAlerts()[0], "" + headerValue);
2397     }
2398 
2399     /**
2400      * @throws Exception if the test fails
2401      */
2402     @Test
2403     @Alerts({"q=HtmlUnit&u=%D0%BB%C6%89", "done", "application/x-www-form-urlencoded;charset=UTF-8",
2404              "q=HtmlUnit", "u=\u043B\u0189"})
2405     public void enctypeURLSearchParams() throws Exception {
2406         final String html = DOCTYPE_HTML
2407             + "<html>\n"
2408             + "<head>\n"
2409             + "<script>\n"
2410             + LOG_TITLE_FUNCTION
2411             + "function doTest() {\n"
2412             + "  var searchParams = '1234';\n"
2413             + "  try {\n"
2414             + "    searchParams = new URLSearchParams();\n"
2415             + "    searchParams.append('q', 'HtmlUnit');\n"
2416             + "    searchParams.append('u', '\u043B\u0189');\n"
2417             + "    log(searchParams);\n"
2418             + "  } catch(e) { logEx(e); }\n"
2419 
2420             + "  try {\n"
2421             + "    var xhr = new XMLHttpRequest();\n"
2422             + "    xhr.open('post', '/test2', false);\n"
2423             + "    xhr.send(searchParams);\n"
2424             + "    log('done');\n"
2425             + "  } catch(e) { logEx(e); }\n"
2426             + "}\n"
2427             + "</script>\n"
2428             + "</head>\n"
2429             + "<body onload='doTest()'>\n"
2430             + "</body>\n"
2431             + "</html>";
2432 
2433         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2434 
2435         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=UTF-8", UTF_8, null);
2436         verifyTitle2(driver, new String[] {getExpectedAlerts()[0], getExpectedAlerts()[1]});
2437 
2438         String headerContentType = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2439             .get(HttpHeader.CONTENT_TYPE);
2440         headerContentType = headerContentType.replace("; ", ";"); // normalize
2441         assertEquals(getExpectedAlerts()[2], headerContentType);
2442         if (getExpectedAlerts().length > 3) {
2443             assertEquals(getExpectedAlerts()[3], getMockWebConnection().getLastWebRequest()
2444                                 .getRequestParameters().get(0).toString());
2445             assertEquals(getExpectedAlerts()[4], getMockWebConnection().getLastWebRequest()
2446                     .getRequestParameters().get(1).toString());
2447             assertEquals(null, getMockWebConnection().getLastWebRequest().getRequestBody());
2448         }
2449     }
2450 
2451     /**
2452      * @throws Exception if the test fails
2453      */
2454     @Test
2455     @Alerts("multipart/form-data")
2456     public void enctypeFormData() throws Exception {
2457         final String html = DOCTYPE_HTML
2458             + "<html>\n"
2459             + "<head>\n"
2460             + "<script>\n"
2461             + LOG_TITLE_FUNCTION
2462             + "function doTest() {\n"
2463             + "  try {\n"
2464             + "    var formData = new FormData(document.testForm);\n"
2465             + "    var xhr = new XMLHttpRequest();\n"
2466             + "    xhr.open('post', '/test2', false);\n"
2467             + "    xhr.send(formData);\n"
2468             + "    log('done');\n"
2469             + "  } catch(e) { logEx(e); }\n"
2470             + "}\n"
2471             + "</script>\n"
2472             + "</head>\n"
2473             + "<body onload='doTest()'>\n"
2474             + "  <form name='testForm'>\n"
2475             + "    <input type='text' id='myText' name='myText' value='textxy'>\n"
2476             + "  </form>\n"
2477             + "</body>\n"
2478             + "</html>";
2479 
2480         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2481 
2482         final WebDriver driver = loadPage2(html);
2483         verifyTitle2(driver, new String[] {"done"});
2484 
2485         String headerValue = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2486             .get(HttpHeader.CONTENT_TYPE);
2487         // Can't test equality for multipart/form-data as it will have the form:
2488         // multipart/form-data; boundary=---------------------------42937861433140731107235900
2489         headerValue = StringUtils.substringBefore(headerValue, ";");
2490         assertEquals(getExpectedAlerts()[0], headerValue);
2491     }
2492 
2493     /**
2494      * @throws Exception if the test fails
2495      */
2496     @Test
2497     @Alerts({"text/plain;charset=UTF-8", "HtmlUnit \u043B\u0189"})
2498     public void enctypeString() throws Exception {
2499         final String html = DOCTYPE_HTML
2500             + "<html>\n"
2501             + "<head>\n"
2502             + "<script>\n"
2503             + LOG_TITLE_FUNCTION
2504             + "function doTest() {\n"
2505             + "  try {\n"
2506             + "    var xhr = new XMLHttpRequest();\n"
2507             + "    xhr.open('post', '/test2', false);\n"
2508             + "    xhr.send('HtmlUnit \u043B\u0189');\n"
2509             + "    log('done');\n"
2510             + "  } catch(e) { logEx(e); }\n"
2511             + "}\n"
2512             + "</script>\n"
2513             + "</head>\n"
2514             + "<body onload='doTest()'>\n"
2515             + "</body>\n"
2516             + "</html>";
2517 
2518         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2519 
2520         // use utf8 here to be able to send all chars
2521         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=UTF-8", UTF_8, null);
2522         verifyTitle2(driver, new String[] {"done"});
2523 
2524         String headerContentType = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2525             .get(HttpHeader.CONTENT_TYPE);
2526         headerContentType = headerContentType.replace("; ", ";"); // normalize
2527         assertEquals(getExpectedAlerts()[0], headerContentType);
2528         assertEquals(getExpectedAlerts()[1], getMockWebConnection().getLastWebRequest().getRequestBody());
2529     }
2530 
2531     /**
2532      * @throws Exception if the test fails
2533      */
2534     @Test
2535     @Alerts({"text/jpeg", "HtmlUnit \u00D0\u00BB\u00C6\u0089"})
2536     public void enctypeUserDefined() throws Exception {
2537         final String html = DOCTYPE_HTML
2538             + "<html>\n"
2539             + "<head>\n"
2540             + "<script>\n"
2541             + LOG_TITLE_FUNCTION
2542             + "function doTest() {\n"
2543             + "  try {\n"
2544             + "    var xhr = new XMLHttpRequest();\n"
2545             + "    xhr.open('post', '/test2', false);\n"
2546             + "    xhr.setRequestHeader('Content-Type', 'text/jpeg');\n"
2547             + "    xhr.send('HtmlUnit \u043B\u0189');\n"
2548             + "    log('done');\n"
2549             + "  } catch(e) { logEx(e); }\n"
2550             + "}\n"
2551             + "</script>\n"
2552             + "</head>\n"
2553             + "<body onload='doTest()'>\n"
2554             + "</body>\n"
2555             + "</html>";
2556 
2557         getMockWebConnection().setDefaultResponse("<html><title>Response</title></html>");
2558 
2559         final WebDriver driver = loadPage2(html, URL_FIRST, "text/html;charset=UTF-8", UTF_8, null);
2560         verifyTitle2(driver, new String[] {"done"});
2561 
2562         String headerContentType = getMockWebConnection().getLastWebRequest().getAdditionalHeaders()
2563                 .get(HttpHeader.CONTENT_TYPE);
2564         headerContentType = headerContentType.replace("; ", ";"); // normalize
2565         assertEquals(getExpectedAlerts()[0], headerContentType);
2566         assertEquals(getExpectedAlerts()[1], getMockWebConnection().getLastWebRequest().getRequestBody());
2567     }
2568 
2569     /**
2570      * @throws Exception if the test fails
2571      */
2572     @Test
2573     @Alerts("InvalidStateError/DOMException")
2574     public void setRequestHeaderNotOpend() throws Exception {
2575         final String html = DOCTYPE_HTML
2576             + "<html>\n"
2577             + "<head>\n"
2578             + "<script>\n"
2579             + LOG_TITLE_FUNCTION
2580             + "function doTest() {\n"
2581             + "  try {\n"
2582             + "    var xhr = new XMLHttpRequest();\n"
2583             + "    xhr.setRequestHeader('Content-Type', 'text/jpeg');\n"
2584             + "    log('done');\n"
2585             + "  } catch(e) { logEx(e); }\n"
2586             + "}\n"
2587             + "</script>\n"
2588             + "</head>\n"
2589             + "<body onload='doTest()'>\n"
2590             + "</body>\n"
2591             + "</html>";
2592 
2593         loadPageVerifyTitle2(html);
2594     }
2595 
2596     /**
2597      * @throws Exception if the test fails.
2598      */
2599     @Test
2600     @Alerts("undefined")
2601     public void getOwnPropertyDescriptor_onabort() throws Exception {
2602         getOwnPropertyDescriptor("onabort");
2603     }
2604 
2605     /**
2606      * @throws Exception if the test fails.
2607      */
2608     @Test
2609     @Alerts("undefined")
2610     public void getOwnPropertyDescriptor_onerror() throws Exception {
2611         getOwnPropertyDescriptor("onerror");
2612     }
2613 
2614     /**
2615      * @throws Exception if the test fails.
2616      */
2617     @Test
2618     @Alerts("undefined")
2619     public void getOwnPropertyDescriptor_onload() throws Exception {
2620         getOwnPropertyDescriptor("onload");
2621     }
2622 
2623     /**
2624      * @throws Exception if the test fails.
2625      */
2626     @Test
2627     @Alerts("undefined")
2628     public void getOwnPropertyDescriptor_onloadstart() throws Exception {
2629         getOwnPropertyDescriptor("onloadstart");
2630     }
2631 
2632     /**
2633      * @throws Exception if the test fails.
2634      */
2635     @Test
2636     @Alerts("undefined")
2637     public void getOwnPropertyDescriptor_onloadend() throws Exception {
2638         getOwnPropertyDescriptor("onloadend");
2639     }
2640 
2641     /**
2642      * @throws Exception if the test fails.
2643      */
2644     @Test
2645     @Alerts("undefined")
2646     public void getOwnPropertyDescriptor_onprogress() throws Exception {
2647         getOwnPropertyDescriptor("onprogress");
2648     }
2649 
2650     /**
2651      * @throws Exception if the test fails.
2652      */
2653     @Test
2654     @Alerts(DEFAULT = {"[object Object]", "undefined", "undefined",
2655                        "function get onreadystatechange() { [native code] }",
2656                        "function set onreadystatechange() { [native code] }",
2657                        "true", "true"},
2658             FF = {"[object Object]", "undefined", "undefined",
2659                   "function onreadystatechange() { [native code] }",
2660                   "function onreadystatechange() { [native code] }",
2661                   "true", "true"},
2662             FF_ESR = {"[object Object]", "undefined", "undefined",
2663                       "function onreadystatechange() { [native code] }",
2664                       "function onreadystatechange() { [native code] }",
2665                       "true", "true"})
2666     @HtmlUnitNYI(CHROME = {"[object Object]", "undefined", "undefined",
2667                            "function onreadystatechange() { [native code] }",
2668                            "function onreadystatechange() { [native code] }",
2669                            "true", "true"},
2670             EDGE = {"[object Object]", "undefined", "undefined",
2671                     "function onreadystatechange() { [native code] }",
2672                     "function onreadystatechange() { [native code] }",
2673                     "true", "true"})
2674     public void getOwnPropertyDescriptor_onreadystatechange() throws Exception {
2675         getOwnPropertyDescriptor("onreadystatechange");
2676     }
2677 
2678     /**
2679      * @throws Exception if the test fails.
2680      */
2681     @Test
2682     @Alerts("undefined")
2683     public void getOwnPropertyDescriptor_ontimeout() throws Exception {
2684         getOwnPropertyDescriptor("ontimeout");
2685     }
2686 
2687     private void getOwnPropertyDescriptor(final String event) throws Exception {
2688         final String html = DOCTYPE_HTML
2689             + "<html>\n"
2690             + "  <head>\n"
2691             + "    <script>\n"
2692             + LOG_TITLE_FUNCTION
2693             + "      var request;\n"
2694             + "      function test() {\n"
2695             + "        var desc = Object.getOwnPropertyDescriptor("
2696                                 + "XMLHttpRequest.prototype, '" + event + "');\n"
2697             + "        log(desc);\n"
2698             + "        if(!desc) { return; }\n"
2699 
2700             + "        log(desc.value);\n"
2701             + "        log(desc.writable);\n"
2702             + "        log(desc.get);\n"
2703             + "        log(desc.set);\n"
2704             + "        log(desc.configurable);\n"
2705             + "        log(desc.enumerable);\n"
2706             + "      }\n"
2707             + "    </script>\n"
2708             + "  </head>\n"
2709             + "  <body onload='test()'>\n"
2710             + "  </body>\n"
2711             + "</html>";
2712 
2713         loadPageVerifyTitle2(html);
2714     }
2715 
2716     /**
2717      * @throws Exception if the test fails
2718      */
2719     @Test
2720     @Alerts({"", "arraybuffer", "blob", "json", "text", "text", "text", "text", "text", ""})
2721     public void responseTypeSetBeforeOpen() throws Exception {
2722         final String html = DOCTYPE_HTML
2723             + "<html>\n"
2724             + "  <head>\n"
2725             + "    <script>\n"
2726             + LOG_TITLE_FUNCTION
2727             + "      function testSync() {\n"
2728             + "        var request = new XMLHttpRequest();\n"
2729             + "        log(request.responseType);\n"
2730             + "      try {\n"
2731             + "        request.responseType = 'arraybuffer';\n"
2732             + "        log(request.responseType);\n"
2733             + "        request.responseType = 'blob';\n"
2734             + "        log(request.responseType);\n"
2735             + "        request.responseType = 'json';\n"
2736             + "        log(request.responseType);\n"
2737             + "        request.responseType = 'text';\n"
2738             + "        log(request.responseType);\n"
2739             + "      } catch(e) { logEx(e); }\n"
2740 
2741             + "      try {\n"
2742             + "        request.responseType = 'JsON';\n"
2743             + "        log(request.responseType);\n"
2744 
2745             + "        request.responseType = 'unknown';\n"
2746             + "        log(request.responseType);\n"
2747             + "      } catch(e) { logEx(e); }\n"
2748 
2749             + "      try {\n"
2750             + "        request.responseType = null;\n"
2751             + "        log(request.responseType);\n"
2752             + "      } catch(e) { logEx(e); }\n"
2753 
2754             + "      try {\n"
2755             + "        request.responseType = undefined;\n"
2756             + "        log(request.responseType);\n"
2757             + "      } catch(e) { logEx(e); }\n"
2758 
2759             + "      try {\n"
2760             + "        request.responseType = '';\n"
2761             + "        log(request.responseType);\n"
2762             + "      } catch(e) { logEx(e); }\n"
2763             + "      }\n"
2764             + "    </script>\n"
2765             + "  </head>\n"
2766             + "  <body onload='testSync()'>\n"
2767             + "  </body>\n"
2768             + "</html>";
2769 
2770         loadPageVerifyTitle2(html);
2771     }
2772 
2773     /**
2774      * @throws Exception if the test fails
2775      */
2776     @Test
2777     @Alerts({"", "InvalidAccessError/DOMException", "InvalidAccessError/DOMException",
2778              "InvalidAccessError/DOMException", "InvalidAccessError/DOMException",
2779              "InvalidAccessError/DOMException", "", "", "", "", "InvalidAccessError/DOMException"})
2780     public void responseTypeSetAfterOpenSync() throws Exception {
2781         final String html = DOCTYPE_HTML
2782             + "<html>\n"
2783             + "  <head>\n"
2784             + "    <script>\n"
2785             + LOG_TITLE_FUNCTION
2786             + "      function testSync() {\n"
2787             + "        var request = new XMLHttpRequest();\n"
2788             + "        request.open('GET', '" + URL_SECOND + "', false);\n"
2789 
2790             + "        log(request.responseType);\n"
2791 
2792             + "      try {\n"
2793             + "        request.responseType = 'arraybuffer';\n"
2794             + "        log(request.responseType);\n"
2795             + "      } catch(e) { logEx(e); }\n"
2796 
2797             + "      try {\n"
2798             + "        request.responseType = 'blob';\n"
2799             + "        log(request.responseType);\n"
2800             + "      } catch(e) { logEx(e); }\n"
2801 
2802             + "      try {\n"
2803             + "        request.responseType = 'json';\n"
2804             + "        log(request.responseType);\n"
2805             + "      } catch(e) { logEx(e); }\n"
2806 
2807             + "      try {\n"
2808             + "        request.responseType = 'text';\n"
2809             + "        log(request.responseType);\n"
2810             + "      } catch(e) { logEx(e); }\n"
2811 
2812             + "      try {\n"
2813             + "        request.responseType = 'document';\n"
2814             + "        log(request.responseType);\n"
2815             + "      } catch(e) { logEx(e); }\n"
2816 
2817             + "      try {\n"
2818             + "        request.responseType = 'JsON';\n"
2819             + "        log(request.responseType);\n"
2820             + "      } catch(e) { logEx(e); }\n"
2821 
2822             + "      try {\n"
2823             + "        request.responseType = 'unknown';\n"
2824             + "        log(request.responseType);\n"
2825             + "      } catch(e) { logEx(e); }\n"
2826 
2827             + "      try {\n"
2828             + "        request.responseType = null;\n"
2829             + "        log(request.responseType);\n"
2830             + "      } catch(e) { logEx(e); }\n"
2831 
2832             + "      try {\n"
2833             + "        request.responseType = undefined;\n"
2834             + "        log(request.responseType);\n"
2835             + "      } catch(e) { logEx(e); }\n"
2836 
2837             + "      try {\n"
2838             + "        request.responseType = '';\n"
2839             + "        log(request.responseType);\n"
2840             + "      } catch(e) { logEx(e); }\n"
2841             + "      }\n"
2842             + "    </script>\n"
2843             + "  </head>\n"
2844             + "  <body onload='testSync()'>\n"
2845             + "  </body>\n"
2846             + "</html>";
2847 
2848         loadPageVerifyTitle2(html);
2849     }
2850 
2851     /**
2852      * @throws Exception if the test fails
2853      */
2854     @Test
2855     @Alerts({"", "arraybuffer", "blob", "json", "text", "document",
2856              "document", "document", "document", "document", ""})
2857     public void responseTypeSetAfterOpenAsync() throws Exception {
2858         final String html = DOCTYPE_HTML
2859             + "<html>\n"
2860             + "  <head>\n"
2861             + "    <script>\n"
2862             + LOG_TITLE_FUNCTION
2863             + "      function testSync() {\n"
2864             + "        var request = new XMLHttpRequest();\n"
2865             + "        request.open('GET', '" + URL_SECOND + "', true);\n"
2866 
2867             + "        log(request.responseType);\n"
2868             + "      try {\n"
2869             + "        request.responseType = 'arraybuffer';\n"
2870             + "        log(request.responseType);\n"
2871             + "      } catch(e) { logEx(e); }\n"
2872 
2873             + "      try {\n"
2874             + "        request.responseType = 'blob';\n"
2875             + "        log(request.responseType);\n"
2876             + "      } catch(e) { logEx(e); }\n"
2877 
2878             + "      try {\n"
2879             + "        request.responseType = 'json';\n"
2880             + "        log(request.responseType);\n"
2881             + "      } catch(e) { logEx(e); }\n"
2882 
2883             + "      try {\n"
2884             + "        request.responseType = 'text';\n"
2885             + "        log(request.responseType);\n"
2886             + "      } catch(e) { logEx(e); }\n"
2887 
2888             + "      try {\n"
2889             + "        request.responseType = 'document';\n"
2890             + "        log(request.responseType);\n"
2891             + "      } catch(e) { logEx(e); }\n"
2892 
2893             + "      try {\n"
2894             + "        request.responseType = 'JsON';\n"
2895             + "        log(request.responseType);\n"
2896             + "      } catch(e) { logEx(e); }\n"
2897 
2898             + "      try {\n"
2899             + "        request.responseType = 'unknown';\n"
2900             + "        log(request.responseType);\n"
2901             + "      } catch(e) { logEx(e); }\n"
2902 
2903             + "      try {\n"
2904             + "        request.responseType = null;\n"
2905             + "        log(request.responseType);\n"
2906             + "      } catch(e) { logEx(e); }\n"
2907 
2908             + "      try {\n"
2909             + "        request.responseType = undefined;\n"
2910             + "        log(request.responseType);\n"
2911             + "      } catch(e) { logEx(e); }\n"
2912 
2913             + "      try {\n"
2914             + "        request.responseType = '';\n"
2915             + "        log(request.responseType);\n"
2916             + "      } catch(e) { logEx(e); }\n"
2917             + "      }\n"
2918             + "    </script>\n"
2919             + "  </head>\n"
2920             + "  <body onload='testSync()'>\n"
2921             + "  </body>\n"
2922             + "</html>";
2923 
2924         loadPageVerifyTitle2(html);
2925     }
2926 
2927     /**
2928      * @throws Exception if the test fails
2929      */
2930     @Test
2931     @Alerts(DEFAULT = {"", "", "arraybuffer", "InvalidStateError/DOMException",
2932                        "send done", "InvalidStateError/DOMException"},
2933             FF = {"", "", "arraybuffer", "", "send done", "InvalidStateError/DOMException"},
2934             FF_ESR = {"", "", "arraybuffer", "", "send done", "InvalidStateError/DOMException"})
2935     public void responseTextInvalidResponseType() throws Exception {
2936         final String html = DOCTYPE_HTML
2937             + "<html>\n"
2938             + "  <head>\n"
2939             + "    <script>\n"
2940             + LOG_TITLE_FUNCTION
2941             + "      var xhr;\n"
2942             + "      function test() {\n"
2943             + "        xhr = new XMLHttpRequest();\n"
2944             + "        log(xhr.responseText);\n"
2945 
2946             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
2947             + "        log(xhr.responseText);\n"
2948 
2949             + "        try {\n"
2950             + "          xhr.responseType = 'arraybuffer';\n"
2951             + "        } catch(e) { logEx(e); }\n"
2952             + "        log(xhr.responseType);\n"
2953 
2954             + "        try {\n"
2955             + "          log(xhr.responseText);\n"
2956             + "        } catch(e) { logEx(e); }\n"
2957 
2958             + "        try {\n"
2959             + "          xhr.onreadystatechange = onStateChange;\n"
2960             + "        } catch(e) { logEx(e); }\n"
2961 
2962             + "        try {\n"
2963             + "          xhr.send('');\n"
2964             + "          log('send done');\n"
2965             + "        } catch(e) { logEx(e); }\n"
2966             + "      }\n"
2967 
2968             + "      function onStateChange(e) {\n"
2969             + "        if (xhr.readyState == 4) {\n"
2970             + "          try {\n"
2971             + "            log(xhr.responseText);\n"
2972             + "          } catch(e) { logEx(e); }\n"
2973             + "        }\n"
2974             + "      }\n"
2975             + "    </script>\n"
2976             + "  </head>\n"
2977             + "  <body onload='test()'>\n"
2978             + "  </body>\n"
2979             + "</html>";
2980 
2981         final String xml =
2982               "<xml>\n"
2983             + "<content>blah</content>\n"
2984             + "</xml>";
2985 
2986         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
2987         loadPage2(html);
2988         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
2989     }
2990 
2991     /**
2992      * @throws Exception if the test fails
2993      */
2994     @Test
2995     @Alerts({"", "", "<xml>\\n<content>blah</content>\\n</xml>"})
2996     public void responseResponseTypeDefault() throws Exception {
2997         final String html = DOCTYPE_HTML
2998             + "<html>\n"
2999             + "  <head>\n"
3000             + "    <script>\n"
3001             + LOG_TITLE_FUNCTION_NORMALIZE
3002             + "      var xhr;\n"
3003             + "      function test() {\n"
3004             + "        xhr = new XMLHttpRequest();\n"
3005             + "        log(xhr.responseText);\n"
3006 
3007             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3008             + "        log(xhr.responseType);\n"
3009 
3010             + "        xhr.onreadystatechange = onStateChange;\n"
3011             + "        xhr.send('');\n"
3012             + "      }\n"
3013 
3014             + "      function onStateChange(e) {\n"
3015             + "        if (xhr.readyState == 4) {\n"
3016             + "          try {\n"
3017             + "            log(xhr.response);\n"
3018             + "          } catch(ex) { logEx(e); }\n"
3019             + "        }\n"
3020             + "      }\n"
3021             + "    </script>\n"
3022             + "  </head>\n"
3023             + "  <body onload='test()'>\n"
3024             + "  </body>\n"
3025             + "</html>";
3026 
3027         final String xml =
3028               "<xml>\n"
3029             + "<content>blah</content>\n"
3030             + "</xml>";
3031 
3032         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3033         loadPage2(html);
3034         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3035     }
3036 
3037     /**
3038      * @throws Exception if the test fails
3039      */
3040     @Test
3041     @Alerts({"", "text", "<xml>\\n<content>blah</content>\\n</xml>"})
3042     public void responseResponseTypeText() throws Exception {
3043         final String html = DOCTYPE_HTML
3044             + "<html>\n"
3045             + "  <head>\n"
3046             + "    <script>\n"
3047             + LOG_TITLE_FUNCTION_NORMALIZE
3048             + "      var xhr;\n"
3049             + "      function test() {\n"
3050             + "        xhr = new XMLHttpRequest();\n"
3051             + "        log(xhr.responseText);\n"
3052 
3053             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3054             + "        xhr.responseType = 'text';\n"
3055             + "        log(xhr.responseType);\n"
3056 
3057             + "        xhr.onreadystatechange = onStateChange;\n"
3058             + "        xhr.send('');\n"
3059             + "      }\n"
3060 
3061             + "      function onStateChange(e) {\n"
3062             + "        if (xhr.readyState == 4) {\n"
3063             + "          try {\n"
3064             + "            log(xhr.response);\n"
3065             + "          } catch(ex) { logEx(e); }\n"
3066             + "        }\n"
3067             + "      }\n"
3068             + "    </script>\n"
3069             + "  </head>\n"
3070             + "  <body onload='test()'>\n"
3071             + "  </body>\n"
3072             + "</html>";
3073 
3074         final String xml =
3075               "<xml>\n"
3076             + "<content>blah</content>\n"
3077             + "</xml>";
3078 
3079         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3080         loadPage2(html);
3081         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3082     }
3083 
3084     /**
3085      * @throws Exception if the test fails
3086      */
3087     @Test
3088     @Alerts({"", "arraybuffer", "[object ArrayBuffer]", "36"})
3089     public void responseResponseTypeArrayBuffer() throws Exception {
3090         final String html = DOCTYPE_HTML
3091             + "<html>\n"
3092             + "  <head>\n"
3093             + "    <script>\n"
3094             + LOG_TITLE_FUNCTION
3095             + "      var xhr;\n"
3096             + "      function test() {\n"
3097             + "        xhr = new XMLHttpRequest();\n"
3098             + "        log(xhr.responseText);\n"
3099 
3100             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3101             + "        xhr.responseType = 'arraybuffer';\n"
3102             + "        log(xhr.responseType);\n"
3103 
3104             + "        xhr.onreadystatechange = onStateChange;\n"
3105             + "        xhr.send('');\n"
3106             + "      }\n"
3107 
3108             + "      function onStateChange(e) {\n"
3109             + "        if (xhr.readyState == 4) {\n"
3110             + "          try {\n"
3111             + "            log(xhr.response);\n"
3112             + "            log(xhr.response.byteLength);\n"
3113             + "          } catch(ex) { logEx(e); }\n"
3114             + "        }\n"
3115             + "      }\n"
3116             + "    </script>\n"
3117             + "  </head>\n"
3118             + "  <body onload='test()'>\n"
3119             + "  </body>\n"
3120             + "</html>";
3121 
3122         final String xml =
3123               "<xml>\n"
3124             + "<content>blah</content>\n"
3125             + "</xml>";
3126 
3127         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3128         loadPage2(html);
3129         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3130     }
3131 
3132     /**
3133      * @throws Exception if the test fails
3134      */
3135     @Test
3136     @Alerts({"", "arraybuffer", "[object ArrayBuffer]", "36"})
3137     public void responseResponseTypeArrayBufferGzipIncrease() throws Exception {
3138         final String html = DOCTYPE_HTML
3139             + "<html>\n"
3140             + "  <head>\n"
3141             + "    <script>\n"
3142             + LOG_TITLE_FUNCTION
3143             + "      var xhr;\n"
3144             + "      function test() {\n"
3145             + "        xhr = new XMLHttpRequest();\n"
3146             + "        log(xhr.responseText);\n"
3147 
3148             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3149             + "        xhr.responseType = 'arraybuffer';\n"
3150             + "        log(xhr.responseType);\n"
3151 
3152             + "        xhr.onreadystatechange = onStateChange;\n"
3153             + "        xhr.send('');\n"
3154             + "      }\n"
3155 
3156             + "      function onStateChange(e) {\n"
3157             + "        if (xhr.readyState == 4) {\n"
3158             + "          try {\n"
3159             + "            log(xhr.response);\n"
3160             + "            log(xhr.response.byteLength);\n"
3161             + "          } catch(ex) { logEx(e); }\n"
3162             + "        }\n"
3163             + "      }\n"
3164             + "    </script>\n"
3165             + "  </head>\n"
3166             + "  <body onload='test()'>\n"
3167             + "  </body>\n"
3168             + "</html>";
3169 
3170         final String xml =
3171               "<xml>\n"
3172             + "<content>blah</content>\n"
3173             + "</xml>";
3174 
3175         final byte[] bytes = xml.getBytes(UTF_8);
3176         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
3177         final GZIPOutputStream gout = new GZIPOutputStream(bos);
3178         gout.write(bytes);
3179         gout.finish();
3180 
3181         final byte[] encoded = bos.toByteArray();
3182         assertTrue(encoded.length > xml.length());
3183 
3184         final List<NameValuePair> headers = new LinkedList<>();
3185         headers.add(new NameValuePair("Content-Encoding", "gzip"));
3186         getMockWebConnection().setResponse(URL_SECOND, encoded, 200, "OK", MimeType.TEXT_XML, headers);
3187         loadPage2(html);
3188         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3189     }
3190 
3191     /**
3192      * @throws Exception if the test fails
3193      */
3194     @Test
3195     @Alerts({"", "arraybuffer", "[object ArrayBuffer]", "72"})
3196     public void responseResponseTypeArrayBufferGzipDecrease() throws Exception {
3197         final String html = DOCTYPE_HTML
3198             + "<html>\n"
3199             + "  <head>\n"
3200             + "    <script>\n"
3201             + LOG_TITLE_FUNCTION
3202             + "      var xhr;\n"
3203             + "      function test() {\n"
3204             + "        xhr = new XMLHttpRequest();\n"
3205             + "        log(xhr.responseText);\n"
3206 
3207             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3208             + "        xhr.responseType = 'arraybuffer';\n"
3209             + "        log(xhr.responseType);\n"
3210 
3211             + "        xhr.onreadystatechange = onStateChange;\n"
3212             + "        xhr.send('');\n"
3213             + "      }\n"
3214 
3215             + "      function onStateChange(e) {\n"
3216             + "        if (xhr.readyState == 4) {\n"
3217             + "          try {\n"
3218             + "            log(xhr.response);\n"
3219             + "            log(xhr.response.byteLength);\n"
3220             + "          } catch(ex) { logEx(e); }\n"
3221             + "        }\n"
3222             + "      }\n"
3223             + "    </script>\n"
3224             + "  </head>\n"
3225             + "  <body onload='test()'>\n"
3226             + "  </body>\n"
3227             + "</html>";
3228 
3229         final String xml =
3230               "<xml>\n"
3231             + "<content>blahblahblahblahblahblahblahblahblahblah</content>\n"
3232             + "</xml>";
3233 
3234         final byte[] bytes = xml.getBytes(UTF_8);
3235         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
3236         final GZIPOutputStream gout = new GZIPOutputStream(bos);
3237         gout.write(bytes);
3238         gout.finish();
3239 
3240         final byte[] encoded = bos.toByteArray();
3241         assertTrue(encoded.length < xml.length());
3242 
3243         final List<NameValuePair> headers = new LinkedList<>();
3244         headers.add(new NameValuePair("Content-Encoding", "gzip"));
3245         getMockWebConnection().setResponse(URL_SECOND, encoded, 200, "OK", MimeType.TEXT_XML, headers);
3246         loadPage2(html);
3247         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3248     }
3249 
3250     /**
3251      * @throws Exception if the test fails
3252      */
3253     @Test
3254     @Alerts({"", "arraybuffer", "[object ArrayBuffer]", "0"})
3255     public void responseResponseTypeArrayBufferEmpty() throws Exception {
3256         final String html = DOCTYPE_HTML
3257             + "<html>\n"
3258             + "  <head>\n"
3259             + "    <script>\n"
3260             + LOG_TITLE_FUNCTION
3261             + "      var xhr;\n"
3262             + "      function test() {\n"
3263             + "        xhr = new XMLHttpRequest();\n"
3264             + "        log(xhr.responseText);\n"
3265 
3266             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3267             + "        xhr.responseType = 'arraybuffer';\n"
3268             + "        log(xhr.responseType);\n"
3269 
3270             + "        xhr.onreadystatechange = onStateChange;\n"
3271             + "        xhr.send('');\n"
3272             + "      }\n"
3273 
3274             + "      function onStateChange(e) {\n"
3275             + "        if (xhr.readyState == 4) {\n"
3276             + "          try {\n"
3277             + "            log(xhr.response);\n"
3278             + "            log(xhr.response.byteLength);\n"
3279             + "          } catch(ex) { logEx(e); }\n"
3280             + "        }\n"
3281             + "      }\n"
3282             + "    </script>\n"
3283             + "  </head>\n"
3284             + "  <body onload='test()'>\n"
3285             + "  </body>\n"
3286             + "</html>";
3287 
3288         final String xml = "";
3289 
3290         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3291         loadPage2(html);
3292         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3293     }
3294 
3295     /**
3296      * @throws Exception if the test fails
3297      */
3298     @Test
3299     @Alerts({"", "blob", "[object Blob]", "36", "text/xml"})
3300     public void responseResponseTypeBlob() throws Exception {
3301         final String html = DOCTYPE_HTML
3302             + "<html>\n"
3303             + "  <head>\n"
3304             + "    <script>\n"
3305             + LOG_TITLE_FUNCTION
3306             + "      var xhr;\n"
3307             + "      function test() {\n"
3308             + "        xhr = new XMLHttpRequest();\n"
3309             + "        log(xhr.responseText);\n"
3310 
3311             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3312             + "        xhr.responseType = 'blob';\n"
3313             + "        log(xhr.responseType);\n"
3314 
3315             + "        xhr.onreadystatechange = onStateChange;\n"
3316             + "        xhr.send('');\n"
3317             + "      }\n"
3318 
3319             + "      function onStateChange(e) {\n"
3320             + "        if (xhr.readyState == 4) {\n"
3321             + "          try {\n"
3322             + "            log(xhr.response);\n"
3323             + "            log(xhr.response.size);\n"
3324             + "            log(xhr.response.type);\n"
3325             + "          } catch(ex) { logEx(e); }\n"
3326             + "        }\n"
3327             + "      }\n"
3328             + "    </script>\n"
3329             + "  </head>\n"
3330             + "  <body onload='test()'>\n"
3331             + "  </body>\n"
3332             + "</html>";
3333 
3334         final String xml =
3335               "<xml>\n"
3336             + "<content>blah</content>\n"
3337             + "</xml>";
3338 
3339         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3340         loadPage2(html);
3341         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3342     }
3343 
3344     /**
3345      * @throws Exception if the test fails
3346      */
3347     @Test
3348     @Alerts({"", "blob", "[object Blob]", "0"})
3349     public void responseResponseTypeBlobEmpty() throws Exception {
3350         final String html = DOCTYPE_HTML
3351             + "<html>\n"
3352             + "  <head>\n"
3353             + "    <script>\n"
3354             + LOG_TITLE_FUNCTION
3355             + "      var xhr;\n"
3356             + "      function test() {\n"
3357             + "        xhr = new XMLHttpRequest();\n"
3358             + "        log(xhr.responseText);\n"
3359 
3360             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3361             + "        xhr.responseType = 'blob';\n"
3362             + "        log(xhr.responseType);\n"
3363 
3364             + "        xhr.onreadystatechange = onStateChange;\n"
3365             + "        xhr.send('');\n"
3366             + "      }\n"
3367 
3368             + "      function onStateChange(e) {\n"
3369             + "        if (xhr.readyState == 4) {\n"
3370             + "          try {\n"
3371             + "            log(xhr.response);\n"
3372             + "            log(xhr.response.size);\n"
3373             + "          } catch(ex) { logEx(e); }\n"
3374             + "        }\n"
3375             + "      }\n"
3376             + "    </script>\n"
3377             + "  </head>\n"
3378             + "  <body onload='test()'>\n"
3379             + "  </body>\n"
3380             + "</html>";
3381 
3382         final String xml = "";
3383 
3384         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3385         loadPage2(html);
3386         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3387     }
3388 
3389     /**
3390      * @throws Exception if the test fails
3391      */
3392     @Test
3393     @Alerts({"", "json", "[object Object]", "Unit", "{\"Html\":\"Unit\"}"})
3394     public void responseResponseTypeJson() throws Exception {
3395         final String html = DOCTYPE_HTML
3396             + "<html>\n"
3397             + "  <head>\n"
3398             + "    <script>\n"
3399             + LOG_TITLE_FUNCTION
3400             + "      var xhr;\n"
3401             + "      function test() {\n"
3402             + "        xhr = new XMLHttpRequest();\n"
3403             + "        log(xhr.responseText);\n"
3404 
3405             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3406             + "        xhr.responseType = 'json';\n"
3407             + "        log(xhr.responseType);\n"
3408 
3409             + "        xhr.onreadystatechange = onStateChange;\n"
3410             + "        xhr.send('');\n"
3411             + "      }\n"
3412 
3413             + "      function onStateChange(e) {\n"
3414             + "        if (xhr.readyState == 4) {\n"
3415             + "          try {\n"
3416             + "            log(xhr.response);\n"
3417             + "            log(xhr.response.Html);\n"
3418             + "            log(JSON.stringify(xhr.response));\n"
3419             + "          } catch(e) { logEx(e); }\n"
3420             + "        }\n"
3421             + "      }\n"
3422             + "    </script>\n"
3423             + "  </head>\n"
3424             + "  <body onload='test()'>\n"
3425             + "  </body>\n"
3426             + "</html>";
3427 
3428         final String json = "{ \"Html\": \"Unit\" }";
3429 
3430         getMockWebConnection().setResponse(URL_SECOND, json, MimeType.APPLICATION_JSON);
3431         loadPage2(html);
3432         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3433     }
3434 
3435     /**
3436      * @throws Exception if the test fails
3437      */
3438     @Test
3439     @Alerts({"", "json", "null"})
3440     public void responseResponseTypeJsonEmpty() throws Exception {
3441         final String html = DOCTYPE_HTML
3442             + "<html>\n"
3443             + "  <head>\n"
3444             + "    <script>\n"
3445             + LOG_TITLE_FUNCTION
3446             + "      var xhr;\n"
3447             + "      function test() {\n"
3448             + "        xhr = new XMLHttpRequest();\n"
3449             + "        log(xhr.responseText);\n"
3450 
3451             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3452             + "        xhr.responseType = 'json';\n"
3453             + "        log(xhr.responseType);\n"
3454 
3455             + "        xhr.onreadystatechange = onStateChange;\n"
3456             + "        xhr.send('');\n"
3457             + "      }\n"
3458 
3459             + "      function onStateChange(e) {\n"
3460             + "        if (xhr.readyState == 4) {\n"
3461             + "          try {\n"
3462             + "            log(xhr.response);\n"
3463             + "          } catch(e) { logEx(e); }\n"
3464             + "        }\n"
3465             + "      }\n"
3466             + "    </script>\n"
3467             + "  </head>\n"
3468             + "  <body onload='test()'>\n"
3469             + "  </body>\n"
3470             + "</html>";
3471 
3472         final String json = "";
3473 
3474         getMockWebConnection().setResponse(URL_SECOND, json, MimeType.APPLICATION_JSON);
3475         loadPage2(html);
3476         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3477     }
3478 
3479     /**
3480      * @throws Exception if the test fails
3481      */
3482     @Test
3483     @Alerts({"", "document", "[object XMLDocument]"})
3484     public void responseResponseTypeDocumentXml() throws Exception {
3485         final String html = DOCTYPE_HTML
3486             + "<html>\n"
3487             + "  <head>\n"
3488             + "    <script>\n"
3489             + LOG_TITLE_FUNCTION
3490             + "      var xhr;\n"
3491             + "      function test() {\n"
3492             + "        xhr = new XMLHttpRequest();\n"
3493             + "        log(xhr.responseText);\n"
3494 
3495             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3496             + "        xhr.responseType = 'document';\n"
3497             + "        log(xhr.responseType);\n"
3498 
3499             + "        xhr.onreadystatechange = onStateChange;\n"
3500             + "        xhr.send('');\n"
3501             + "      }\n"
3502 
3503             + "      function onStateChange(e) {\n"
3504             + "        if (xhr.readyState == 4) {\n"
3505             + "          try {\n"
3506             + "            log(xhr.response);\n"
3507             + "          } catch(e) { logEx(e); }\n"
3508             + "        }\n"
3509             + "      }\n"
3510             + "    </script>\n"
3511             + "  </head>\n"
3512             + "  <body onload='test()'>\n"
3513             + "  </body>\n"
3514             + "</html>";
3515 
3516         final String xml =
3517                 "<xml>\n"
3518               + "<content>blah</content>\n"
3519               + "</xml>";
3520 
3521         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_XML);
3522         loadPage2(html);
3523         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3524     }
3525 
3526     /**
3527      * @throws Exception if the test fails
3528      */
3529     @Test
3530     @Alerts({"", "document", "[object HTMLDocument]"})
3531     public void responseResponseTypeDocumentHtml() throws Exception {
3532         final String html = DOCTYPE_HTML
3533             + "<html>\n"
3534             + "  <head>\n"
3535             + "    <script>\n"
3536             + LOG_TITLE_FUNCTION
3537             + "      var xhr;\n"
3538             + "      function test() {\n"
3539             + "        xhr = new XMLHttpRequest();\n"
3540             + "        log(xhr.responseText);\n"
3541 
3542             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3543             + "        xhr.responseType = 'document';\n"
3544             + "        log(xhr.responseType);\n"
3545 
3546             + "        xhr.onreadystatechange = onStateChange;\n"
3547             + "        xhr.send('');\n"
3548             + "      }\n"
3549 
3550             + "      function onStateChange(e) {\n"
3551             + "        if (xhr.readyState == 4) {\n"
3552             + "          try {\n"
3553             + "            log(xhr.response);\n"
3554             + "          } catch(e) { logEx(e); }\n"
3555             + "        }\n"
3556             + "      }\n"
3557             + "    </script>\n"
3558             + "  </head>\n"
3559             + "  <body onload='test()'>\n"
3560             + "  </body>\n"
3561             + "</html>";
3562 
3563         final String xml =
3564                 "<html>\n"
3565               + "<body>Test</body>\n"
3566               + "<html>";
3567 
3568         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_HTML);
3569         loadPage2(html);
3570         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3571     }
3572 
3573     /**
3574      * @throws Exception if the test fails
3575      */
3576     @Test
3577     @Alerts({"", "document", "null"})
3578     public void responseResponseTypeDocumentJs() throws Exception {
3579         final String html = DOCTYPE_HTML
3580             + "<html>\n"
3581             + "  <head>\n"
3582             + "    <script>\n"
3583             + LOG_TITLE_FUNCTION
3584             + "      var xhr;\n"
3585             + "      function test() {\n"
3586             + "        xhr = new XMLHttpRequest();\n"
3587             + "        log(xhr.responseText);\n"
3588 
3589             + "        xhr.open('GET', '" + URL_SECOND + "', true);\n"
3590             + "        xhr.responseType = 'document';\n"
3591             + "        log(xhr.responseType);\n"
3592 
3593             + "        xhr.onreadystatechange = onStateChange;\n"
3594             + "        xhr.send('');\n"
3595             + "      }\n"
3596 
3597             + "      function onStateChange(e) {\n"
3598             + "        if (xhr.readyState == 4) {\n"
3599             + "          try {\n"
3600             + "            log(xhr.response);\n"
3601             + "          } catch(e) { logEx(e); }\n"
3602             + "        }\n"
3603             + "      }\n"
3604             + "    </script>\n"
3605             + "  </head>\n"
3606             + "  <body onload='test()'>\n"
3607             + "  </body>\n"
3608             + "</html>";
3609 
3610         final String xml =
3611                 "<html>\n"
3612               + "<body>Test</body>\n"
3613               + "<html>";
3614 
3615         getMockWebConnection().setResponse(URL_SECOND, xml, MimeType.TEXT_JAVASCRIPT);
3616         loadPage2(html);
3617         verifyTitle2(DEFAULT_WAIT_TIME, getWebDriver(), getExpectedAlerts());
3618     }
3619 }