<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="../../resources/js-test-pre.js"></script>
    <script src="../../resources/ui-helper.js"></script>
    <script>
        description("Tests that transient activation is generated by correct events.");

        testRunner.waitUntilDone();

        function waitFor(element, type) {
            return new Promise(resolve => {
                element.addEventListener(type, event => {
                    testPassed(`EVENT(${event.type})`);
                    resolve(event);
                }, { once: true });
            });
        }

        async function doTest() {
            internals.consumeTransientActivation();

            let mouseMovePromise = waitFor(document, 'mousemove');
            evalAndLog("eventSender.mouseMoveTo(50, 50)");
            await mouseMovePromise;
            shouldBeFalse("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            let mouseDownPromise = waitFor(document, 'mousedown');
            evalAndLog("eventSender.mouseDown()");
            await mouseDownPromise;
            shouldBeTrue("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            let mouseUpPromise = waitFor(document, 'mouseup');
            evalAndLog("eventSender.mouseUp()");
            await mouseUpPromise;
            shouldBeFalse("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            var keyDownPromise = waitFor(document, 'keydown');
            var promise = evalAndLog("UIHelper.rawKeyDown('escape')");
            await Promise.all([promise, keyDownPromise]);
            shouldBeFalse("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            var keyUpPromise = waitFor(document, 'keyup');
            var promise = evalAndLog("UIHelper.rawKeyUp('esc')");
            await Promise.all([promise, keyUpPromise]);
            shouldBeFalse("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            keyDownPromise = waitFor(document, 'keydown');
            var promise = evalAndLog("UIHelper.rawKeyDown('a')");
            await Promise.all([promise, keyDownPromise]);
            shouldBeTrue("navigator.userActivation.isActive");
            internals.consumeTransientActivation();

            keyUpPromise = waitFor(document, 'keyup');
            var promise = evalAndLog("UIHelper.rawKeyUp('a')");
            await Promise.all([promise, keyUpPromise]);
            shouldBeFalse("navigator.userActivation.isActive");
            internals.consumeTransientActivation();
        }

        window.addEventListener("load", event => {
            doTest().catch(e => {
                testFailed(e.description);
            }).finally(() => {
                testRunner.notifyDone();
            });
        });
    </script>
</head>
<body>
    <button id="target" style="width: 100px; height: 100px;"></button>
    <script src="../../resources/js-test-post.js"></script>
</body>
</html>
