<!DOCTYPE html>
<title>Test for autoplay of muted video</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script src="media-controls.js"></script>
<body>
<script>
    test(function() {
        assert_true(!!window.internals
            && !!window.internals.settings
            && !!window.internals.runtimeFlags
            && !!window.eventSender,
            "This test only works when run as a layout test!");
    }, "Prerequisites to running the rest of the tests");

    window.internals.settings.setAutoplayPolicy('user-gesture-required');
    window.internals.runtimeFlags.autoplayMutedVideosEnabled = true;
    testRunner.setAutoplayAllowed(true);

    function createMutedMediaElement(type) {
        var e = document.createElement(type);
        e.src = type == 'audio' ? 'content/test.oga' : 'content/test.ogv';
        e.muted = true;
        return e;
    }

    function createMutedVideoElement() {
        return createMutedMediaElement('video');
    }

    function createMutedAudioElement() {
        return createMutedMediaElement('audio');
    }

    async_test(function(t) {
        var e = createMutedVideoElement();
        e.autoplay = true;
        document.body.appendChild(e);

        var expectedEvents = [ 'canplay', 'play', 'playing'];
        var eventWatcher = new EventWatcher(t, e, expectedEvents);
        eventWatcher.wait_for(expectedEvents).then(
            t.step_func_done(function() {
                assert_false(e.paused);
            }));
    }, "Test that a muted video with an autoplay attribute autoplays.");

    promise_test(function() {
        return createMutedVideoElement().play();
    }, "Test that play() on a muted video succeeds without gesture.");

    promise_test(function (t) {
        return promise_rejects(
            t,
            new DOMException(
                'play() can only be initiated by a user gesture.',
                'NotAllowedError'),
            createMutedAudioElement().play());
    }, "Test that play() on a muted audio without gesture will reject.");

    async_test(function (t) {
        var e = createMutedAudioElement();
        e.autoplay = true;
        e.onplay = t.unreached_func();
        e.oncanplaythrough = t.step_func(function() {
            setTimeout(t.step_func_done(function() {
                assert_true(e.paused);
            }), 0);
        });
    }, "Test that autoplay on a muted audio without gesture has no effect.");

    async_test(t => {
      var e = createMutedVideoElement();
      e.play().then(t.step_func(() => {
        e.muted = false;

        var expectedEvents = [ 'volumechange', 'pause' ];
          new EventWatcher(t, e, expectedEvents).wait_for(expectedEvents).then(
          t.step_func_done(() => {
            assert_true(e.paused, "The video should be paused.");
          }));
      }));
    }, "Test that unmuting an autoplayed video without gesture pauses.");

    async_test(function(t) {
        var e = createMutedVideoElement();

        e.play().then(t.step_func(function() {
            eventSender.mouseDown();
            eventSender.mouseUp();
        }));

        document.onclick = t.step_func_done(function() {
            e.muted = false;
            assert_false(e.paused, "The video should not be paused.");
        });
    }, "Test that unmuting autoplayed video with gesture doesn't pause it.");

    promise_test(function(t) {
        testRunner.setAutoplayAllowed(false);
        return promise_rejects(
            t,
            new DOMException(
                'play() can only be initiated by a user gesture.',
                'NotAllowedError'),
            createMutedVideoElement().play());
    }, "Test that muted videos don't autoplay when the setting is disabled");
</script>
</body>
