<!DOCTYPE html>
<html>
    <head>
        <title>getDisplayMedia prompt</title>
        <script src="../../../../resources/js-test-pre.js"></script>
    </head>
    <body>
    <p id="description"></p>
    <div id="console"></div>

<script>
    if (window.internals)
        internals.setDisableGetDisplayMediaUserGestureConstraint(true);

    let stream;
    let err;
    
    function numberOfTimesGetUserMediaPromptHasBeenCalled() {
        return testRunner.userMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
    }
    
    async function promptForAudioOnly() {
        debug("<br>** Request an audio-only stream, the user should not be prompted **");
        stream = await navigator.mediaDevices.getDisplayMedia({ audio: true })
            .catch((e) => { err = e; });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");
        shouldBeUndefined("stream");
        shouldBeTrue("err instanceof Error ");
        shouldBeEqualToString("err.name", "TypeError");
    }

    async function promptForVideoOnly() {
        debug("<br>** Request an video-only stream, the user should be prompted **");
        stream = await navigator.mediaDevices.getDisplayMedia({ video: true });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
        shouldBe("stream.getAudioTracks().length", "0");
        shouldBe("stream.getVideoTracks().length", "1");
    }

    async function promptForAudioAndVideo() {
        debug("<br>** Request a stream with audio and video, the user should be prompted but no audio track should be created **");
        stream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
        shouldBe("stream.getAudioTracks().length", "0");
        shouldBe("stream.getVideoTracks().length", "1");
    }
    
    async function promptWithExactVideoConstraints() {
        debug("<br>** Request a stream with 'max' constraints, the user should not be prompted **");

        stream = null;
        stream = await navigator.mediaDevices.getDisplayMedia({ video: {width: {exact: 640}, height: {exact: 480}} })
            .catch((e) => { err = e; });
        
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
        shouldBeUndefined("stream");
        shouldBeTrue("err instanceof Error ");
        shouldBeEqualToString("err.name", "TypeError");
    }

    async function promptWithMinVideoConstraints() {
        debug("<br>** Request a stream with 'min' constraints, the user should not be prompted **");

        stream = null;
        stream = await navigator.mediaDevices.getDisplayMedia({ video: {width: {min: 640}, height: {min: 480}} })
            .catch((e) => { err = e; });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
        shouldBeUndefined("stream");
        shouldBeTrue("err instanceof Error ");
        shouldBeEqualToString("err.name", "TypeError");
    }

    async function promptWithAdvancedVideoConstraints() {
        debug("<br>** Request a stream with 'advanced' constraints, the user should not be prompted **");

        stream = null;
        stream = await navigator.mediaDevices.getDisplayMedia({ video: { width: 640, height: 480, advanced: [ { width: 1920, height: 1280 } ] } })
            .catch((e) => { err = e; });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "2");
        shouldBeUndefined("stream");
        shouldBeTrue("err instanceof Error ");
        shouldBeEqualToString("err.name", "TypeError");
    }

    async function promptWithValidVideoConstraints() {
        debug("<br>** Request a stream with valid constraints, the user should be prompted **");

        stream = null;
        stream = await navigator.mediaDevices.getDisplayMedia({ video: {width: 640, height: 480} })
            .catch((e) => { err = e; });
        
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "3");
        shouldBe("stream.getAudioTracks().length", "0");
        shouldBe("stream.getVideoTracks().length", "1");
    }

    async function promptWithInvalidAudioConstraint() {
        debug("<br>** Request a stream with an exact audio constraint, it should be ignored **");

        stream = null;
        stream = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: { volume: { exact: 0.5 } } });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "4");
        shouldBe("stream.getAudioTracks().length", "0");
        shouldBe("stream.getVideoTracks().length", "1");
    }
    
    (async function() {
        description('Test basic getDisplayMedia prompting behavior');
        jsTestIsAsync = true;

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        window.internals.settings.setScreenCaptureEnabled(true);

        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");

        await promptForAudioOnly();
        await promptForVideoOnly();
        await promptForAudioAndVideo();
        await promptWithExactVideoConstraints();
        await promptWithMinVideoConstraints();
        await promptWithAdvancedVideoConstraints();
        await promptWithValidVideoConstraints();
        await promptWithInvalidAudioConstraint();

        debug("");
        finishJSTest();
    })()

</script>
<script src="../../../../resources/js-test-post.js"></script>
</body>
</html>
