<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="../debugger/resources/log-active-stack-trace.js"></script>
<script>
function subtreeModifiedTest() {
    document.getElementById("subtree-modified-test").append(document.createElement("p"));
}

function attributeModifiedTest() {
    document.getElementById("attribute-modified-test").setAttribute("display", "none");
}

function nodeRemovedTest() {
    let node = document.getElementById("node-removed-test");
    let parent = node.parentNode;
    node.remove();
    parent.append(node);
}

function test()
{
    const subtreeModifiedTestId = "subtree-modified-test";
    const attributeModifiedTestId = "attribute-modified-test";
    const nodeRemovedTestId = "node-removed-test";
    const multipleBreakpointsTestId = "multiple-breakpoints-test";

    let debuggerPausedListener = null;

    let suite = InspectorTest.createAsyncSuite("DOMBreakpoints");

    function teardown(resolve) {
        let breakpoints = WI.domDebuggerManager.domBreakpoints;
        for (let breakpoint of breakpoints)
            WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);
        InspectorTest.assert(!WI.domDebuggerManager.domBreakpoints.length);

        WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, debuggerPausedListener);
        debuggerPausedListener = null;

        resolve();
    }

    function rejectOnPause() {
        return new Promise((resolve, reject) => {
            InspectorTest.assert(!debuggerPausedListener);
            debuggerPausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                WI.debuggerManager.resume();
                InspectorTest.fail("Should not pause.");
                reject();
            });
        });
    }

    function awaitEvaluateInPage(expression) {
        return new Promise((resolve, reject) => {
            InspectorTest.log("Wait for evaluate in page to return.");
            InspectorTest.evaluateInPage(expression, (error) => {
                if (error)
                    reject(error);

                resolve();
            });
        });
    }

    function awaitQuerySelector(selector) {
        return new Promise((resolve, reject) => {
            WI.domManager.requestDocument((documentNode) => {
                if (!documentNode) {
                    reject();
                    return;
                }

                WI.domManager.querySelector(documentNode.id, selector, (nodeId) => {
                    if (!nodeId) {
                        InspectorTest.fail("Selector returned no nodes.", selector);
                        reject();
                        return;
                    }

                    let node = WI.domManager.nodeForId(nodeId);
                    InspectorTest.assert(node, "Missing node for id.", nodeId);
                    if (!node) {
                        reject();
                        return;
                    }

                    resolve(node);
                });
            });
        });
    }

    function addBreakpointForElementIdentifier(elementIdentifier, type, disabled) {
        return new Promise((resolve, reject) => {
            awaitQuerySelector("#" + elementIdentifier)
            .then((node) => {
                WI.domDebuggerManager.awaitEvent(WI.DOMDebuggerManager.Event.DOMBreakpointAdded)
                .then((event) => {
                    let breakpoint = event.data.breakpoint;
                    InspectorTest.pass(`Added '${type}' breakpoint.`);
                    resolve(event);
                });

                WI.domDebuggerManager.addDOMBreakpoint(new WI.DOMBreakpoint(node, type, {disabled}));
            });
        });
    }

    function addTestsForBreakpointType({name, elementIdentifier, type, expression}) {
        suite.addTestCase({
            name: `DOMBreakpoints.${name}.BreakpointEnabled`,
            description: "Check that debugger pauses for breakpoint type.",
            teardown,
            test(resolve, reject) {
                addBreakpointForElementIdentifier(elementIdentifier, type)
                .then((event) => {
                    let breakpoint = event.data.breakpoint;
                    InspectorTest.expectEqual(breakpoint.type, type, "Breakpoint should have expected type.");

                    InspectorTest.log("Call DOM operation.");
                    InspectorTest.evaluateInPage(expression);
                    return WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Paused);
                })
                .then(() => {
                    let targetData = WI.debuggerManager.dataForTarget(WI.debuggerManager.activeCallFrame.target);
                    InspectorTest.log("PAUSED:");
                    InspectorTest.expectEqual(targetData.pauseReason, WI.DebuggerManager.PauseReason.DOM, "Pause reason should be DOM.");
                    logActiveStackTrace();

                    return WI.debuggerManager.resume();
                })
                .then(resolve, reject);
            }
        });

        suite.addTestCase({
            name: `DOMBreakpoints.${name}.BreakpointDisabled`,
            description: "Check that debugger does not pause for disabled breakpoint.",
            teardown,
            test(resolve, reject) {
                const disabled = true;
                addBreakpointForElementIdentifier(elementIdentifier, type, disabled)
                .then(() => Promise.race([awaitEvaluateInPage(expression), rejectOnPause()]))
                .then(() => {
                    InspectorTest.pass("Should not pause for disabled breakpoint.");
                    resolve();
                })
                .catch(reject);
            }
        });

        suite.addTestCase({
            name: `DOMBreakpoints.${name}.DebuggerDisabled`,
            description: "Check that debugger does not pause when the debugger is disabled.",
            teardown,
            test(resolve, reject) {
                addBreakpointForElementIdentifier(elementIdentifier, type)
                .then(() => DebuggerAgent.setBreakpointsActive(false))
                .then(() => Promise.race([awaitEvaluateInPage(expression), rejectOnPause()]))
                .then(() => DebuggerAgent.setBreakpointsActive(true))
                .then(() => {
                    InspectorTest.pass("Should not pause for disabled breakpoint.");
                    resolve();
                })
                .catch(reject);
            }
        });

        suite.addTestCase({
            name: `DOMBreakpoints.${name}.RemoveBreakpoint`,
            description: "Check that debugger does not pause for removed breakpoint.",
            teardown,
            test(resolve, reject) {
                addBreakpointForElementIdentifier(elementIdentifier, type)
                .then((event) => {
                    let promise = WI.domDebuggerManager.awaitEvent(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved);
                    let breakpoint = event.data.breakpoint;

                    InspectorTest.log("Remove breakpoint.");
                    WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);
                    return promise;
                })
                .then(() => Promise.race([awaitEvaluateInPage(expression), rejectOnPause()]))
                .then(() => {
                    InspectorTest.pass("Should not pause for removed breakpoint.");
                    resolve();
                })
                .catch(reject);
            }
        });
    }

    suite.addTestCase({
        name: "BasicBreakpoint",
        description: "Check that breakpoint is in a valid initial state.",
        teardown,
        test(resolve, reject) {
            addBreakpointForElementIdentifier(subtreeModifiedTestId, WI.DOMBreakpoint.Type.SubtreeModified)
            .then((event) => {
                let breakpoint = event.data.breakpoint;
                InspectorTest.expectFalse(breakpoint.disabled, "Breakpoint should not be disabled.");
                InspectorTest.expectThat(breakpoint.domNodeIdentifier, "Breakpoint should have node identifier.");

                InspectorTest.assert(WI.networkManager.mainFrame, "Missing main frame.");
                let documentURL = WI.networkManager.mainFrame.url;
                InspectorTest.expectEqual(breakpoint.url, documentURL, "Breakpoint URL should match document URL.");
            })
            .then(resolve, reject);
        }
    });

    addTestsForBreakpointType({
        name: "SubtreeModified",
        elementIdentifier: subtreeModifiedTestId,
        type: WI.DOMBreakpoint.Type.SubtreeModified,
        expression: "subtreeModifiedTest()",
    });

    addTestsForBreakpointType({
        name: "AttributeModified",
        elementIdentifier: attributeModifiedTestId,
        type: WI.DOMBreakpoint.Type.AttributeModified,
        expression: "attributeModifiedTest()",
    });

    addTestsForBreakpointType({
        name: "NodeRemoved",
        elementIdentifier: nodeRemovedTestId,
        type: WI.DOMBreakpoint.Type.NodeRemoved,
        expression: "nodeRemovedTest()",
    });

    suite.addTestCase({
        name: "RemoveAllBreakpointsForNode",
        description: "Check that debugger does not pause for removed breakpoints on node.",
        teardown,
        test(resolve, reject) {
            let breakpointTypes = Object.values(WI.DOMBreakpoint.Type);
            let breakpointPromises = breakpointTypes.map(type => addBreakpointForElementIdentifier(multipleBreakpointsTestId, type));

            Promise.all(breakpointPromises)
            .then((values) => {
                let breakpoints = values.map(event => event.data.breakpoint);
                if (!breakpoints.length) {
                    InspectorTest.fail("No breakpoints added.");
                    reject();
                    return;
                }

                let node = WI.domManager.nodeForId(breakpoints[0].domNodeIdentifier);
                if (!node) {
                    InspectorTest.fail("No DOM node associated with breakpoint.");
                    reject();
                    return;
                }

                let breakpointsRemoved = 0;

                function breakpointRemoved() {
                    if (++breakpointsRemoved === breakpoints.length) {
                        InspectorTest.pass(`Removed ${breakpointsRemoved} breakpoints.`);

                        let nodeBreakpoints = WI.domDebuggerManager.domBreakpointsForNode(node);
                        InspectorTest.expectThat(!nodeBreakpoints.length, "DOM node should have no breakpoints.");

                        WI.domDebuggerManager.removeEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, breakpointRemoved);
                        resolve();
                    }
                }

                WI.domDebuggerManager.addEventListener(WI.DOMDebuggerManager.Event.DOMBreakpointRemoved, breakpointRemoved);
                WI.domDebuggerManager.removeDOMBreakpointsForNode(node);
            })
            .then(resolve, reject);
        }
    });

    suite.addTestCase({
        name: "SetBreakpointWithInvalidNodeId",
        description: "Check that setting a breakpoint for a nonexistant node returns an error.",
        teardown,
        test(resolve, reject) {
            InspectorTest.log("Attempting to set breakpoint.");

            DOMDebuggerAgent.setDOMBreakpoint(0, WI.DOMBreakpoint.Type.SubtreeModified, (error) => {
                InspectorTest.log("Protocol result: " + error);
                InspectorTest.expectThat(error, "Protocol should return an error.")
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "SetBreakpointWithInvalidType",
        description: "Check that setting a breakpoint with an invalid type returns an error.",
        teardown,
        test(resolve, reject) {
            awaitQuerySelector("body")
            .then((node) => {
                InspectorTest.log("Attempting to set breakpoint.");

                DOMDebuggerAgent.setDOMBreakpoint(node.id, "custom-breakpoint-type", (error) => {
                    InspectorTest.log("Protocol result: " + error);
                    InspectorTest.expectThat(error, "Protocol should return an error.")
                    resolve();
                });
            });
        }
    });

    suite.addTestCase({
        name: "RemoveBreakpointWithInvalidNodeId",
        description: "Check that removing a breakpoint for a nonexistant node returns an error.",
        teardown,
        test(resolve, reject) {
            InspectorTest.log("Attempting to remove breakpoint.");

            DOMDebuggerAgent.removeDOMBreakpoint(0, WI.DOMBreakpoint.Type.SubtreeModified, (error) => {
                InspectorTest.log("Protocol result: " + error);
                InspectorTest.expectThat(error, "Protocol should return an error.")
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "RemoveBreakpointWithInvalidType",
        description: "Check that removing a breakpoint with an invalid type returns an error.",
        teardown,
        test(resolve, reject) {
            awaitQuerySelector("body")
            .then((node) => {
                InspectorTest.log("Attempting to remove breakpoint.");

                DOMDebuggerAgent.removeDOMBreakpoint(node.id, "custom-breakpoint-type", (error) => {
                    InspectorTest.log("Protocol result: " + error);
                    InspectorTest.expectThat(error, "Protocol should return an error.")
                    resolve();
                });
            });
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for DOM breakpoints.</p>
<div id="test-container" style="display: none">
    <div id="subtree-modified-test"></div>
    <div id="attribute-modified-test"></div>
    <div id="node-removed-test"></div>
    <div id="multiple-breakpoints-test"></div>
</div>
</body>
</html>
