<!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>
    let stream;
    let err;
    
    function callGetDisplayMedia(options)
    {
        let promise;
        window.internals.withUserGesture(() => {
            promise = navigator.mediaDevices.getDisplayMedia(options);
        });
        return promise;
    }

    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 **");
        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = await callGetDisplayMedia({ audio: true });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
        shouldBe("stream.getAudioTracks().length", "0");
        shouldBe("stream.getVideoTracks().length", "1");
    }

    async function promptForVideoOnly() {
        debug("<br>** Request an video-only stream, the user should be prompted **");
        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = await callGetDisplayMedia({ 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 **");
        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = await callGetDisplayMedia({ video: true, audio: true });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
        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 **");

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = null;
        stream = await callGetDisplayMedia({ video: {width: {exact: 640}, height: {exact: 480}} })
            .catch((e) => { err = e; });
        
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");
        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 **");

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = null;
        stream = await callGetDisplayMedia({ video: {width: {min: 640}, height: {min: 480}} })
            .catch((e) => { err = e; });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");
        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 **");

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = null;
        stream = await callGetDisplayMedia({ video: { width: 640, height: 480, advanced: [ { width: 1920, height: 1280 } ] } })
            .catch((e) => { err = e; });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "0");
        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 **");

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = null;
        stream = await callGetDisplayMedia({ video: {width: 640, height: 480} })
            .catch((e) => { err = e; });
        
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
        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 **");

        testRunner.resetUserMediaPermissionRequestCountForOrigin(document.location.href, document.location.href);
        stream = null;
        stream = await callGetDisplayMedia({ video: true, audio: { volume: { exact: 0.5 } } });
        shouldBe("numberOfTimesGetUserMediaPromptHasBeenCalled()", "1");
        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>
