<html>
<head>
<script src="../../http/tests/inspector/inspector-test.js"></script>
<script src="../../http/tests/inspector/debugger-test.js"></script>

<script>

function addErrorToConsole()
{
    console.error("test error message");
}

function methodForBreakpoint()
{
    alert("Hello world");
}

function test()
{
    WebInspector.showPanel("resources");
    InspectorTest.runDebuggerTestSuite([
        function testSetBreakpoint(next)
        {
            InspectorTest.showScriptSource("source-frame.html", didShowScriptSource);

            function didShowScriptSource(sourceFrame)
            {
                InspectorTest.addResult("Script source was shown.");
                InspectorTest.addSniffer(WebInspector.JavaScriptSourceFrame.prototype, "_addBreakpointDecoration", didAddBreakpoint);
                InspectorTest.setBreakpoint(sourceFrame, 14, "", true);
            }

            function didAddBreakpoint(lineNumber)
            {
                InspectorTest.addResult("Breakpoint added to source frame at line " + lineNumber);
                next();
            }
        },

        function testConsoleMessage(next)
        {
            InspectorTest.showScriptSource("source-frame.html", didShowScriptSource);

            var shownSourceFrame;
            function didShowScriptSource(sourceFrame)
            {
                InspectorTest.addResult("Script source was shown.");
                shownSourceFrame = sourceFrame;
                InspectorTest.addSniffer(WebInspector.SourceFrame.prototype, "addMessageToSource", didAddMessage);
                InspectorTest.addSniffer(WebInspector.SourceFrame.prototype, "clearMessages", clearMessages);
                InspectorTest.evaluateInPage("addErrorToConsole()");
            }

            function didAddMessage(lineNumber, message)
            {
                if (this !== shownSourceFrame)
                    return;
                InspectorTest.addResult("Message added to source frame: " + message.message);
                WebInspector.console.requestClearMessages();
            }

            function clearMessages()
            {
                if (this !== shownSourceFrame)
                    return;
                InspectorTest.addResult("Messages cleared in source frame.");
                next();
            }
        },

        function testShowResource(next)
        {
            WebInspector.showPanel("network");

            InspectorTest.addSniffer(WebInspector.SourceFrame.prototype, "show", didShowSourceFrame);

            WebInspector.resourceTreeModel.forAllResources(visit);
            function visit(resource)
            {
                if (resource.url.indexOf("debugger-test.js") !== -1) {
                    WebInspector.panels.resources.showResource(resource, 1);
                    return true;
                }
            }

            function didShowSourceFrame()
            {
                next();
            }
        }
    ]);
};

</script>

</head>

<body onload="runTest()">
<p>Tests that it's possible to set breakpoint in source frame, and that
source frame displays breakpoints and console errors.
</p>

</body>
</html>
