com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequestTest.java Source code

Java tutorial

Introduction

Here is the source code for com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequestTest.java

Source

/*
 * Copyright (c) 2002-2017 Gargoyle Software Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gargoylesoftware.htmlunit.javascript.host.xml;

import static com.gargoylesoftware.htmlunit.BrowserRunner.Browser.IE;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Locale;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.ArrayUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;

import com.gargoylesoftware.htmlunit.BrowserRunner;
import com.gargoylesoftware.htmlunit.BrowserRunner.Alerts;
import com.gargoylesoftware.htmlunit.BrowserRunner.NotYetImplemented;
import com.gargoylesoftware.htmlunit.BrowserRunner.Tries;
import com.gargoylesoftware.htmlunit.WebDriverTestCase;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlPageTest;
import com.gargoylesoftware.htmlunit.util.NameValuePair;

/**
 * Tests for {@link XMLHttpRequest}.
 *
 * @author Daniel Gredler
 * @author Marc Guillemot
 * @author Ahmed Ashour
 * @author Stuart Begg
 * @author Sudhan Moghe
 * @author Sebastian Cato
 * @author Ronald Brill
 * @author Frank Danek
 * @author Jake Cobb
 */
@RunWith(BrowserRunner.class)
public class XMLHttpRequestTest extends WebDriverTestCase {

    private static final String UNINITIALIZED = String.valueOf(XMLHttpRequest.UNSENT);
    private static final String LOADING = String.valueOf(XMLHttpRequest.OPENED);
    private static final String COMPLETED = String.valueOf(XMLHttpRequest.DONE);

    /**
     * Tests synchronous use of XMLHttpRequest.
     * @throws Exception if the test fails
     */
    @Test
    @Tries(3)
    public void syncUse() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function testSync() {\n"
                + "        var request = new XMLHttpRequest();\n" + "        alert(request.readyState);\n"
                + "        request.open('GET', '" + URL_SECOND + "', false);\n"
                + "        alert(request.readyState);\n" + "        request.send('');\n"
                + "        alert(request.readyState);\n" + "        alert(request.responseText);\n" + "      }\n"
                + "    </script>\n" + "  </head>\n" + "  <body onload='testSync()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content>blah</content>\n" + "<content>blah2</content>\n" + "</xml>";

        setExpectedAlerts(UNINITIALIZED, LOADING, COMPLETED, xml);
        getMockWebConnection().setDefaultResponse(xml, "text/xml");

        loadPageWithAlerts2(html);
    }

