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