<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function load() {
    window.animation = document.body.animate([]);

    runTest();
}

function test()
{
    let suite = InspectorTest.createAsyncSuite("Animation.targetChanged");

    suite.addTestCase({
        name: "Animation.targetChanged.NewTarget",
        description: "Should return a valid object for the given animation identifier.",
        async test() {
            let animations = Array.from(WI.animationManager.animationCollection);
            InspectorTest.assert(animations.length === 1, "There should only be one animation.");

            let animation = animations[0];
            if (!animation) {
                throw `Missing animation.`;
                return;
            }

            InspectorTest.assert(animation.animationType === WI.Animation.Type.WebAnimation, "Animation should be a web animation.");

            let [oldTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectThat(oldTarget.node instanceof WI.DOMNode, "Animation effect should have a target element.");
            InspectorTest.expectNull(oldTarget.pseudoId, "Animation effect should not have a target pseudo-element.");

            InspectorTest.log("Changing target...\n");
            await Promise.all([
                animation.awaitEvent(WI.Animation.Event.TargetChanged),
                InspectorTest.evaluateInPage(`window.animation.effect.target = document.createElement("div")`),
            ]);

            let [newTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectThat(newTarget.node instanceof WI.DOMNode, "Animation effect should have a target element.");
            InspectorTest.expectNull(newTarget.pseudoId, "Animation effect should not have a target pseudo-element.");

            InspectorTest.expectNotEqual(newTarget, oldTarget, "Animation effect target should have changed.");
            InspectorTest.expectNotEqual(newTarget.node, oldTarget.node, "Animation effect target element should have changed.");
        },
    });

    suite.addTestCase({
        name: "Animation.targetChanged.NullTarget",
        description: "Should return a valid object for the given animation identifier.",
        async test() {
            let animations = Array.from(WI.animationManager.animationCollection);
            InspectorTest.assert(animations.length === 1, "There should only be one animation.");

            let animation = animations[0];
            if (!animation) {
                throw `Missing animation.`;
                return;
            }

            InspectorTest.assert(animation.animationType === WI.Animation.Type.WebAnimation, "Animation should be a web animation.");

            let [oldTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectThat(oldTarget.node instanceof WI.DOMNode, "Animation effect should have a target element.");
            InspectorTest.expectNull(oldTarget.pseudoId, "Animation effect should not have a target pseudo-element.");

            InspectorTest.log("Changing target...\n");
            await Promise.all([
                animation.awaitEvent(WI.Animation.Event.TargetChanged),
                InspectorTest.evaluateInPage(`window.animation.effect.target = null`),
            ]);

            let [newTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectNull(newTarget, "Animation effect should not have a target element.");

            InspectorTest.expectNotEqual(newTarget, oldTarget, "Animation effect target should have changed.");
        },
    });

    suite.addTestCase({
        name: "Animation.targetChanged.NewTargetWithPseudoId",
        description: "Should return a valid object for the given animation identifier.",
        async test() {
            let animations = Array.from(WI.animationManager.animationCollection);
            InspectorTest.assert(animations.length === 1, "There should only be one animation.");

            let animation = animations[0];
            if (!animation) {
                throw `Missing animation.`;
                return;
            }

            InspectorTest.assert(animation.animationType === WI.Animation.Type.WebAnimation, "Animation should be a web animation.");

            let [oldTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectNull(oldTarget, "Animation effect should not have a target.");

            InspectorTest.log("Changing target...\n");
            await Promise.all([
                animation.awaitEvent(WI.Animation.Event.TargetChanged),
                InspectorTest.evaluateInPage(`window.animation.effect.target = document.createElement("div")`),
            ]);

            let [newTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectThat(newTarget.node instanceof WI.DOMNode, "Animation effect should have a target element.");
            InspectorTest.expectNull(newTarget.pseudoId, "Animation effect should not have a target pseudo-element.");

            InspectorTest.log("Changing target again...\n");
            await Promise.all([
                animation.awaitEvent(WI.Animation.Event.TargetChanged),
                InspectorTest.evaluateInPage(`window.animation.effect.pseudoElement = "::before"`),
            ]);

            let [newestTarget] = await promisify((callback) => { animation.requestEffectTarget(callback); });
            InspectorTest.expectThat(newestTarget.node instanceof WI.DOMNode, "Animation effect should have a target element.");
            InspectorTest.expectEqual(newestTarget.pseudoId, "before", "Animation effect should have a target pseudo-element.");

            InspectorTest.expectNotEqual(newTarget, newestTarget, "Animation effect target should have changed.");
            InspectorTest.expectEqual(newTarget.node, newestTarget.node, "Animation effect target element should not have changed.");
        },
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="load()">
    <p>Tests for the Animation.targetChanged event.</p>
</body>
</html>