    /**
     * Tests Mozilla and IE style object creation.
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object XMLHttpRequest]")
    public void creation() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "        if (window.XMLHttpRequest) {\n"
                + "          alert(new XMLHttpRequest());\n" + "        }\n"
                + "        else if (window.ActiveXObject) {\n"
                + "          new ActiveXObject('Microsoft.XMLHTTP');\n" + "          alert('activeX created');\n"
                + "        }\n" + "    </script>\n" + "  </head>\n" + "  <body></body>\n" + "</html>";
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "1: 0-", "2: ", "3: 200-OK" })
    public void statusSync() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n" + "<script>\n"
                + "  var xhr = new XMLHttpRequest();\n"

                + "  alertStatus('1: ');\n" + "  xhr.open('GET', '/foo.xml', false);\n" + "  alert('2: ');\n"

                + "  xhr.send();\n" + "  alertStatus('3: ');\n"

                + "  function alertStatus(prefix) {\n" + "    var msg = prefix;" + "    try {\n"
                + "      msg = msg + xhr.status + '-';\n" + "    } catch(e) { msg = msg + 'ex: status' + '-' }\n"
                + "    try {\n" + "      msg = msg + xhr.statusText;;\n"
                + "    } catch(e) { msg = msg + 'ex: statusText' }\n" + "    alert(msg);\n" + "  }\n"
                + "</script>\n" + "  </head>\n" + "  <body></body>\n" + "</html>";

        getMockWebConnection().setDefaultResponse("<res></res>", "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "1: 0-", "2: 0-", "#1: 0-", "3: 0-", "#1: 0-", "4: 0-", "#2: 200-OK", "#3: 200-OK",
            "#4: 200-OK" }, FF = { "1: 0-", "2: 0-", "#1: 0-", "3: 0-", "4: 0-", "#2: 200-OK", "#3: 200-OK",
                    "#4: 200-OK" }, CHROME = { "1: 0-", "2: 0-", "#1: 0-", "3: 0-", "4: 0-", "#2: 200-OK",
                            "#3: 200-OK", "#4: 200-OK" })
    public void statusAsync() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n" + "<script>\n"
                + "  var xhr = new XMLHttpRequest();\n"

                + "  function test() {\n" + "    try {\n" + "      alertStatus('1: ');\n"

                + "      xhr.onreadystatechange = onReadyStateChange;\n" + "      alertStatus('2: ');\n"

                + "      xhr.open('GET', '/foo.xml', true);\n" + "      alertStatus('3: ');\n"

                + "      xhr.send();\n" + "      alertStatus('4: ');\n" + "    } catch(e) { alert(e) }\n" + "  }\n"

                + "  function onReadyStateChange() {\n" + "    alertStatus('#' + xhr.readyState + ': ');" + "  }\n"

                + "  function alertStatus(prefix) {\n" + "    var msg = prefix;" + "    try {\n"
                + "      msg = msg + xhr.status + '-';\n" + "    } catch(e) { msg = msg + 'ex: status' + '-' }\n"
                + "    try {\n" + "      msg = msg + xhr.statusText;;\n"
                + "    } catch(e) { msg = msg + 'ex: statusText' }\n" + "    alert(msg);\n" + "  }\n"
                + "</script>\n" + "  </head>\n" + "  <body onload='test()'></body>\n" + "</html>";

        getMockWebConnection().setDefaultResponse("<res></res>", "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * Checks that not passing the async flag to <code>open()</code>
     * results in async execution.  If this gets interpreted as {@code false}
     * then you will see the alert order 1-2-4-3 instead of 1-2-3-4.
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "#1", "#2", "#3", "#4" })
    public void asyncIsDefault() throws Exception {
        final String html = "<html><body><script>\n" + "var xhr = new XMLHttpRequest();\n"

                + "function onReadyStateChange() {\n" + "  if( xhr.readyState == 4 ) {\n" + "    alert('#4');\n"
                + "  }\n" + "}\n"

                + "try {\n" + "  alert('#1');\n" + "  xhr.onreadystatechange = onReadyStateChange;\n"
                + "  xhr.open('GET', '/foo.xml');\n" + "  alert('#2');\n" + "  xhr.send();\n" + "  alert('#3');\n"
                + "} catch(e) { alert(e); }\n" + "</script></body></html>";

        getMockWebConnection().setDefaultResponse("<res></res>", "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "orsc1", "open-done", "orsc1", "send-done", "orsc2", "orsc3", "orsc4", "4", "<a>b</a>",
            "[object XMLHttpRequest]" }, FF = { "orsc1", "open-done", "send-done", "orsc2", "orsc3", "orsc4", "4",
                    "<a>b</a>", "[object XMLHttpRequest]" }, CHROME = { "orsc1", "open-done", "send-done", "orsc2",
                            "orsc3", "orsc4", "4", "<a>b</a>", "[object XMLHttpRequest]" })
    public void onload() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function test() {\n"
                + "        var xhr = new XMLHttpRequest();\n"

                + "        xhr.onreadystatechange = function() { alert('orsc' + xhr.readyState); };\n"
                + "        xhr.onload = function() { alert(xhr.readyState); alert(xhr.responseText); alert(this); }\n"

                + "        xhr.open('GET', '/foo.xml', true);\n" + "        alert('open-done');\n"

                + "        xhr.send('');\n" + "        alert('send-done');\n" + "      }\n" + "    </script>\n"
                + "  </head>\n" + "  <body onload='test()'></body>\n" + "</html>";

        final String xml = "<a>b</a>";

        getMockWebConnection().setDefaultResponse(xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "null", "null" })
    public void responseHeaderBeforeSend() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "        var request = new XMLHttpRequest();\n"

                + "        alert(request.getResponseHeader('content-length'));\n"
                + "        request.open('GET', '/foo.xml', false);\n"
                + "        alert(request.getResponseHeader('content-length'));\n" + "    </script>\n"
                + "  </head>\n" + "  <body></body>\n" + "</html>";
        loadPageWithAlerts2(html);
    }

    /**
     * Regression test for http://sourceforge.net/p/htmlunit/bugs/269/.
     * @throws Exception if the test fails
     */
    @Test
    public void relativeUrl() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function testSync() {\n"
                + "        var request = new XMLHttpRequest();\n"
                + "        request.open('GET', '/foo.xml', false);\n" + "        request.send('');\n"
                + "        alert(request.readyState);\n" + "        alert(request.responseText);\n" + "      }\n"
                + "    </script>\n" + "  </head>\n" + "  <body onload='testSync()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content>blah</content>\n" + "<content>blah2</content>\n" + "</xml>";

        setExpectedAlerts(COMPLETED, xml);
        getMockWebConnection().setDefaultResponse(xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("bla bla")
    public void responseText_NotXml() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.txt', false);\n"
                + "  request.send('');\n" + "  alert(request.responseText);\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setDefaultResponse("bla bla", "text/plain");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("null")
    public void responseXML_text_html() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n"
                + "  function test() {\n" + "    var xhr = new XMLHttpRequest();\n"
                + "    xhr.open('GET', 'foo.xml', false);\n" + "    xhr.send('');\n" + "    try {\n"
                + "      alert(xhr.responseXML);\n" + "    } catch(e) { alert('exception'); }\n" + "  }\n"
                + "</script></head><body onload='test()'>\n" + "</body></html>";

        getMockWebConnection().setDefaultResponse("<html></html>", "text/html");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object XMLDocument]")
    public void responseXML_text_xml() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n"
                + "  function test() {\n" + "    var xhr = new XMLHttpRequest();\n"
                + "    xhr.open('GET', 'foo.xml', false);\n" + "    xhr.send('');\n" + "    try {\n"
                + "      alert(xhr.responseXML);\n" + "    } catch(e) { alert('exception'); }\n" + "  }\n"
                + "</script></head><body onload='test()'>\n" + "</body></html>";

        getMockWebConnection().setDefaultResponse("<note/>", "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object XMLDocument]")
    public void responseXML_application_xml() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n"
                + "  function test() {\n" + "    var xhr = new XMLHttpRequest();\n"
                + "    xhr.open('GET', 'foo.xml', false);\n" + "    xhr.send('');\n" + "    try {\n"
                + "      alert(xhr.responseXML);\n" + "    } catch(e) { alert('exception'); }\n" + "  }\n"
                + "</script></head><body onload='test()'>\n" + "</body></html>";

        getMockWebConnection().setDefaultResponse("<note/>", "application/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object XMLDocument]")
    public void responseXML_application_xhtmlXml() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n"
                + "  function test() {\n" + "    var xhr = new XMLHttpRequest();\n"
                + "    xhr.open('GET', 'foo.xml', false);\n" + "    xhr.send('');\n" + "    try {\n"
                + "      alert(xhr.responseXML);\n" + "    } catch(e) { alert('exception'); }\n" + "  }\n"
                + "</script></head><body onload='test()'>\n" + "</body></html>";

        getMockWebConnection().setDefaultResponse("<html/>", "application/xhtml+xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object XMLDocument]")
    public void responseXML_application_svgXml() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = HtmlPageTest.STANDARDS_MODE_PREFIX_ + "<html><head><title>foo</title><script>\n"
                + "  function test() {\n" + "    var xhr = new XMLHttpRequest();\n"
                + "    xhr.open('GET', 'foo.xml', false);\n" + "    xhr.send('');\n" + "    try {\n"
                + "      alert(xhr.responseXML);\n" + "    } catch(e) { alert('exception'); }\n" + "  }\n"
                + "</script></head><body onload='test()'>\n" + "</body></html>";

        getMockWebConnection().setDefaultResponse("<svg xmlns=\"http://www.w3.org/2000/svg\"/>", "image/svg+xml");
        loadPageWithAlerts2(html);
    }

