<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.domManager.requestDocument(function(documentNode) {
        documentNode.querySelector("#x", function(nodeId) {
            testDOMNode = WI.domManager.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.domManager.addEventListener(WI.DOMManager.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.domManager.addEventListener(WI.DOMManager.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>
