<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="../debugger/resources/breakpoint-options-utilities.js"></script>
<script src="../debugger/resources/log-active-stack-trace.js"></script>
<script src="resources/dom-breakpoint-utilities.js"></script>
<script>
function testNodeRemovedAncestor() {
    let node = document.getElementById("node-removed-ancestor-test");
    let parent = node.parentNode;
    let grandparent = parent.parentNode;
    parent.remove();
    grandparent.appendChild(parent);
}

function test()
{
    let suite = InspectorTest.createAsyncSuite("DOMBreakpoint.NodeRemoved");

    suite.addTestCase({
        name: `DOMBreakpoint.NodeRemoved.Ancestor.BreakpointEnabled`,
        description: "Check that debugger pauses for breakpoint type.",
        async test() {
            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");

            let breakpoint = await InspectorTest.DOMBreakpoint.createBreakpoint(node, WI.DOMBreakpoint.Type.NodeRemoved);

            let paused = false;
            let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                paused = true;

                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.");

                let pauseData = targetData.pauseData;
                InspectorTest.expectEqual(pauseData.type, breakpoint.type, `Pause type should be '${breakpoint.type}'.`);
                InspectorTest.expectEqual(pauseData.nodeId, breakpoint.domNode.id, "Pause nodeId should be expected value.");
                InspectorTest.expectEqual(pauseData.targetNodeId, node.parentNode.id, "Pause targetNodeId should be expected value.");
                InspectorTest.assert(!("insertion" in pauseData), "Should not have 'insertion'.");

                logActiveStackTrace();
                WI.debuggerManager.resume();
            });

            await InspectorTest.evaluateInPage(`testNodeRemovedAncestor()`);

            InspectorTest.assert(!breakpoint.domNode, "Should not have domNode.");

            InspectorTest.assert(paused, "Should pause.");
            WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
        },
        teardown: InspectorTest.DOMBreakpoint.teardown,
    });

    suite.addTestCase({
        name: `DOMBreakpoint.NodeRemoved.Ancestor.BreakpointDisabled`,
        description: "Check that debugger does not pause for disabled breakpoint.",
        async test() {
            let paused = false;
            let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                paused = true;

                WI.debuggerManager.resume();
            });

            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");

            let breakpoint = await InspectorTest.DOMBreakpoint.createBreakpoint(node, WI.DOMBreakpoint.Type.NodeRemoved);

            InspectorTest.log("Disabling breakpoint...");
            breakpoint.disabled = true;

            InspectorTest.assert(breakpoint.domNode === node, "Should have domNode.");

            InspectorTest.log("Triggering breakpoint...");
            await InspectorTest.evaluateInPage(`testNodeRemovedAncestor()`);

            InspectorTest.assert(!breakpoint.domNode, "Should not have domNode.");

            InspectorTest.expectFalse(paused, "Should not pause for disabled breakpoint.");
            WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
        },
        teardown: InspectorTest.DOMBreakpoint.teardown,
    });

    suite.addTestCase({
        name: `DOMBreakpoint.NodeRemoved.Ancestor.DebuggerDisabled`,
        description: "Check that debugger does not pause when the debugger is disabled.",
        async test() {
            let paused = false;
            let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                paused = true;

                WI.debuggerManager.resume();
            });

            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");

            let breakpoint = await InspectorTest.DOMBreakpoint.createBreakpoint(node, WI.DOMBreakpoint.Type.NodeRemoved);

            InspectorTest.log("Disabling all breakpoints...");
            await DebuggerAgent.setBreakpointsActive(false);

            InspectorTest.log("Triggering breakpoint...");
            await InspectorTest.evaluateInPage(`testNodeRemovedAncestor()`);

            InspectorTest.assert(!breakpoint.domNode, "Should not have domNode.");

            InspectorTest.log("Enabling all breakpoints...");
            await DebuggerAgent.setBreakpointsActive(true);

            InspectorTest.expectFalse(paused, "Should not pause when all breakpoints disabled.");
            WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
        },
        teardown: InspectorTest.DOMBreakpoint.teardown,
    });

    suite.addTestCase({
        name: `DOMBreakpoint.NodeRemoved.Ancestor.RemoveBreakpoint`,
        description: "Check that debugger does not pause for removed breakpoint.",
        async test() {
            let paused = false;
            let pausedListener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, (event) => {
                paused = true;

                WI.debuggerManager.resume();
            });

            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");

            let breakpoint = await InspectorTest.DOMBreakpoint.createBreakpoint(node, WI.DOMBreakpoint.Type.NodeRemoved);

            InspectorTest.log("Removing breakpoint...");
            WI.domDebuggerManager.removeDOMBreakpoint(breakpoint);

            InspectorTest.assert(!breakpoint.domNode, "Should not have domNode.");

            InspectorTest.log("Triggering breakpoint...");
            await InspectorTest.evaluateInPage(`testNodeRemovedAncestor()`);

            InspectorTest.assert(!breakpoint.domNode, "Should not have domNode.");

            InspectorTest.expectFalse(paused, "Should not pause for removed breakpoint.");
            WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.Paused, pausedListener);
        },
        teardown: InspectorTest.DOMBreakpoint.teardown,
    });

    InspectorTest.BreakpointOptions.addTestCases(suite, {
        testCaseNamePrefix: "Ancestor.",
        async createBreakpoint() {
            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");
            return InspectorTest.DOMBreakpoint.createBreakpoint(node, WI.DOMBreakpoint.Type.NodeRemoved);
        },
        async triggerBreakpoint(breakpoint) {
            let node = await InspectorTest.DOMBreakpoint.awaitQuerySelector("#node-removed-ancestor-test");
            InspectorTest.assert(breakpoint.domNode === node, "Should have domNode.");
            return InspectorTest.evaluateInPage(`testNodeRemovedAncestor()`);
        },
        skip: {
            ignoreCount: true,
        },
    });

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