    /**
     * Regression test for IE specific properties attribute.text & attribute.xml.
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "1", "someAttr", "undefined", "undefined" })
    public void responseXML2() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.xml', false);\n"
                + "  request.send('');\n" + "  var childNodes = request.responseXML.childNodes;\n"
                + "  alert(childNodes.length);\n" + "  var rootNode = childNodes[0];\n"
                + "  alert(rootNode.attributes[0].nodeName);\n" + "  alert(rootNode.attributes[0].text);\n"
                + "  alert(rootNode.attributes[0].xml);\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        final URL urlPage2 = new URL(URL_FIRST + "foo.xml");
        getMockWebConnection().setResponse(urlPage2,
                "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n", "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("received: null")
    public void responseXML_siteNotExisting() throws Exception {
        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "try {\n"
                + "  request.open('GET', 'http://this.doesnt.exist/foo.xml', false);\n" + "  request.send('');\n"
                + "} catch(e) {\n" + "  alert('received: ' + request.responseXML);\n" + "}\n" + "}\n"
                + "</script>\n" + "</head>\n" + "<body onload='test()'></body></html>";

        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    public void sendNull() throws Exception {
        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.txt', false);\n"
                + "  request.send(null);\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setDefaultResponse("");
        loadPageWithAlerts2(html);
    }

    /**
     * Test calls to send('foo') for a GET. HtmlUnit 1.14 was incorrectly throwing an exception.
     * @throws Exception if the test fails
     */
    @Test
    public void sendGETWithContent() throws Exception {
        send("'foo'");
    }

