<!DOCTYPE html>
<html>
<head>
    <title>Test Caching "max-age" For History Only</title>
</head>
<body>
    <p>
        This test checks that loading a subresource with "Cache-Control: max-age=0" is
        cached and reused in back navigation when the page is not in the page cache.
    </p>
    <p>
        We then test that loading the same subresource is refetched when used in
        non-stale loads such as refreshes or normal navigation.
    </p>
    <pre id="console"></pre>
    <script>
    // Asynchronous test because this requires a new window to perform multiple navigations.
    if (window.testRunner) {
        testRunner.dumpAsText();
        testRunner.waitUntilDone();
        testRunner.setCanOpenWindows();
    }

    // Values to check.
    var originalRandomNumber = 0;
    var backLoadRandomNumber = 0;
    var refreshRandomNumber  = 0;
    var nextLoadRandomNumber = 0;

    // Window we will be controlling.
    var target;

    // Pass messages between windows to control the navigation types.
    var pre = document.getElementById('console');
    window.addEventListener('message', function(event) {

        // First time, record the first number, and tell the target window to trigger a back navigation.
        if (!originalRandomNumber) {
            originalRandomNumber = event.data;
            target.postMessage('go-forward-and-back', '*');
            return;
        }

        // Second time, record the second number. It should be identical. Also tell the target window to reload.
        if (!backLoadRandomNumber) {
            backLoadRandomNumber = event.data;
            var wasCached = (backLoadRandomNumber === originalRandomNumber);
            if (wasCached)
                pre.appendChild(document.createTextNode('PASS - max-age subresource was cached and used for a back navigation\n'));
            else
                pre.appendChild(document.createTextNode('FAIL - max-age subresource should have been cached and used in a back navigation\n'));
            target.postMessage('reload', '*');
            return;
        }

        // Third time, record the third number. It should not match. Also tell the target window to navigate forward.
        if (!refreshRandomNumber) {
            refreshRandomNumber = event.data;
            var wasCached = (refreshRandomNumber === originalRandomNumber);
            if (wasCached)
                pre.appendChild(document.createTextNode('FAIL - max-age subresource should have been refetched with a reload\n'));
            else
                pre.appendChild(document.createTextNode('PASS - max-age subresource was refetched with a reload\n'));
            target.postMessage('next', '*');
            return;
        }

        // Fourth time, record the fourth number. It should not match any numbers so far.
        if (!nextLoadRandomNumber) {
            nextLoadRandomNumber = event.data;
            var wasCached = (nextLoadRandomNumber === originalRandomNumber || nextLoadRandomNumber === refreshRandomNumber);
            if (wasCached)
                pre.appendChild(document.createTextNode('FAIL - max-age subresource should have been refetched with a normal navigation\n'));
            else
                pre.appendChild(document.createTextNode('PASS - max-age subresource was refetched with a normal navigation\n'));
        }

        // Test completed.
        target.close();
        if (window.testRunner)
            window.testRunner.notifyDone();

    }, false);

    // Open the target window and it will begin to send us messages.
    target = window.open('https://127.0.0.1:8443/cache/resources/max-age-resource.html');
    </script>
</body>
</html>
