<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
let contextA = document.createElement("canvas").getContext("2d");
let contextB = document.createElement("canvas").getContext("2d");

function performActionsNaN() {
    contextA.globalAlpha = NaN;
    contextB.globalAlpha = NaN;
}

function performActionsMultiple() {
    contextA.fill();
    contextB.fill();

    TestPage.dispatchEventToFrontend("TestPage-performActionsMultiple");
}

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

    suite.addTestCase({
        name: "Canvas.ActionParameterNaN",
        description: "Check that NaN is converted into the proper value for serialization.",
        test(resolve, reject) {
            let canvas = Array.from(WI.canvasManager.canvasCollection)[0];
            InspectorTest.assert(canvas, "There should be at least one canvas context.");

            canvas.awaitEvent(WI.Canvas.Event.RecordingStopped)
            .then((event) => {
                let recording = event.data.recording.toJSON();

                let frames = recording.frames;
                InspectorTest.expectEqual(frames.length, 1, "The recording should have 1 frame.");

                let actions = frames[0].actions;
                InspectorTest.expectEqual(actions.length, 1, "The first frame should have 1 action.");
                InspectorTest.expectEqual(actions[0][1].length, 1, "The action should have 1 parameter.");
                InspectorTest.expectEqual(actions[0][1][0], null, "The parameter should be null.");
            })
            .then(resolve, reject);

            canvas.awaitEvent(WI.Canvas.Event.RecordingStarted)
            .then((event) => {
                InspectorTest.evaluateInPage(`performActionsNaN()`);

                canvas.stopRecording();
            })
            .catch(reject);

            canvas.startRecording();
        },
    });

    suite.addTestCase({
        name: "Canvas.MultipleRecording",
        description: "Check that multiple recordings are able to be started/stopped at the same time.",
        test(resolve, reject) {
            let canvases = Array.from(WI.canvasManager.canvasCollection);
            InspectorTest.assert(canvases.length === 2, "There should be two canvas contexts.");

            canvases[1].awaitEvent(WI.Canvas.Event.RecordingStopped)
            .then((event) => {
                InspectorTest.expectThat(event.data.recording, "There should be a recording for canvas 2.");
            })
            .then(resolve, reject);

            canvases[0].awaitEvent(WI.Canvas.Event.RecordingStopped)
            .then((event) => {
                InspectorTest.expectThat(event.data.recording, "There should be a recording for canvas 1.");

                InspectorTest.log("Stopping the recording of canvas 2...");
                canvases[1].stopRecording();
            })
            .catch(reject);

            InspectorTest.awaitEvent("TestPage-performActionsMultiple")
            .then((event) => {
                InspectorTest.pass("Actions performed.");

                InspectorTest.log("Stopping the recording of canvas 1...");
                canvases[0].stopRecording();
            })
            .catch(reject);

            canvases[1].awaitEvent(WI.Canvas.Event.RecordingStarted)
            .then((event) => {
                InspectorTest.expectThat(canvases[1].recordingActive, "Recording started of canvas 2");

                InspectorTest.log("Performing actions...");
                InspectorTest.evaluateInPage(`performActionsMultiple()`);
            })
            .catch(reject);

            canvases[0].awaitEvent(WI.Canvas.Event.RecordingStarted)
            .then((event) => {
                InspectorTest.expectThat(canvases[0].recordingActive, "Recording started of canvas 1");

                InspectorTest.log("Starting a recording of canvas 2...");
                canvases[1].startRecording();
            })
            .catch(reject);

            InspectorTest.log("Starting a recording of canvas 1...");
            canvases[0].startRecording();
        },
    });

    suite.addTestCase({
        name: "Canvas.NoActions",
        description: "Check that a canvas is still able to be recorded after stopping a recording with no actions.",
        test(resolve, reject) {
            let canvas = Array.from(WI.canvasManager.canvasCollection)[0];
            InspectorTest.assert(canvas, "There should be at least one canvas context.");

            let eventCount = 0;
            function handleRecordingStopped(event) {
                InspectorTest.assert(!event.data.recording, "The recording payload should be null.");

                ++eventCount;
                if (eventCount == 1) {
                    InspectorTest.pass("A recording should have been started and stopped once.");

                    canvas.startRecording();
                    canvas.stopRecording();
                } else if (eventCount >= 2) {
                    InspectorTest.pass("A recording should have been started and stopped twice.");

                    canvas.removeEventListener(WI.Canvas.Event.RecordingStopped, handleRecordingStopped);
                    resolve();
                }
            }
            canvas.addEventListener(WI.Canvas.Event.RecordingStopped, handleRecordingStopped);

            canvas.startRecording();
            canvas.stopRecording();
        },
    });

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

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

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
    <p>Test general cases of CanvasAgent recording calls.</p>
</body>
</html>
