<button onclick="testSyncCookiesNoCredentials();">Start</button>
<pre id="console"></pre>
<script>
if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.waitUntilDone();
    testRunner.setCanOpenWindows();
    testRunner.setBlockThirdPartyCookies(false);
}

function log(message)
{
    var consoleDiv = document.getElementById('console');
    consoleDiv.appendChild(document.createTextNode(message + '\n'));
}

function resourceURL(resourceName)
{
    return "https://localhost:8443/xmlhttprequest/resources/" + resourceName;
}

function clearCookies()
{
    var xhr = new XMLHttpRequest;
    xhr.open("GET", resourceURL("cross-origin-set-cookies.php?clear=1"), false);
    xhr.withCredentials = true;
    xhr.send("");
}

function endTesting()
{
    clearCookies();
    if (window.testRunner)
        testRunner.notifyDone();
}

function checkForCookie()
{
    var xhr = new XMLHttpRequest;
    xhr.open("GET", resourceURL("cross-origin-check-cookies.php?cookie=WK-xhr-cookie-storage"), false);
    xhr.withCredentials = true;
    try {
        xhr.send();
        return xhr.responseText
    } catch (ex) {
        log("FAIL: Got an exception. " + ex);
    }
}

function testSyncCookiesNoCredentials()
{
    log("Cross-origin XMLHttpRequest (sync), testing that cookies are not set when not sending credentials.");

    clearCookies();

    var req = new XMLHttpRequest;
    req.open("GET", resourceURL("cross-origin-set-cookies.php"), false);
    req.withCredentials = false;
    req.send();
    log("PASS: Finished sync xhr.");

    var response = checkForCookie()
    log(!response.match(/WK\-xhr\-cookie\-storage: MySpecialValue/) ? "PASS: No cookies set." : ("FAIL: " + response));

    testAsyncCookiesNoCredentials();
}

function testAsyncCookiesNoCredentials()
{
    log("Cross-origin XMLHttpRequest (async), testing that cookies are not set when not sending credentials.");

    clearCookies();

    var req = new XMLHttpRequest;
    req.open("GET", resourceURL("cross-origin-set-cookies.php"), true);
    req.withCredentials = false;
    req.send();
    req.onerror = function() {
        log("FAIL: Async xhr to set cookies.");
        endTesting();
    }
    req.onload = function() {
        log("PASS: Finished async xhr.");
        var response = checkForCookie();
        log(!response.match(/WK\-xhr\-cookie\-storage: MySpecialValue/) ? "PASS: No cookies set." : ("FAIL: " + response));
        testSyncCookiesWithCredentials();
    }
}

function testSyncCookiesWithCredentials()
{
    log("Cross-origin XMLHttpRequest (sync), testing that cookies are set when sending credentials.");

    clearCookies();

    var req = new XMLHttpRequest;
    req.open("GET", resourceURL("cross-origin-set-cookies.php"), false);
    req.withCredentials = true;
    req.send();
    log("PASS: Finished sync xhr.");

    var response = checkForCookie();
    log(response.match(/WK\-xhr\-cookie\-storage: MySpecialValue/) ? "PASS: Cookie set." : "FAIL: no cookie set.");
    log("DONE");
    endTesting();
}

if (window.testRunner)
    testSyncCookiesNoCredentials();
</script>
