<html>
<head>
<script>
if (window.testRunner) {
    testRunner.dumpAsText();
    testRunner.dumpChildFramesAsText();
    testRunner.setHandlesAuthenticationChallenges(true);
    testRunner.setAuthenticationUsername("first");
    testRunner.setAuthenticationPassword("first-pw");
    testRunner.waitUntilDone();
}

function firstFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("second");
        testRunner.setAuthenticationPassword("second-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/protected-resource.py");
    frame.setAttribute("onload", "setTimeout(secondFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function secondFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("third");
        testRunner.setAuthenticationPassword("third-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/protected-resource.py");
    frame.setAttribute("onload", "setTimeout(thirdFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function thirdFrameLoaded()
{
    if (window.testRunner) {
        testRunner.setAuthenticationUsername("fourth");
        testRunner.setAuthenticationPassword("fourth-pw");
    }
    var frame = document.createElement("iframe");
    frame.setAttribute("src", "http://127.0.0.1:8000/loading/resources/othersubresources/protected-resource.py");
    frame.setAttribute("onload", "setTimeout(fourthFrameLoaded, 0)");
    document.body.appendChild(frame);
}

function fourthFrameLoaded()
{
    if (window.testRunner)
        testRunner.notifyDone();
}

function makeIFrame() {
    var iframe = document.createElement("iframe");
    iframe.setAttribute("onload", "setTimeout(firstFrameLoaded, 0)");
    iframe.src="resources/subresources/protected-resource.py";
    document.body.appendChild(iframe);
}

</script>
</head>
<body onload="setTimeout(makeIFrame, 0)">
This test makes sure that once an HTTP Basic Auth. protected path is authenticated once, urls that emanate from that path automatically have their credentials sent without a challenge.<br>
The first frame's path is /loading/resources/subresources/protected-resource.py, and we should get a challenge for it.<br>
It will be authorized with first/first-pw.<br>
The second frame's path is /loading/resources/protected-resource.py, and we should get a challenge for it, because it does not share a common subpath of the previously authorized resource.<br>
It will be authorized with second/second-pw.<br>
The third frame's path is also /loading/resources/protected-resource.py, and we should *not* get a challenge for it because we authorized to this path for the second frame.<br>
It will be authorized with second/second-pw.<br>
The fourth frame's path is /loading/resources/othersubresources/protected-resource.py, and we should *not* get a challenge for it, because it has a common subpath with the previously authorized second and third frames.<br>
It will be authorized with second/second-pw.<br>
</body>
</html>
