<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test()
{
    const color = undefined;
    const outlineColor = undefined;

    function getHighlightRects(callback) {
        InspectorTest.evaluateInPage("JSON.stringify(Array.from(window.internals.inspectorHighlightRects()))", (error, value, wasThrown) => {
            InspectorTest.assert(!error, "Unexpected error dumping highlight: " + error);
            InspectorTest.assert(!wasThrown, "Unexpected exception when dumping highlight.");
            callback(JSON.parse(value));
        });
    }

    function dumpHighlightRects(callback) {
        getHighlightRects((highlightRects) => {
            InspectorTest.expectThat(highlightRects.length === 1, "Should be one highlight rect.");
            InspectorTest.log("Highlight Rect: " + JSON.stringify(highlightRects[0]));
            callback();
        });
    }

    function getHighlight(callback) {
        InspectorTest.evaluateInPage("window.internals.inspectorHighlightObject()", (error, value, wasThrown) => {
            InspectorTest.assert(!error, "Unexpected error dumping highlight: " + error);
            InspectorTest.assert(!wasThrown, "Unexpected exception when dumping highlight.");
            callback(JSON.parse(value));
        });
    }

    function dumpHighlight(callback) {
        getHighlight((highlightObjectPayload) => {
            InspectorTest.expectThat(highlightObjectPayload.length === 1, "Should be one highlighted node.");
            InspectorTest.log("Highlighted Element Data: " + JSON.stringify(highlightObjectPayload[0].elementData));
            callback();
        });
    }

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

    function addHideHighlightTestCase() {
        suite.addTestCase({
            name: "HideHighlight",
            description: "Calling hideHighlight should hide the highlight.",
            test(resolve, reject) {
                DOMAgent.hideHighlight(() => {
                    getHighlightRects((highlightRects) => {
                        InspectorTest.expectThat(highlightRects.length === 0, "Should be no highlight.");
                        resolve();
                    });
                });
            }
        });
    }

    suite.addTestCase({
        name: "CheckEmptyHighlight",
        description: "Should not be a highlight yet.",
        test(resolve, reject) {
            getHighlightRects((highlightRects) => {
                InspectorTest.expectThat(highlightRects.length === 0, "Should not be a highlight yet.");
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "HighlightRect",
        description: "Call highlightRect to create a highlight.",
        test(resolve, reject) {
            let rect = new WI.Rect(0, 0, 100, 100);
            DOMAgent.highlightRect(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height, color, outlineColor, (error) => {
                dumpHighlightRects(resolve);
            });
        }
    });

    addHideHighlightTestCase();

    suite.addTestCase({
        name: "HighlightQuad",
        description: "Call highlightQuad to create a highlight.",
        test(resolve, reject) {
            let quad = new WI.Quad([100, 100, 150, 150, 100, 200, 50, 150]);
            DOMAgent.highlightQuad(quad.toProtocol(), color, outlineColor, (error) => {
                dumpHighlightRects(resolve);
            });
        }
    });

    addHideHighlightTestCase();

    suite.addTestCase({
        name: "HighlightNode",
        description: "Call highlightNode to create a highlight.",
        test(resolve, reject) {
            const highlightConfig = {
                showInfo: true,
                contentColor: {r: 255, g: 255, b: 255},
                paddingColor: {r: 255, g: 255, b: 255},
                borderColor: {r: 255, g: 255, b: 255},
                marginColor: {r: 255, g: 255, b: 255},
            };

            WI.domTreeManager.requestDocument((documentNode) => {
                WI.domTreeManager.querySelector(documentNode.id, "#target", (nodeId) => {
                    DOMAgent.highlightNode(highlightConfig, nodeId, (error) => {
                        InspectorTest.assert(!error, "Should not have an error.");
                        dumpHighlight(resolve);
                    });
                });
            });
        }
    });

    addHideHighlightTestCase();
    addHideHighlightTestCase(); // Test that a duplicate hideHighlight is not problematic.

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p id="target" style="width:500px; height:100px">Tests for the DOM.hideHighlight command.</p>
</body>
</html>
