<!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
    //   - inspector internal scripts InjectedScriptSource.js CommandLineAPIModuleSource.js

    let foundExternalScript = false;
    let foundInlineScriptTagScript = false;
    let foundInlineAttributeEventListenerScript = false;
    let foundEvalScript = false;
    let foundInjectedScriptSourceScript = false;
    let foundCommandLineAPISourceScript = 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 >= 100; // Estimate of <body> below.
    }

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

    function isInjectedScriptSourceScript(params) {
        return params.sourceURL.startsWith("__InjectedScript_") && params.sourceURL.endsWith(".js");
    }

    function isCommandLineAPISourceScript(params) {
        return params.sourceURL.indexOf("CommandLineAPIModuleSource") !== -1;
    }

    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 if (!foundCommandLineAPISourceScript && isCommandLineAPISourceScript(params))
                        foundCommandLineAPISourceScript = true;
                    else if (!foundInjectedScriptSourceScript && isInjectedScriptSourceScript(params))
                        foundInjectedScriptSourceScript = 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(foundInjectedScriptSourceScript, "Should find Inspector InjectedScriptSource Script.");
                ProtocolTest.expectThat(foundCommandLineAPISourceScript, "Should find Inspector CommandLineAPISource 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>
