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

function insertBeforeFirst()
{
    var container = document.getElementById("container");
    var child = document.createElement("div");
    child.setAttribute("id", "child-before");
    container.insertBefore(child, container.firstChild);
}

function insertNode()
{
    var container = document.getElementById("container");
    var child2 = document.getElementById("child2");
    var child = document.createElement("div");
    child.setAttribute("id", "child-middle");
    container.insertBefore(child, child2);
}

function appendChild()
{
    var container = document.getElementById("container");
    var child = document.createElement("div");
    child.setAttribute("id", "child-after");
    container.appendChild(child);
}

function appendChildWithText()
{
    var container = document.getElementById("container");
    var child = document.createElement("div");
    child.style.display = "none";
    child.innerText = "Text";
    child.setAttribute("id", "child-with-text");
    container.appendChild(child);
}

function insertFirstTextNode()
{
    var child3 = document.getElementById("child3");
    child3.innerText = "First text";
}

function test()
{
    var containerNode;

    InspectorTest.runTestSuite([
        function testDumpInitial(next)
        {
            function callback(node)
            {
                containerNode = InspectorTest.expandedNodeWithId("container");

                InspectorTest.addResult("========= Original ========");
                InspectorTest.dumpElementsTree(containerNode);
                next();
            }
            InspectorTest.expandElementsTree(callback);
        },

        function testInsertBefore(next)
        {
            function callback()
            {
                InspectorTest.addResult("===== Inserted before =====");
                InspectorTest.dumpElementsTree(containerNode);
                next();
            }
            InspectorTest.evaluateInPage("insertBeforeFirst()", callback);
        },

        function testInsertMiddle(next)
        {
            function callback()
            {
                InspectorTest.addResult("===== Inserted middle =====");
                InspectorTest.dumpElementsTree(containerNode);
                next();
            }
            InspectorTest.evaluateInPage("insertNode()", callback);
        },

        function testAppend(next)
        {
            function callback()
            {
                InspectorTest.addResult("======== Appended =========");
                InspectorTest.dumpElementsTree(containerNode);
                next();
            }
            InspectorTest.evaluateInPage("appendChild()", callback);
        },

        function testAppendWithText(next)
        {
            function callback()
            {
                InspectorTest.addResult("======== Appended with text=========");
                InspectorTest.dumpElementsTree(containerNode);
                var newNode = InspectorTest.expandedNodeWithId("child-with-text");
                if (WebInspector.domAgent.nodeForId(newNode.firstChild.id))
                    InspectorTest.addResult("Success: child text is bound");
                else
                    InspectorTest.addResult("Failed: child text is not bound");
                next();
            }
            InspectorTest.evaluateInPage("appendChildWithText()", callback);
        },

        function testInsertFirstTextNode(next)
        {
            function callback()
            {
                InspectorTest.addResult("======== Inserted first text node =========");
                InspectorTest.expandElementsTree(callback2);
            }

            function callback2()
            {
                InspectorTest.dumpElementsTree(containerNode);
                var newNode = InspectorTest.expandedNodeWithId("child3");
                if (WebInspector.domAgent.nodeForId(newNode.firstChild.id))
                    InspectorTest.addResult("Success: child text is bound");
                else
                    InspectorTest.addResult("Failed: child text is not bound");
                next();
            }
            InspectorTest.evaluateInPage("insertFirstTextNode()", callback);
        }
    ]);
}

</script>
</head>

<body onload="runTest()">
<p>
Tests that elements panel updates dom tree structure upon node insertion.
</p>

<div id="container"><div id="child1"></div><div id="child2"></div><div id="child3"></div></div>

</body>
</html>
