<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function load() {
    window.onscreenCanvas = document.getElementById("onscreen").getContext("2d");
    window.offscreenCanvas = document.createElement("canvas").getContext("2d");
    window.cssCanvas = document.getCSSCanvasContext("2d", "css", 10, 10);

    runTest();
}

function test() {
    let suite = InspectorTest.createAsyncSuite("Canvas.requestNode");

    suite.addTestCase({
        name: "Canvas.requestNode.missingDocument",
        description: "Getting the canvas node requires that WebInspector knows about the document.",
        test(resolve, reject) {
            let canvases = WI.canvasManager.canvases;
            InspectorTest.expectEqual(canvases.length, 3, "The page should have three canvases.");
            if (!canvases.length) {
                reject("Missing canvas.");
                return;
            }

            CanvasAgent.requestNode(canvases[0].identifier, (error) => {
                InspectorTest.expectThat(error, "Should produce an error.");
                InspectorTest.log("Error: " + error);
                resolve();
            });
        }
    });

    suite.addTestCase({
        name: "Canvas.requestNode.validCanvasId",
        description: "Get the node id for each canvas on the page.",
        test(resolve, reject) {
            let canvases = WI.canvasManager.canvases;
            let expectedLength = canvases.length;
            InspectorTest.assert(expectedLength === 3, "The page has 3 canvases.");

            let nodesMap = new Map;

            function finish() {
                let results = {};
                for (let [canvas, node] of nodesMap)
                    results[canvas.displayName] = node;

                let keys = Object.keys(results);
                InspectorTest.assert(keys.length === nodesMap.size, "No display name collisions");

                // Ensure that the test runs properly even if the canvas
                // events are sent in a different order than the above.
                keys.sort();
                for (let displayName of keys) {
                    InspectorTest.expectThat(results[displayName], `Canvas "${displayName}" has node with valid id.`);
                    InspectorTest.expectEqual(results[displayName].nodeName(), "CANVAS", `Canvas "${displayName}" has node with type "CANVAS".`);
                }

                resolve();
            }

            canvases.forEach((canvas) => {
                WI.domTreeManager.requestDocument((documentNode) => {
                    CanvasAgent.requestNode(canvas.identifier, (error, nodeId) => {
                        if (error) {
                            reject(error);
                            return;
                        }

                        nodesMap.set(canvas, WI.domTreeManager.nodeForId(nodeId));
                        if (nodesMap.size === expectedLength)
                            finish();
                    });
                });
            });
        }
    });

    // ------

    suite.addTestCase({
        name: "Canvas.requestNode.invalidCanvasId",
        description: "Invalid canvas identifiers should cause an error.",
        test(resolve, reject) {
            const canvasId = "DOES_NOT_EXIST";
            CanvasAgent.requestNode(canvasId, (error) => {
                InspectorTest.expectThat(error, "Should produce an error.");
                InspectorTest.log("Error: " + error);
                resolve();
            });
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
<style>
    .css { background-image: -webkit-canvas(css); }
</style>
</head>
<body onload="load()">
<p>Test that CanvasAgent.requestNode can properly resolve the owner canvas node.</p>
<canvas id="onscreen"></canvas>
</body>
</html>
