<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/protocol-test.js"></script>
<script>
// Create a named eval.
eval("//# sourceURL=eval.js\nfunction foo() { }");

function test()
{
    let suite = ProtocolTest.createAsyncSuite("Debugger.scriptParsed.enable");

    // Because InspectorTest output causes scripts to be parsed
    // this test only checks the scripts the frontend is notified
    // of when enabling the Debugger domain.
    //
    // Scripts we expect to see (in an undefined order)
    //   - external <script> protocol-test.js
    //   - inline <script> (this) starting on line 5
    //   - inline body onload event listener attribute on <body> line below
    //   - eval source above on line 7

    let foundExternalScript = false;
    let foundInlineScriptTagScript = false;
    let foundInlineAttributeEventListenerScript = false;
    let foundEvalScript = false;
    let foundUnexpectedScript = false;

    function isExternalScript(params) {
        return /inspector\/resources\/protocol-test\.js/.test(params.url);
    }

    function isInlineScript(params) {
        return /inspector\/debugger\/scriptParsed\.html$/.test(params.url);
    }

    function isInlineScriptTagScript(params) {
        return isInlineScript(params) && params.startLine === 4;
    }

    function isInlineAttributeEventListenerScript(params) {
        return isInlineScript(params) && params.startLine >= 99; // Estimate of <body> below.
    }

    function isEvalScript(params) {
        return params.sourceURL === "eval.js";
    }

    suite.addTestCase({
        name: "EnableDebuggerDomainAndCheckInitialScripts",
        test(resolve, reject) {

            let initialScriptParsedMessages = [];
            let receivingInitialScripts = true;
            InspectorProtocol.sendCommand("Debugger.enable", {}, function() {
                receivingInitialScripts = false;

                ProtocolTest.log("Debugger Enabled - Initial Scripts Received");
                ProtocolTest.expectThat(initialScriptParsedMessages.length > 0, "Should have received some scriptParsed messages.");

                for (let messageObject of initialScriptParsedMessages) {
                    let params = messageObject.params;
                    if (!foundExternalScript && isExternalScript(params))
                        foundExternalScript = true;
                    else if (!foundInlineScriptTagScript && isInlineScriptTagScript(params))
                        foundInlineScriptTagScript = true;
                    else if (!foundInlineAttributeEventListenerScript && isInlineAttributeEventListenerScript(params))
                        foundInlineAttributeEventListenerScript = true;
                    else if (!foundEvalScript && isEvalScript(params))
                        foundEvalScript = true;
                    else {
                        ProtocolTest.log("UNEXPECTED SCRIPT: " + JSON.stringify(messageObject));
                        foundUnexpectedScript = true;
                    }
                }

                ProtocolTest.expectThat(foundExternalScript, "Should find External Script.");
                ProtocolTest.expectThat(foundInlineScriptTagScript, "Should find Inline Script Tag Script.");
                ProtocolTest.expectThat(foundInlineAttributeEventListenerScript, "Should find Inline Attribute Event Listener Script.");
                ProtocolTest.expectThat(foundEvalScript, "Should find Eval Script.");
                ProtocolTest.expectThat(!foundUnexpectedScript, "Should not receive any unexpected scripts.");

                resolve();
            });

            InspectorProtocol.eventHandler["Debugger.scriptParsed"] = function(messageObject) {
                // Ignore non-initial load scripts.
                if (!receivingInitialScripts)
                    return;

                initialScriptParsedMessages.push(messageObject);
            };
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()"> <!-- This line number is important -->
<p>Tests for the Debugger.scriptParsed messages the frontend receives when enabling the Debugger domain.</p>
</body>
</html>