    /**
     * Test calls to send() without any arguments.
     * @throws Exception if the test fails
     */
    @Test
    public void sendNoArg() throws Exception {
        send("");
    }

    /**
     * @throws Exception if the test fails
     */
    private void send(final String sendArg) throws Exception {
        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.txt', false);\n"
                + "  request.send(" + sendArg + ");\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setDefaultResponse("");
        loadPageWithAlerts2(html);
    }

    /**
     * Regression test for bug 1357412.
     * Response received by the XMLHttpRequest should not come in any window
     * @throws Exception if the test fails
     */
    @Test
    public void responseNotInWindow() throws Exception {
        final String html = "<html><head><title>foo</title>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.txt', false);\n"
                + "  request.send();\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setDefaultResponse("");
        final WebDriver webdriver = loadPageWithAlerts2(html);
        assertEquals(getDefaultUrl().toString(), webdriver.getCurrentUrl());
        assertEquals("foo", webdriver.getTitle());
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "true", "false" })
    public void overrideMimeType() throws Exception {
        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "try {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.xml.txt', false);\n"
                + "  request.send('');\n" + "  alert(request.responseXML == null);\n"
                + "  request.open('GET', 'foo.xml.txt', false);\n" + "  request.overrideMimeType('text/xml');\n"
                + "  request.send('');\n" + "  alert(request.responseXML == null);\n"
                + "} catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        final URL urlPage2 = new URL(getDefaultUrl() + "foo.xml.txt");
        getMockWebConnection().setResponse(urlPage2,
                "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n", "text/plain");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "true", "overwritten" }, CHROME = { "true", "exception" }, IE = { "true", "exception" })
    public void overrideMimeTypeAfterSend() throws Exception {
        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', 'foo.xml.txt', false);\n"
                + "  request.send('');\n" + "  alert(request.responseXML == null);\n" + "  try {\n"
                + "    request.overrideMimeType('text/xml');\n" + "    alert('overwritten');\n"
                + "  } catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        final URL urlPage2 = new URL(getDefaultUrl() + "foo.xml.txt");
        getMockWebConnection().setResponse(urlPage2,
                "<bla someAttr='someValue'><foo><fi id='fi1'/><fi/></foo></bla>\n", "text/plain");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("27035")
    public void overrideMimeType_charset() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "try {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', '" + URL_SECOND
                + "', false);\n" + "  request.overrideMimeType('text/plain; charset=GBK');\n"
                + "  request.send('');\n" + "  alert(request.responseText.charCodeAt(0));\n"
                + "} catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", "text/plain", "UTF-8");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("27035")
    public void overrideMimeType_charset_upper_case() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "try {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', '" + URL_SECOND
                + "', false);\n" + "  request.overrideMimeType('text/plain; chaRSet=GBK');\n"
                + "  request.send('');\n" + "  alert(request.responseText.charCodeAt(0));\n"
                + "} catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", "text/plain", "UTF-8");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("40644")
    public void overrideMimeType_charset_empty() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "try {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', '" + URL_SECOND
                + "', false);\n" + "  request.overrideMimeType('text/plain; charset=');\n" + "  request.send('');\n"
                + "  alert(request.responseText.charCodeAt(0));\n" + "} catch (e) { alert('exception'); }\n" + "}\n"
                + "</script>\n" + "</head>\n" + "<body onload='test()'></body></html>";

        getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", "text/plain", "UTF-8");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = "40644", CHROME = { "233", "187", "8222" }, IE = {})
    public void overrideMimeType_charset_wrong() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "  try {\n"
                + "    var request = new XMLHttpRequest();\n" + "    request.open('GET', '" + URL_SECOND
                + "', false);\n" + "    request.overrideMimeType('text/plain; charset=abcdefg');\n"
                + "    request.send('');\n" + "    var text = request.responseText;\n"
                + "    for (var i = 0; i < text.length; i++) {\n" + "      alert(text.charCodeAt(i));\n" + "    }\n"
                + "  } catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setResponse(URL_SECOND, "\u9EC4", "text/plain", "UTF-8");
        loadPageWithAlerts2(html);
    }

    /**
     * Regression test for bug 410.
     * http://sourceforge.net/p/htmlunit/bugs/410/
     * Caution: the problem appeared with JDK 1.4 but not with JDK 1.5 as String contains a
     * replace(CharSequence, CharSequence) method in this version
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "ibcdefg", "xxxxxfg" })
    public void replaceOnTextData() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      var request;\n" + "      function testReplace() {\n"
                + "        request = new XMLHttpRequest();\n"
                + "        request.onreadystatechange = onReadyStateChange;\n" + "        request.open('GET', '"
                + URL_SECOND + "', false);\n" + "        request.send('');\n" + "      }\n"
                + "      function onReadyStateChange() {\n" + "        if (request.readyState == 4){\n"
                + "          var theXML = request.responseXML;\n"
                + "          var theDoc = theXML.documentElement;\n"
                + "          var theElements = theDoc.getElementsByTagName('update');\n"
                + "          var theUpdate = theElements[0];\n"
                + "          var theData = theUpdate.firstChild.data;\n"
                + "          theResult = theData.replace('a','i');\n" + "          alert(theResult)\n"
                + "          theResult = theData.replace('abcde', 'xxxxx');\n" + "          alert(theResult)\n"
                + "        }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='testReplace()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<updates>\n" + "<update>abcdefg</update>\n" + "<update>hijklmn</update>\n"
                + "</updates>";

        getMockWebConnection().setDefaultResponse(xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * Tests that the <tt>Referer</tt> header is set correctly.
     * @throws Exception if the test fails
     */
    @Test
    public void refererHeader() throws Exception {
        final String html = "<html><head><script>\n" + "function test() {\n" + "  req = new XMLHttpRequest();\n"
                + "  req.open('post', 'foo.xml', false);\n" + "  req.send('');\n" + "}\n" + "</script></head>\n"
                + "<body onload='test()'></body></html>";

        final URL urlPage2 = new URL(URL_FIRST + "foo.xml");
        getMockWebConnection().setResponse(urlPage2, "<foo/>\n", "text/xml");
        loadPage2(html);

        final WebRequest request = getMockWebConnection().getLastWebRequest();
        assertEquals(urlPage2, request.getUrl());
        assertEquals(URL_FIRST.toExternalForm(), request.getAdditionalHeaders().get("Referer"));
    }

    /**
     * Test for bug https://sourceforge.net/tracker/?func=detail&atid=448266&aid=1784330&group_id=47038.
     * @throws Exception if an error occurs
     */
    @Test
    @Alerts(DEFAULT = "ActiveXObject not available", IE = { "0", "0" })
    public void caseInsensitivityActiveXConstructor() throws Exception {
        final String html = "<html><head><script>\n" + "function test() {\n" + "  try {\n"
                + "    var req = new ActiveXObject('MSXML2.XmlHttp');\n" + "    alert(req.readyState);\n"

                + "    var req = new ActiveXObject('msxml2.xMLhTTp');\n" + "    alert(req.readyState);\n"
                + "  } catch (e) { alert('ActiveXObject not available'); }\n" + "}\n" + "</script></head>\n"
                + "<body onload='test()'></body></html>";

        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("selectNodes not available")
    public void responseXML_selectNodesIE() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function test() {\n" + "        var request = new XMLHttpRequest();\n"
                + "        request.open('GET', '" + URL_SECOND + "', false);\n" + "        request.send('');\n"
                + "        if (!request.responseXML.selectNodes) { alert('selectNodes not available'); return }\n"
                + "        alert(request.responseXML.selectNodes('//content').length);\n" + "      }\n"
                + "    </script>\n" + "  </head>\n" + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content>blah</content>\n" + "<content>blah2</content>\n" + "</xml>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "null", "myID", "blah", "span", "[object XMLDocument]" }, CHROME = { "[object Element]",
            "myID", "blah", "span",
            "[object XMLDocument]" }, FF = { "[object Element]", "myID", "blah", "span", "[object XMLDocument]" })
    public void responseXML_getElementById2() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function test() {\n" + "        var request = new XMLHttpRequest();\n"
                + "        request.open('GET', '" + URL_SECOND + "', false);\n" + "        request.send('');\n"
                + "        if (request.responseXML.getElementById) {\n"
                + "          alert(request.responseXML.getElementById('id1'));\n"
                + "          alert(request.responseXML.getElementById('myID').id);\n"
                + "          alert(request.responseXML.getElementById('myID').innerHTML);\n"
                + "          alert(request.responseXML.getElementById('myID').tagName);\n"
                + "          alert(request.responseXML.getElementById('myID').ownerDocument);\n"
                + "        } else  {\n" + "          alert('responseXML.getElementById not available');\n"
                + "        }\n" + "      }\n" + "    </script>\n" + "  </head>\n" + "  <body onload='test()'>\n"
                + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content id='id1'>blah</content>\n" + "<content>blah2</content>\n"
                + "<html xmlns='http://www.w3.org/1999/xhtml'>\n" + "<span id='myID'>blah</span>\n"
                + "<script src='foo.js'></script>\n" + "</html>\n" + "</xml>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts({ "[object Element]", "[object Element]", "[object HTMLBodyElement]", "[object HTMLSpanElement]",
            "[object XMLDocument]", "undefined" })
    public void responseXML_getElementById() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function test() {\n" + "        var request = new XMLHttpRequest();\n"
                + "        request.open('GET', '" + URL_SECOND + "', false);\n" + "        request.send('');\n"
                + "        var doc = request.responseXML;\n" + "        alert(doc.documentElement);\n"
                + "        alert(doc.documentElement.childNodes[0]);\n"
                + "        alert(doc.documentElement.childNodes[1]);\n" + "        if (doc.getElementById) {\n"
                + "          alert(doc.getElementById('out'));\n"
                + "          alert(doc.getElementById('out').ownerDocument);\n" + "        }\n"
                + "        alert(doc.documentElement.childNodes[1].xml);\n" + "      }\n" + "    </script>\n"
                + "  </head>\n" + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<html>" + "<head>" + "</head>" + "<body xmlns='http://www.w3.org/1999/xhtml'>"
                + "<span id='out'>Hello Bob Dole!</span>" + "</body>" + "</html>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * Verifies that the default encoding for an XMLHttpRequest is UTF-8.
     * @throws Exception if an error occurs
     */
    @Test
    @Alerts("ol\u00E9")
    public void defaultEncodingIsUTF8() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function test() {\n"
                + "        var request = new XMLHttpRequest();\n" + "        request.open('GET', '" + URL_SECOND
                + "', false);\n" + "        request.send('');\n" + "        alert(request.responseText);\n"
                + "      }\n" + "    </script>\n" + "  </head>\n" + "  <body onload='test()'>\n" + "  </body>\n"
                + "</html>";

        final String response = "ol\u00E9";
        final byte[] responseBytes = response.getBytes("UTF-8");

        getMockWebConnection().setResponse(URL_SECOND, responseBytes, 200, "OK", "text/html",
                new ArrayList<NameValuePair>());
        loadPageWithAlerts2(html);
    }

    /**
     * Custom servlet which streams content to the client little by little.
     */
    public static final class StreamingServlet extends HttpServlet {
        /** {@inheritDoc} */
        @Override
        protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
            resp.setStatus(200);
            resp.addHeader("Content-Type", "text/html");
            try {
                for (int i = 0; i < 10; i++) {
                    resp.getOutputStream().print(String.valueOf(i));
                    resp.flushBuffer();
                    Thread.sleep(150);
                }
            } catch (final InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    /**
     * Servlet for testing XMLHttpRequest basic authentication.
     */
    public static final class BasicAuthenticationServlet extends HttpServlet {

        /**
         * {@inheritDoc}
         */
        @Override
        protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
            handleRequest(req, resp);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws IOException {
            handleRequest(req, resp);
        }

        private static void handleRequest(final HttpServletRequest req, final HttpServletResponse resp)
                throws IOException {
            final String authHdr = req.getHeader("Authorization");
            if (null == authHdr) {
                resp.setStatus(401);
                resp.setHeader("WWW-Authenticate", "Basic realm=\"someRealm\"");
            } else {
                final String[] authHdrTokens = authHdr.split("\\s+");
                String authToken = "";
                if (authHdrTokens.length == 2) {
                    authToken += authHdrTokens[0] + ':' + authHdrTokens[1];
                }

                resp.setStatus(200);
                resp.addHeader("Content-Type", "text/plain");
                resp.getOutputStream().print(authToken);
                resp.flushBuffer();
            }
        }
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("myID")
    public void responseXML_html_select() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function test() {\n" + "        try {\n"
                + "          var request = new XMLHttpRequest();\n" + "          request.open('GET', '" + URL_SECOND
                + "', false);\n" + "          request.send('');\n"
                + "          alert(request.responseXML.getElementById('myID').id);\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content id='id1'>blah</content>\n" + "<content>blah2</content>\n"
                + "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
                + "<select id='myID'><option>One</option></select>\n" + "</html>\n" + "</xml>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("myInput")
    public void responseXML_html_form() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      function test() {\n" + "        try {\n"
                + "          var request = new XMLHttpRequest();\n" + "          request.open('GET', '" + URL_SECOND
                + "', false);\n" + "          request.send('');\n"
                + "          alert(request.responseXML.getElementById('myID').myInput.name);\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<xml>\n" + "<content id='id1'>blah</content>\n" + "<content>blah2</content>\n"
                + "<html xmlns='http://www.w3.org/1999/xhtml'>\n"
                + "<form id='myID'><input name='myInput'/></form>\n" + "</html>\n" + "</xml>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if an error occurs
     */
    @Test
    @Alerts(DEFAULT = "ActiveXObject not available", IE = { "0", "0" })
    public void caseSensitivity_activeX() throws Exception {
        final String html = "<html><head><script>\n" + "function test() {\n" + "  try {\n"
                + "    var req = new ActiveXObject('MSXML2.XmlHttp');\n" + "    alert(req.readyState);\n"
                + "    alert(req.reAdYsTaTe);\n" + "  } catch (e) { alert('ActiveXObject not available'); }\n"
                + "}\n" + "</script></head>\n" + "<body onload='test()'></body></html>";
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if an error occurs
     */
    @Test
    @Alerts({ "0", "undefined" })
    public void caseSensitivity_XMLHttpRequest() throws Exception {
        final String html = "<html><head><script>\n" + "function test() {\n" + "  try {\n"
                + "    var req = new XMLHttpRequest();\n" + "    alert(req.readyState);\n"
                + "    alert(req.reAdYsTaTe);\n" + "  } catch (e) { alert('exception'); }\n" + "}\n"
                + "</script></head>\n" + "<body onload='test()'></body></html>";
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    public void isAuthorizedHeader() throws Exception {
        assertTrue(XMLHttpRequest.isAuthorizedHeader("Foo"));
        assertTrue(XMLHttpRequest.isAuthorizedHeader("Content-Type"));

        final String[] headers = { "accept-charset", "accept-encoding", "connection", "content-length", "cookie",
                "cookie2", "content-transfer-encoding", "date", "expect", "host", "keep-alive", "referer", "te",
                "trailer", "transfer-encoding", "upgrade", "user-agent", "via" };
        for (final String header : headers) {
            assertFalse(XMLHttpRequest.isAuthorizedHeader(header));
            assertFalse(XMLHttpRequest.isAuthorizedHeader(header.toUpperCase(Locale.ROOT)));
        }
        assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-"));
        assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-Control"));
        assertFalse(XMLHttpRequest.isAuthorizedHeader("Proxy-Hack"));
        assertFalse(XMLHttpRequest.isAuthorizedHeader("Sec-"));
        assertFalse(XMLHttpRequest.isAuthorizedHeader("Sec-Hack"));
    }

    /**
     * Test case for Bug #1623.
     *
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "39", "27035", "65533", "39" }, IE = { "39", "27035", "63" })
    @NotYetImplemented(IE)
    public void overrideMimeType_charset_all() throws Exception {
        // TODO [IE]SINGLE-VS-BULK test runs when executed as single but breaks as bulk
        shutDownRealIE();

        final String html = "<html><head>\n" + "<script>\n" + "function test() {\n" + "try {\n"
                + "  var request = new XMLHttpRequest();\n" + "  request.open('GET', '" + URL_SECOND
                + "', false);\n" + "  request.overrideMimeType('text/plain; charset=GBK');\n"
                + "  request.send('');\n" + "  for (var i = 0; i < request.responseText.length; i++) {\n"
                + "    alert(request.responseText.charCodeAt(i));\n" + "  }\n"
                + "} catch (e) { alert('exception'); }\n" + "}\n" + "</script>\n" + "</head>\n"
                + "<body onload='test()'></body></html>";

        getMockWebConnection().setResponse(URL_SECOND, "'\u9EC4'", "text/plain", "UTF-8");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    public void java_encoding() throws Exception {
        // Chrome and FF return the last apostrophe, see overrideMimeType_charset_all()
        // but Java and other tools (e.g. Notpad++) return only 3 characters, not 4
        // this method is not a test case, but rather to show the behavior of java

        final String string = "'\u9EC4'";
        final ByteArrayInputStream bais = new ByteArrayInputStream(string.getBytes("UTF-8"));
        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(bais, "GBK"))) {
            final String output = reader.readLine();
            assertNotNull(output);
            assertEquals(39, output.codePointAt(0));
            assertEquals(27035, output.codePointAt(1));
            assertEquals(65533, output.codePointAt(2));
            assertEquals(39, output.codePointAt(3));
        }
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts("[object ProgressEvent]")
    public void loadParameter() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function someLoad(e) {\n"
                + "        alert(e);\n" + "      }\n" + "      function test() {\n" + "        try {\n"
                + "          var request = new XMLHttpRequest();\n" + "          request.onload = someLoad;"
                + "          request.open('GET', '" + URL_SECOND + "', false);\n" + "          request.send('');\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<abc></abc>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "someLoad [object ProgressEvent]", "load", "true" }, CHROME = {
            "someLoad [object ProgressEvent]", "load", "false" })
    public void addEventListener() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function someLoad(event) {\n"
                + "        alert('someLoad ' + event);\n" + "        alert(event.type);\n"
                + "        alert(event.lengthComputable);\n" + "      }\n" + "      function test() {\n"
                + "        try {\n" + "          var request = new XMLHttpRequest();\n"
                + "          request.addEventListener('load', someLoad, false);" + "          request.open('GET', '"
                + URL_SECOND + "', false);\n" + "          request.send('');\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<abc></abc>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "someLoad [object ProgressEvent]", "load", "true", "11", "11" }, CHROME = {
            "someLoad [object ProgressEvent]", "load", "false", "11", "0" })
    public void addEventListenerDetails() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function someLoad(event) {\n"
                + "        alert('someLoad ' + event);\n" + "        alert(event.type);\n"
                + "        alert(event.lengthComputable);\n" + "        alert(event.loaded);\n"
                + "        alert(event.total);\n" + "      }\n" + "      function test() {\n" + "        try {\n"
                + "          var request = new XMLHttpRequest();\n"
                + "          request.addEventListener('load', someLoad, false);" + "          request.open('GET', '"
                + URL_SECOND + "', false);\n" + "          request.send('');\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<abc></abc>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = "null", CHROME = "function")
    @NotYetImplemented
    public void addEventListenerCaller() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function someLoad(event) {\n"
                + "        var caller = arguments.callee.caller;\n"
                + "        alert(typeof caller == 'function' ? 'function' : caller);\n" + "      }\n"
                + "      function test() {\n" + "        try {\n"
                + "          var request = new XMLHttpRequest();\n"
                + "          request.addEventListener('load', someLoad, false);" + "          request.open('GET', '"
                + URL_SECOND + "', false);\n" + "          request.send('');\n"
                + "        } catch (e) { alert('exception'); }\n" + "      }\n" + "    </script>\n" + "  </head>\n"
                + "  <body onload='test()'>\n" + "  </body>\n" + "</html>";

        final String xml = "<abc></abc>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        loadPageWithAlerts2(html);
    }

    /**
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = "[object XMLHttpRequestUpload]", IE = "[object XMLHttpRequestEventTarget]")
    public void upload() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <script>\n" + "      function test() {\n"
                + "        try {\n" + "          var request = new XMLHttpRequest();\n"
                + "          alert(request.upload);\n" + "        } catch (e) { alert('exception'); }\n"
                + "      }\n" + "    </script>\n" + "  </head>\n" + "  <body onload='test()'>\n" + "  </body>\n"
                + "</html>";

        loadPageWithAlerts2(html);
    }

    /**
     * Tests asynchronous use of XMLHttpRequest, using Mozilla style object creation.
     * @throws Exception if the test fails
     */
    @Test
    @Alerts(DEFAULT = { "0", "1", "2", "3", "4" }, IE = { "0", "1", "1", "2", "3", "4" })
    public void asyncUse() throws Exception {
        final String html = "<html>\n" + "  <head>\n" + "    <title>XMLHttpRequest Test</title>\n"
                + "    <script>\n" + "      var request;\n" + "      function testAsync() {\n"
                + "        request = new XMLHttpRequest();\n"
                + "        request.onreadystatechange = onReadyStateChange;\n"
                + "        alert(request.readyState);\n" + "        request.open('GET', '" + URL_SECOND
                + "', true);\n" + "        request.send('');\n" + "      }\n"
                + "      function onReadyStateChange() {\n" + "        alert(request.readyState);\n"
                + "        if (request.readyState == 4)\n" + "          alert(request.responseText);\n"
                + "      }\n" + "    </script>\n" + "  </head>\n" + "  <body onload='testAsync()'>\n"
                + "  </body>\n" + "</html>";

        final String xml = "<xml2>\n" + "<content2>sdgxsdgx</content2>\n" + "<content2>sdgxsdgx2</content2>\n"
                + "</xml2>";

        getMockWebConnection().setResponse(URL_SECOND, xml, "text/xml");
        setExpectedAlerts(ArrayUtils.add(getExpectedAlerts(), xml));
        loadPageWithAlerts2(html);
    }

}