<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test() {

    var testDOMNode = null;
    var insertedOrRemovedDOMNode = null;
    var previousInsertedDOMNode = null;

    var steps = [
        {
            name: "Add :before",
            action: function() {
                InspectorTest.evaluateInPage("document.getElementById('x').classList.add('b')");
            }
        },
        {
            name: "Verify :before was added",
            action: function() {
                InspectorTest.expectThat(testDOMNode.hasPseudoElements(), "#x DOMNode has pseudo elements");
                InspectorTest.expectThat(testDOMNode.pseudoElements().size === 1, "DOMNode has 1 pseudo elements");
                InspectorTest.expectThat(testDOMNode.beforePseudoElement(), "DOMNode has a before pseudo element");
                InspectorTest.expectThat(!testDOMNode.afterPseudoElement(), "DOMNode does not have an after pseudo element");

                InspectorTest.expectThat(insertedOrRemovedDOMNode === testDOMNode.beforePseudoElement(), "New DOMNode is the beforePseudoElement");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.parentNode === testDOMNode, "New DOMNode is a child of #x");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.pseudoType() === WI.DOMNode.PseudoElementType.Before, "New DOMNode is a before pseudo element");

                previousInsertedDOMNode = insertedOrRemovedDOMNode;
                next();
            }
        },
        {
            name: "Remove :before",
            action: function() {
                InspectorTest.evaluateInPage("document.getElementById('x').classList.remove('b')");
            }
        },
        {
            name: "Verify :before was removed",
            action: function() {
                InspectorTest.expectThat(!testDOMNode.hasPseudoElements(), "#x DOMNode has no pseudo elements");
                InspectorTest.assert(testDOMNode.pseudoElements().size === 0);
                InspectorTest.assert(!testDOMNode.beforePseudoElement());
                InspectorTest.assert(!testDOMNode.afterPseudoElement());

                InspectorTest.expectThat(insertedOrRemovedDOMNode === previousInsertedDOMNode, "Removed DOMNode was the before pseudo element");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.parentNode === null, "Removed DOMNode has no parent");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.pseudoType() === WI.DOMNode.PseudoElementType.Before, "Removed DOMNode was a before pseudo element");

                previousInsertedDOMNode = null;
                next();
            }
        },
        {
            name: "Add :after",
            action: function() {
                InspectorTest.evaluateInPage("document.getElementById('x').classList.add('a')");
            }
        },
        {
            name: "Verify :after was added",
            action: function() {
                InspectorTest.expectThat(testDOMNode.hasPseudoElements(), "#x DOMNode has pseudo elements");
                InspectorTest.expectThat(testDOMNode.pseudoElements().size === 1, "DOMNode has 1 pseudo elements");
                InspectorTest.expectThat(!testDOMNode.beforePseudoElement(), "DOMNode does not have a before pseudo element");
                InspectorTest.expectThat(testDOMNode.afterPseudoElement(), "DOMNode has an after pseudo element");

                InspectorTest.expectThat(insertedOrRemovedDOMNode === testDOMNode.afterPseudoElement(), "New DOMNode is the afterPseudoElement");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.parentNode === testDOMNode, "New DOMNode is a child of #x");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.pseudoType() === WI.DOMNode.PseudoElementType.After, "New DOMNode is an after pseudo element");

                previousInsertedDOMNode = insertedOrRemovedDOMNode;
                next();
            }
        },
        {
            name: "Remove :after",
            action: function() {
                InspectorTest.evaluateInPage("document.getElementById('x').classList.remove('a')");
            }
        },
        {
            name: "Verify :after was removed",
            action: function() {
                InspectorTest.expectThat(!testDOMNode.hasPseudoElements(), "#x DOMNode has no pseudo elements");
                InspectorTest.assert(testDOMNode.pseudoElements().size === 0);
                InspectorTest.assert(!testDOMNode.beforePseudoElement());
                InspectorTest.assert(!testDOMNode.afterPseudoElement());

                InspectorTest.expectThat(insertedOrRemovedDOMNode === previousInsertedDOMNode, "Removed DOMNode was the after pseudo element");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.parentNode === null, "Removed DOMNode has no parent");
                InspectorTest.expectThat(insertedOrRemovedDOMNode.pseudoType() === WI.DOMNode.PseudoElementType.After, "Removed DOMNode was an after pseudo element");

                previousInsertedDOMNode = null;
                next();
            }
        },
    ];

    function next()
    {
        var step = steps.shift();
        if (step) {
            InspectorTest.log("");
            InspectorTest.log(step.name);
            step.action();
            return;
        }
        InspectorTest.completeTest();
    }

    WI.domTreeManager.requestDocument(function(documentNode) {
        WI.domTreeManager.querySelector(documentNode.id, "#x", function(nodeId) {
            testDOMNode = WI.domTreeManager.nodeForId(nodeId);
            InspectorTest.log("");
            InspectorTest.expectThat(testDOMNode, "Got DOMNode for #x");
            InspectorTest.assert(!testDOMNode.pseudoType());
            InspectorTest.expectThat(!testDOMNode.hasPseudoElements(), "DOMNode has no pseudo elements");
            InspectorTest.assert(testDOMNode.pseudoElements().size === 0);
            InspectorTest.assert(!testDOMNode.beforePseudoElement());
            InspectorTest.assert(!testDOMNode.afterPseudoElement());
            next();
        });
    });

    WI.domTreeManager.addEventListener(WI.DOMTreeManager.Event.NodeInserted, function(event) {
        // Test logging will add nodes to the test page. Ignore any elements added that are not children of our test node.
        if (event.data.parent !== testDOMNode)
            return;

        InspectorTest.log("EVENT: NodeInserted");
        insertedOrRemovedDOMNode = event.data.node;
        next();
    });

    WI.domTreeManager.addEventListener(WI.DOMTreeManager.Event.NodeRemoved, function(event) {
        InspectorTest.log("EVENT: NodeRemoved");
        insertedOrRemovedDOMNode = event.data.node;
        next();
    });
}
</script>
</head>
<body onload="runTest()">
    <p>Test for dynamic DOMNode pseudo element support, pseudo elements getting added and removed dynamically.</p>

    <style>
    .b:before { content: "before"; }
    .a:after { content: "after"; }
    </style>

    <div id="x">TEST ELEMENT</div>
</body>
</html>
