<html>
<head>
    <script src="resources/cross-frame-access.js"></script>
    <script>
        window.onload = function()
        {
            if (window.testRunner) {
                testRunner.dumpAsText();
                testRunner.waitUntilDone();
            }

            if (window.testRunner) {
                setTimeout(pollForTest, 1);
            } else {
                log("To run the test, click the button below when the frame finishes loading.");
                var button = document.createElement("button");
                button.appendChild(document.createTextNode("Run Test"));
                button.onclick = runTest;
                document.body.appendChild(button);
            }
        }
    
        pollForTest = function()
        {
            if (!testRunner.globalFlag) {
                setTimeout(pollForTest, 1);
                return;
            }
            runTest();
            testRunner.notifyDone();
        }

        runTest = function()
        {
            // Test enumerating the Window object
            var b_win = document.getElementsByTagName("iframe")[0].contentWindow;
            try {
                for (var k in b_win) {
                    if (k == "customWindowProperty") {
                        log("FAIL: Cross frame access by enumerating the window object was allowed.");
                        return;
                    }
                }
            } catch (e) {
            }
            log("PASS: Cross frame access by enumerating the window object was denied.");

            var b_winKeys = Object.keys(b_win);
            if (b_winKeys.indexOf("customWindowProperty") != -1) { 
                log("FAIL: Cross frame access by getting the keys of the window object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the keys of the window object was denied.");

            var b_winPropertyNames = Object.getOwnPropertyNames(b_win);
            if (b_winPropertyNames.indexOf("customWindowProperty") != -1) {
                log("FAIL: Cross frame access by getting the property names of the window object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the property names of the window object was denied.");

            // Test enumerating the History object
            var b_win_history = b_win.history;
            try {
                for (var k in b_win_history) {
                    if (k == "customHistoryProperty") {
                        log("FAIL: Cross frame access by enumerating the History object was allowed.");
                        return;
                    }
                }
            } catch (e) {
            }
            log("PASS: Cross frame access by enumerating the History object was denied.");

            var b_winHistoryKeys = Object.keys(b_win_history);
            if (b_winHistoryKeys.indexOf("customHistoryProperty") != -1) { 
                log("FAIL: Cross frame access by getting the keys of the History object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the keys of the History object was denied.");

            var b_winHistoryPropertyNames = Object.getOwnPropertyNames(b_win_history);
            if (b_winHistoryPropertyNames.indexOf("customHistoryProperty") != -1) {
                log("FAIL: Cross frame access by getting the property names of the History object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the property names of the History object was denied.");

            // Test enumerating the Location object
            var b_win_location = b_win.location;
            try {
                for (var k in b_win_location) {
                    if (k == "customLocationProperty") {
                        log("FAIL: Cross frame access by enumerating the Location object was allowed.");
                        return;
                    }
                }
            } catch (e) {
            }
            log("PASS: Cross frame access by enumerating the Location object was denied.");

            var b_winLocationKeys = Object.keys(b_win_location);
            if (b_winLocationKeys.indexOf("customLocationProperty") != -1) { 
                log("FAIL: Cross frame access by getting the keys of the Location object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the keys of the Location object was denied.");

            var b_winLocationPropertyNames = Object.getOwnPropertyNames(b_win_location);
            if (b_winLocationPropertyNames.indexOf("customLocationProperty") != -1) {
                log("FAIL: Cross frame access by getting the property names of the Location object was allowed.");
                return;
            }
            log("PASS: Cross frame access by getting the property names of the Location object was denied.");
        }
    </script>
</head>
<body>
    <p>This tests that variable names can't be enumerated cross domain (see http://bugs.webkit.org/show_bug.cgi?id=16387)</p>
    <iframe src="http://localhost:8000/security/resources/cross-frame-iframe-for-enumeration-test.html"></iframe>
    <pre id="console"></pre>
</body>
</html>
