<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
const callback = (event) => { };

function addListener(selector) {
    document.querySelector(selector).addEventListener("click", callback);
    TestPage.dispatchEventToFrontend("addListener");
}

function removeListener(selector) {
    document.querySelector(selector).removeEventListener("click", callback);
    TestPage.dispatchEventToFrontend("removeListener");
}

function test() {
    let parentNode = null;
    let childNode = null;
    let siblingNode = null;

    async function addListener(node) {
        let promise = new WI.WrappedPromise;
        let listener = node.addEventListener(WI.DOMNode.Event.EventListenersChanged, (event) => {
            if (!promise.settled)
                promise.resolve(true);
        });
        InspectorTest.singleFireEventListener("addListener", (event) => {
            node.removeEventListener(WI.DOMNode.Event.EventListenersChanged, listener);

            if (!promise.settled)
                promise.resolve(false);
        });

        let selector = node.escapedIdSelector;
        InspectorTest.log(`Adding listener to ${selector}...`);
        await InspectorTest.evaluateInPage(`addListener("${selector}")`);

        return promise.promise;
    }

    async function removeListener(node) {
        let promise = new WI.WrappedPromise;
        let listener = node.addEventListener(WI.DOMNode.Event.EventListenersChanged, (event) => {
            if (!promise.settled)
                promise.resolve(true);
        });
        InspectorTest.singleFireEventListener("removeListener", (event) => {
            node.removeEventListener(WI.DOMNode.Event.EventListenersChanged, listener);

            if (!promise.settled)
                promise.resolve(false);
        });

        let selector = node.escapedIdSelector;
        InspectorTest.log(`Removing listener from ${selector}...`);
        await InspectorTest.evaluateInPage(`removeListener("${selector}")`);

        return promise.promise;
    }

    async function checkTestEventListener(node, expected) {
        let {listeners} = await DOMAgent.getEventListenersForNode(node.id);
        listeners = listeners.map((listener) => listener.type);

        let selector = node.escapedIdSelector;
        if (expected)
            InspectorTest.expectThat(listeners.includes("click"), `There should be an event listener for ${selector}.`);
        else
            InspectorTest.expectFalse(listeners.includes("click"), `There should not be an event listener for ${selector}.`);
    }

    let suite = InspectorTest.createAsyncSuite("DOM.eventListeners");

    suite.addTestCase({
        name: "DOM.eventListeners.InspectedNode",
        description: "Test that event listener add/remove events for the inspected node are sent to the frontend.",
        async test() {
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectThat(await addListener(childNode), "Adding an event listener to the inspected node should notify the frontend.");
            await checkTestEventListener(childNode, true);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectThat(await removeListener(childNode), "Removing an event listener from the inspected node should notify the frontend.");
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);
        },
    });

    suite.addTestCase({
        name: "DOM.eventListeners.InspectedNode.ancestor",
        description: "Test that event listener add/remove events for ancestors of the inspected node are sent to the frontend.",
        async test() {
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectThat(await addListener(parentNode), "Adding an event listener to an ancestor of the inspected node should notify the frontend.");
            await checkTestEventListener(childNode, true);
            await checkTestEventListener(parentNode, true);

            InspectorTest.expectThat(await removeListener(parentNode), "Removing an event listener from an ancestor of the inspected node should notify the frontend.");
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);
        },
    });

    suite.addTestCase({
        name: "DOM.eventListeners.NotInspectedNode",
        description: "Test that event listener add/remove events for nodes other than the inspected node are not sent to the frontend.",
        async test() {
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectFalse(await addListener(siblingNode), "Adding an event listener to a node other than the inspected node should not notify the frontend.");
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectFalse(await removeListener(siblingNode), "Removing an event listener from a node other than the inspected node should not notify the frontend.");
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);
        },
    });

    suite.addTestCase({
        name: "DOM.eventListeners.SubsequentBeforeGet",
        description: "Test that subsequent event listener add/remove events are not sent to the frontend if the frontend hasn't requested the new list since the last update.",
        async test() {
            await checkTestEventListener(childNode, false);
            await checkTestEventListener(parentNode, false);

            InspectorTest.expectThat(await addListener(childNode), "Adding an event listener to the inspected node should notify the frontend.");
            InspectorTest.expectFalse(await addListener(parentNode), "Adding an event listener to an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.");

            InspectorTest.log("Requesting event listeners...");
            await checkTestEventListener(childNode, true);
            await checkTestEventListener(parentNode, true);

            InspectorTest.expectThat(await removeListener(childNode), "Removing an event listener from the inspected node should notify the frontend.");
            InspectorTest.expectFalse(await removeListener(parentNode), "Removing an event listener from an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.");
        },
    });

    WI.domManager.requestDocument(async (documentNode) => {
        let [parentNodeId, childNodeId, siblingNodeId] = await Promise.all([
            documentNode.querySelector("#parent"),
            documentNode.querySelector("#child"),
            documentNode.querySelector("#sibling"),
        ]);

        parentNode = WI.domManager.nodeForId(parentNodeId);
        childNode = WI.domManager.nodeForId(childNodeId);
        siblingNode = WI.domManager.nodeForId(siblingNodeId);

        InspectorTest.assert(childNode !== WI.domManager.inspectedNode);
        InspectorTest.log(`Changing inspected node to ${childNode.escapedIdSelector}...`);
        await Promise.all([
            WI.domManager.awaitEvent(WI.DOMManager.Event.InspectedNodeChanged),
            WI.domManager.setInspectedNode(childNode),
        ]);
        InspectorTest.assert(childNode === WI.domManager.inspectedNode);

        suite.runTestCasesAndFinish();
    });
}
</script>
</head>
<body onload="runTest()">
    <p>Testing that event listener add/remove events are only fired for the inspected node and its ancestors.</p>
    <div id="parent">
        <div id="child"></div>
    </div>
    <div id="sibling"></div>
</body>
</html>
