<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Testing basic autoplay with getUserMedia</title>
        <script src="../resources/testharness.js"></script>
        <script src="../resources/testharnessreport.js"></script>
        <script src=../media/media-file.js></script>
        <script src=../media/video-test.js></script>
    </head>
    <body>
        <video id="video" autoplay></video>
        <script src ="routines.js"></script>
        <script>
video = document.getElementById("video");

if (window.internals)
    internals.setMediaElementRestrictions(video, "RequireUserGestureForVideoRateChange");
if (window.testRunner)
    testRunner.setUserMediaPermission(true);

promise_test((test) => {
    findMediaElement();
    video.src = findMediaFile("video", "content/test");
    return video.play().then(() => assert_unreached(), (e) => { assert_equals(e.name, 'NotAllowedError')});
}, "Ensuring autoplay does not work on regular video elements")

promise_test((test) => {
    return navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((stream) => {
        findMediaElement();
        video.src = findMediaFile("video", "content/test");
        return video.play().then(() => assert_unreached(), (e) => { assert_equals(e.name, 'NotAllowedError')});
    });
}, "Ensuring autoplay does not work on regular video elements when getUserMedia is on");

promise_test((test) => {
    return navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((stream) => {
        video.srcObject = stream;
        return waitFor(10);
    }).then(() => {
        return video.play();
    });
}, "Local media stream autoplay");

promise_test((test) => {
    return navigator.mediaDevices.getUserMedia({audio: true, video: true}).then((stream) => {
        return new Promise((resolve, reject) => {
            createConnections((firstConnection) => {
                firstConnection.addTrack(stream.getVideoTracks()[0], stream);
                firstConnection.addTrack(stream.getAudioTracks()[0], stream);
            }, (secondConnection) => {
                var count = 0;
                secondConnection.ontrack = (trackEvent) => {
                    if (++count == 2)
                        resolve(trackEvent.streams[0]);
                };
            });
            setTimeout(() => reject("Test timed out"), 5000);
        });
    }).then((stream) => {
        video.srcObject = stream;
        return video.play();
    });
}, "Remote media stream autoplay");
        </script>
    </body>
</html>
