diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/screen-capture | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/screen-capture')
10 files changed, 744 insertions, 0 deletions
diff --git a/testing/web-platform/tests/screen-capture/META.yml b/testing/web-platform/tests/screen-capture/META.yml new file mode 100644 index 0000000000..6fbb899ac3 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/META.yml @@ -0,0 +1,7 @@ +spec: https://w3c.github.io/mediacapture-screen-share/ +suggested_reviewers: + - alvestrand + - martinthomson + - uysalere + - jan-ivar + - eladalon1983 diff --git a/testing/web-platform/tests/screen-capture/getdisplaymedia-after-discard.https.html b/testing/web-platform/tests/screen-capture/getdisplaymedia-after-discard.https.html new file mode 100644 index 0000000000..445120f8c2 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/getdisplaymedia-after-discard.https.html @@ -0,0 +1,45 @@ +<!doctype html> +<title>Test for rejected promise from getDisplayMedia() in a discarded browsing + context</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script src="/resources/testdriver.js"></script> +<script src='/resources/testdriver-vendor.js'></script> +<body></body> +<script> +// https://w3c.github.io/mediacapture-screen-share/#dom-mediadevices-getdisplaymedia +// If the current settings object's responsible document is NOT fully active, +// return a promise rejected with a DOMException object whose name attribute +// has the value "InvalidStateError". +promise_test(async () => { + const frame = document.createElement('iframe'); + document.body.appendChild(frame); + frame.srcdoc = '<html></html>'; + await new Promise(resolve => frame.onload = resolve); + const child_window = frame.contentWindow; + const devices = child_window.navigator.mediaDevices; + const child_DOMException = child_window.DOMException; + // transient activation of iframe content + await test_driver.bless('getDisplayMedia()', undefined, child_window); + frame.remove(); + // `catch()` is used rather than static Promise methods because microtasks + // for `PromiseResolve()` do not run when Promises in inactive Documents are + // involved. Whether microtasks for `catch()` run depends on the realm of + // the handler rather than the realm of the Promise. + // See https://github.com/whatwg/html/issues/5319. + let promise_already_rejected = false; + let rejected_reason; + devices.getDisplayMedia({video:true}).catch(reason => { + promise_already_rejected = true; + rejected_reason = reason; + }); + // Race a settled promise to check that the returned promise is already + // rejected. + await Promise.reject().catch(() => { + assert_true(promise_already_rejected, + 'should have returned an already-rejected promise.'); + assert_throws_dom('InvalidStateError', child_DOMException, + () => { throw rejected_reason }); + }); +}, 'getDisplayMedia() in a discarded browsing context'); +</script> diff --git a/testing/web-platform/tests/screen-capture/getdisplaymedia-capture-controller.https.window.js b/testing/web-platform/tests/screen-capture/getdisplaymedia-capture-controller.https.window.js new file mode 100644 index 0000000000..fa1fd84b36 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/getdisplaymedia-capture-controller.https.window.js @@ -0,0 +1,201 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: timeout=long + +'use strict'; + +const validFocusBehaviors = ['focus-captured-surface', 'no-focus-change']; +const validDisplaySurfaces = ['window', 'browser']; + +test(() => { + assert_own_property(window, 'CaptureController'); +}, 'CaptureController in window'); + +const stopTracks = stream => stream.getTracks().forEach(track => track.stop()); + +validFocusBehaviors.forEach( + (focusBehavior) => test( + (t) => { + const controller = new CaptureController(); + controller.setFocusBehavior(focusBehavior); + }, + `setFocusBehavior("${ + focusBehavior}") must succeed before capture starts`)); + +['invalid', null, undefined, {}, true].forEach( + (focusBehavior) => test( + () => { + const controller = new CaptureController(); + assert_throws_js( + TypeError, () => controller.setFocusBehavior(focusBehavior)); + }, + `setFocusBehavior("${ + focusBehavior}") must throw TypeError if focusBehavior is invalid`)); + +promise_test(async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia({controller}); + t.add_cleanup(() => stopTracks(stream)); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); +}, 'getDisplayMedia({controller}) must succeed'); + +['invalid', null, {}, true].forEach( + (controller) => promise_test( + async (t) => { + await test_driver.bless('getDisplayMedia()'); + await promise_rejects_js( + t, TypeError, + navigator.mediaDevices.getDisplayMedia({controller})); + }, + `getDisplayMedia({controller: ${ + controller}}) must fail with TypeError`)); + +promise_test(async (t) => { + const controller = new CaptureController(); + + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia({controller}); + t.add_cleanup(() => stopTracks(stream)); + + await test_driver.bless('getDisplayMedia()'); + const p = navigator.mediaDevices.getDisplayMedia({controller}); + t.add_cleanup(async () => { + try { + stopTracks(await p); + } catch { + } + }); + await promise_rejects_dom( + t, 'InvalidStateError', Promise.race([p, Promise.resolve()]), + 'getDisplayMedia should have returned an already-rejected promise.'); +}, 'getDisplayMedia({controller}) must fail with InvalidStateError if controller is bound'); + +validDisplaySurfaces.forEach((displaySurface) => { + validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface}}); + t.add_cleanup(() => stopTracks(stream)); + controller.setFocusBehavior(focusBehavior); + }, + `setFocusBehavior("${ + focusBehavior}") must succeed when window of opportunity is opened if capturing a ${ + displaySurface}`)); +}); + +validDisplaySurfaces.forEach((displaySurface) => { + validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const p = navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface}}); + controller.setFocusBehavior(focusBehavior); + const stream = await p; + t.add_cleanup(() => stopTracks(stream)); + }, + `setFocusBehavior("${ + focusBehavior}") must succeed when getDisplayMedia promise is pending if capturing a ${ + displaySurface}`)); +}); + +validDisplaySurfaces.forEach((displaySurface) => { + validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface}}); + stopTracks(stream); + assert_throws_dom( + 'InvalidStateError', + () => controller.setFocusBehavior(focusBehavior)); + }, + `setFocusBehavior("${ + focusBehavior}") must throw InvalidStateError when track is stopped if capturing a ${ + displaySurface}`)); +}); + +validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface: 'monitor'}}); + t.add_cleanup(() => stopTracks(stream)); + assert_throws_dom( + 'InvalidStateError', + () => controller.setFocusBehavior(focusBehavior)); + }, + `setFocusBehavior("${ + focusBehavior}") must throw InvalidStateError if capturing a monitor`)); + +validDisplaySurfaces.forEach((displaySurface) => { + validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface}}); + t.add_cleanup(() => stopTracks(stream)); + await new Promise((resolve) => step_timeout(resolve, 0)); + assert_throws_dom( + 'InvalidStateError', + () => controller.setFocusBehavior(focusBehavior)); + }, + `setFocusBehavior("${ + focusBehavior}") must throw InvalidStateError when window of opportunity is closed if capturing a ${ + displaySurface}`)); +}); + +validDisplaySurfaces.forEach((displaySurface) => { + validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + await test_driver.bless('getDisplayMedia()'); + const stream = await navigator.mediaDevices.getDisplayMedia( + {controller, video: {displaySurface}}); + t.add_cleanup(() => stopTracks(stream)); + controller.setFocusBehavior(focusBehavior) + assert_throws_dom( + 'InvalidStateError', + () => controller.setFocusBehavior(focusBehavior)); + }, + `setFocusBehavior("${ + focusBehavior}") must throw InvalidStateError the second time if capturing a ${ + displaySurface}`)); +}); + +validFocusBehaviors.forEach( + (focusBehavior) => promise_test( + async (t) => { + const controller = new CaptureController(); + const options = { + controller: controller, + video: {width: {max: 0}}, + } + try { + await test_driver.bless('getDisplayMedia()'); + stopTracks(await navigator.mediaDevices.getDisplayMedia(options)); + } catch (err) { + assert_equals(err.name, 'OverconstrainedError', err.message); + assert_throws_dom( + 'InvalidStateError', + () => controller.setFocusBehavior(focusBehavior)); + return; + } + assert_unreached('getDisplayMedia should have failed'); + }, + `setFocusBehavior("${ + focusBehavior}") must throw InvalidStateError if getDisplayMedia fails`)); diff --git a/testing/web-platform/tests/screen-capture/getdisplaymedia-framerate.https.html b/testing/web-platform/tests/screen-capture/getdisplaymedia-framerate.https.html new file mode 100644 index 0000000000..c17b25d987 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/getdisplaymedia-framerate.https.html @@ -0,0 +1,42 @@ +<!doctype html> +<meta charset=utf-8> +<title>getDisplayMedia</title> +<meta name="timeout" content="long"> +<button id="button">User gesture</button> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<video id="display"></video> +<script> + 'use strict'; + +const stopTracks = stream => stream.getTracks().forEach(track => track.stop()); + +async function getDisplayMedia(constraints) { + const p = new Promise(r => button.onclick = r); + await test_driver.click(button); + await p; + return navigator.mediaDevices.getDisplayMedia(constraints); +} + +promise_test( async t => { + const v = document.getElementById('display'); + v.autoplay = true; + // work around firefox bug 1586505, orthogonal to what's being tested + const frames = () => v.mozPaintedFrames ?? v.getVideoPlaybackQuality()?.totalVideoFrames; + const target_rate = 5; + const stream = await getDisplayMedia({video: {width:160, frameRate: target_rate}}); + t.add_cleanup(() => stopTracks(stream)); + v.srcObject = stream; + const intitial_time = v.currentTime; + const initial_frame_count = frames(); + await new Promise(r => t.step_timeout(r, 10000)); + const total_elapsed_frames = frames() - initial_frame_count; + const total_elapsed_time = v.currentTime - intitial_time; + const average_fps = total_elapsed_frames / total_elapsed_time; + assert_greater_than_equal(average_fps, target_rate * 0.50); + assert_less_than_equal(average_fps, target_rate * 1.75); +}, "getDisplayMedia() must adhere to frameRate if set"); + +</script> diff --git a/testing/web-platform/tests/screen-capture/getdisplaymedia.https.html b/testing/web-platform/tests/screen-capture/getdisplaymedia.https.html new file mode 100644 index 0000000000..095b98dea4 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/getdisplaymedia.https.html @@ -0,0 +1,279 @@ +<!doctype html> +<meta charset=utf-8> +<title>getDisplayMedia</title> +<meta name="timeout" content="long"> +<button id="button">User gesture</button> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> + 'use strict'; +test(() => { + assert_idl_attribute(navigator.mediaDevices, 'getDisplayMedia'); +}, "getDisplayMedia in navigator.mediaDevices"); + +const stopTracks = stream => stream.getTracks().forEach(track => track.stop()); +const j = obj => JSON.stringify(obj); + +async function getDisplayMedia(constraints) { + const p = new Promise(r => button.onclick = r); + await test_driver.click(button); + await p; + return navigator.mediaDevices.getDisplayMedia(constraints); +} + +promise_test(t => { + const p = navigator.mediaDevices.getDisplayMedia({video: true}); + t.add_cleanup(async () => { + try { stopTracks(await p) } catch {} + }); + // Race a settled promise to check that the returned promise is already + // rejected. + return promise_rejects_dom( + t, 'InvalidStateError', Promise.race([p, Promise.resolve()]), + 'getDisplayMedia should have returned an already-rejected promise.'); +}, `getDisplayMedia() must require user activation`); + +[ + {video: true}, + {video: true, audio: false}, + {video: {}}, + {audio: false}, + {}, + undefined +].forEach(constraints => promise_test(async t => { + const stream = await getDisplayMedia(constraints); + t.add_cleanup(() => stopTracks(stream)); + assert_equals(stream.getTracks().length, 1); + assert_equals(stream.getVideoTracks().length, 1); + assert_equals(stream.getAudioTracks().length, 0); +}, `getDisplayMedia(${j(constraints)}) must succeed with video`)); + +[ + {video: false}, + {video: {advanced: [{width: 320}]}}, + {video: {width: {min: 320}}}, + {video: {width: {exact: 320}}}, + {video: {height: {min: 240}}}, + {video: {height: {exact: 240}}}, + {video: {frameRate: {min: 4}}}, + {video: {frameRate: {exact: 4}}}, + {video: false, audio: true}, +].forEach(constraints => promise_test(async t => { + await test_driver.bless('getDisplayMedia()'); + const p = navigator.mediaDevices.getDisplayMedia(constraints); + t.add_cleanup(async () => { + try { stopTracks(await p) } catch {} + }); + await promise_rejects_js( + t, TypeError, Promise.race([p, Promise.resolve()]), + 'getDisplayMedia should have returned an already-rejected promise.'); +}, `getDisplayMedia(${j(constraints)}) must fail with TypeError`)); + +[ + {video: true, audio: true}, + {audio: true}, +].forEach(constraints => promise_test(async t => { + const stream = await getDisplayMedia(constraints); + t.add_cleanup(() => stopTracks(stream)); + assert_greater_than_equal(stream.getTracks().length, 1); + assert_less_than_equal(stream.getTracks().length, 2); + assert_equals(stream.getVideoTracks().length, 1); + assert_less_than_equal(stream.getAudioTracks().length, 1); +}, `getDisplayMedia(${j(constraints)}) must succeed with video maybe audio`)); + +[ + {width: {max: 360}}, + {height: {max: 240}}, + {width: {max: 360}, height: {max: 240}}, + {frameRate: {max: 4}}, + {frameRate: {max: 4}, width: {max: 360}}, + {frameRate: {max: 4}, height: {max: 240}}, + {frameRate: {max: 4}, width: {max: 360}, height: {max: 240}}, +].forEach(constraints => promise_test(async t => { + const stream = await getDisplayMedia({video: constraints}); + t.add_cleanup(() => stopTracks(stream)); + const {width, height, frameRate} = stream.getTracks()[0].getSettings(); + assert_greater_than_equal(width, 1); + assert_greater_than_equal(height, 1); + assert_greater_than_equal(frameRate, 1); + if (constraints.width) { + assert_less_than_equal(width, constraints.width.max); + } + if (constraints.height) { + assert_less_than_equal(height, constraints.height.max); + } + if (constraints.frameRate) { + assert_less_than_equal(frameRate, constraints.frameRate.max); + } +}, `getDisplayMedia({video: ${j(constraints)}}) must be constrained`)); + +const someSizes = [ + {width: 160}, + {height: 120}, + {width: 80}, + {height: 60}, + {width: 158}, + {height: 118}, +]; + +someSizes.forEach(constraints => promise_test(async t => { + const stream = await getDisplayMedia({video: constraints}); + t.add_cleanup(() => stopTracks(stream)); + const {width, height, frameRate} = stream.getTracks()[0].getSettings(); + if (constraints.width) { + assert_equals(width, constraints.width); + } else { + assert_equals(height, constraints.height); + } + assert_greater_than_equal(frameRate, 1); +}, `getDisplayMedia({video: ${j(constraints)}}) must be downscaled precisely`)); + +promise_test(async t => { + const video = {height: 240}; + const stream = await getDisplayMedia({video}); + t.add_cleanup(() => stopTracks(stream)); + const [track] = stream.getVideoTracks(); + const {height} = track.getSettings(); + assert_equals(height, video.height); + for (const constraints of someSizes) { + await track.applyConstraints(constraints); + const {width, height} = track.getSettings(); + if (constraints.width) { + assert_equals(width, constraints.width); + } else { + assert_equals(height, constraints.height); + } + } +}, `applyConstraints(width or height) must downscale precisely`); + +[ + {video: {width: {max: 0}}}, + {video: {height: {max: 0}}}, + {video: {frameRate: {max: 0}}}, + {video: {width: {max: -1}}}, + {video: {height: {max: -1}}}, + {video: {frameRate: {max: -1}}}, +].forEach(constraints => promise_test(async t => { + try { + stopTracks(await getDisplayMedia(constraints)); + } catch (err) { + assert_equals(err.name, 'OverconstrainedError', err.message); + return; + } + assert_unreached('getDisplayMedia should have failed'); +}, `getDisplayMedia(${j(constraints)}) must fail with OverconstrainedError`)); + +// Content shell picks a fake desktop device by default. +promise_test(async t => { + const stream = await getDisplayMedia({video: true}); + t.add_cleanup(() => stopTracks(stream)); + assert_equals(stream.getVideoTracks().length, 1); + const track = stream.getVideoTracks()[0]; + assert_equals(track.kind, "video"); + assert_equals(track.enabled, true); + assert_equals(track.readyState, "live"); + track.stop(); + assert_equals(track.readyState, "ended"); +}, 'getDisplayMedia() resolves with stream with video track'); + +{ + const displaySurfaces = ['monitor', 'window', 'browser']; + displaySurfaces.forEach((displaySurface) => { + promise_test(async t => { + const stream = await getDisplayMedia({video: {displaySurface}}); + t.add_cleanup(() => stopTracks(stream)); + const settings = stream.getVideoTracks()[0].getSettings(); + assert_equals(settings.displaySurface, displaySurface); + assert_any(assert_equals, settings.logicalSurface, [true, false]); + assert_any(assert_equals, settings.cursor, ['never', 'always', 'motion']); + assert_false("suppressLocalAudioPlayback" in settings); + }, `getDisplayMedia({"video":{"displaySurface":"${displaySurface}"}}) with getSettings`); + }) +} + +{ + const properties = ["displaySurface"]; + properties.forEach((property) => { + test(() => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + assert_true(supportedConstraints[property]); + }, property + " is supported"); + }); +} + +[ + {video: {displaySurface: "monitor"}}, + {video: {displaySurface: "window"}}, + {video: {displaySurface: "browser"}}, + {selfBrowserSurface: "include"}, + {selfBrowserSurface: "exclude"}, + {surfaceSwitching: "include"}, + {surfaceSwitching: "exclude"}, + {systemAudio: "include"}, + {systemAudio: "exclude"}, +].forEach(constraints => promise_test(async t => { + const stream = await getDisplayMedia(constraints); + t.add_cleanup(() => stopTracks(stream)); +}, `getDisplayMedia(${j(constraints)}) must succeed`)); + +[ + {selfBrowserSurface: "invalid"}, + {surfaceSwitching: "invalid"}, + {systemAudio: "invalid"}, +].forEach(constraints => promise_test(async t => { + await test_driver.bless('getDisplayMedia()'); + const p = navigator.mediaDevices.getDisplayMedia(constraints); + t.add_cleanup(async () => { + try { stopTracks(await p) } catch {} + }); + await promise_rejects_js( + t, TypeError, Promise.race([p, Promise.resolve()]), + 'getDisplayMedia should have returned an already-rejected promise.'); +}, `getDisplayMedia(${j(constraints)}) must fail with TypeError`)); + +test(() => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + assert_true(supportedConstraints.suppressLocalAudioPlayback); +}, "suppressLocalAudioPlayback is supported"); + +{ + const suppressLocalAudioPlaybacks = [true, false]; + suppressLocalAudioPlaybacks.forEach((suppressLocalAudioPlayback) => { + promise_test(async (t) => { + const stream = await getDisplayMedia({ + audio: { suppressLocalAudioPlayback }, + }); + t.add_cleanup(() => stopTracks(stream)); + const [videoTrack] = stream.getVideoTracks(); + assert_false("suppressLocalAudioPlayback" in videoTrack.getSettings()); + const [audioTrack] = stream.getAudioTracks(); + const audioTrackSettings = audioTrack.getSettings(); + assert_true("suppressLocalAudioPlayback" in audioTrackSettings); + assert_equals( + audioTrackSettings.suppressLocalAudioPlayback, + suppressLocalAudioPlayback + ); + await audioTrack.applyConstraints(); + assert_true("suppressLocalAudioPlayback" in audioTrackSettings); + assert_equals( + audioTrackSettings.suppressLocalAudioPlayback, + suppressLocalAudioPlayback + ); + }, `getDisplayMedia({"audio":{"suppressLocalAudioPlayback":${suppressLocalAudioPlayback}}}) with getSettings`); + }); +} + +promise_test(async t => { + const stream = await getDisplayMedia({video: true}); + t.add_cleanup(() => stopTracks(stream)); + const capabilities = stream.getVideoTracks()[0].getCapabilities(); + assert_any( + assert_equals, capabilities.displaySurface, + ['monitor', 'window', 'browser']); +}, 'getDisplayMedia() with getCapabilities'); + +</script> diff --git a/testing/web-platform/tests/screen-capture/historical.https.html b/testing/web-platform/tests/screen-capture/historical.https.html new file mode 100644 index 0000000000..d510bc4208 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/historical.https.html @@ -0,0 +1,10 @@ +<!doctype html> +<meta charset=utf-8> +<title>getDisplayMedia historical tests</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(function() { + assert_false('getDisplayMedia' in navigator); +}, 'navigator.getDisplayMedia should not exist'); +</script> diff --git a/testing/web-platform/tests/screen-capture/idlharness.https.window.js b/testing/web-platform/tests/screen-capture/idlharness.https.window.js new file mode 100644 index 0000000000..527565ea96 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/idlharness.https.window.js @@ -0,0 +1,16 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://w3c.github.io/mediacapture-screen-share/ + +idl_test( + ['screen-capture'], + ['mediacapture-streams', 'html', 'dom'], + idl_array => { + idl_array.add_objects({ + MediaDevices: ['navigator.mediaDevices'], + }); + } +); diff --git a/testing/web-platform/tests/screen-capture/permissions-policy-audio+video.https.sub.html b/testing/web-platform/tests/screen-capture/permissions-policy-audio+video.https.sub.html new file mode 100644 index 0000000000..2e7df39125 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/permissions-policy-audio+video.https.sub.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<body> + <script src="/resources/testharness.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testharnessreport.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="/common/get-host-info.sub.js"></script> + <script src="/permissions-policy/resources/permissions-policy.js"></script> + <script> + 'use strict'; + + async function getDisplayMedia(constraints) { + await test_driver.bless('transient activation for getDisplayMedia()'); + return navigator.mediaDevices.getDisplayMedia(constraints); + } + + async function testGDM({audio, video}) { + let stream; + try { + stream = await getDisplayMedia({audio, video}); + if (stream.getVideoTracks().length == 0) { + throw Error(`requested video track must be present with ` + + `audio ${audio} and video ${video}, or fail`); + } + } finally { + if (stream) { + stream.getTracks().forEach(track => track.stop()); + } + } + } + + if (page_loaded_in_iframe()) { + test_driver.set_test_context(window.parent); + } + const cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN; + run_all_fp_tests_allow_self( + cross_domain, + 'display-capture', + 'NotAllowedError', + async () => { + await testGDM({audio: true, video: true}); + } + ); + </script> +</body> diff --git a/testing/web-platform/tests/screen-capture/permissions-policy-audio.https.sub.html b/testing/web-platform/tests/screen-capture/permissions-policy-audio.https.sub.html new file mode 100644 index 0000000000..7bfc33f861 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/permissions-policy-audio.https.sub.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<body> + <script src="/resources/testharness.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testharnessreport.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="/common/get-host-info.sub.js"></script> + <script src="/permissions-policy/resources/permissions-policy.js"></script> + <script> + 'use strict'; + + async function getDisplayMedia(constraints) { + await test_driver.bless('transient activation for getDisplayMedia()'); + return navigator.mediaDevices.getDisplayMedia(constraints); + } + + async function testGDM({audio, video}) { + let stream; + try { + stream = await getDisplayMedia({audio, video}); + if (stream.getVideoTracks().length == 0) { + throw Error(`requested video track must be present with ` + + `audio ${audio} and video ${video}, or fail`); + } + } finally { + if (stream) { + stream.getTracks().forEach(track => track.stop()); + } + } + } + + if (page_loaded_in_iframe()) { + test_driver.set_test_context(window.parent); + } + const cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN; + run_all_fp_tests_allow_self( + cross_domain, + 'display-capture', + 'NotAllowedError', + async () => { + await testGDM({audio: true}); + } + ); + </script> +</body> diff --git a/testing/web-platform/tests/screen-capture/permissions-policy-video.https.sub.html b/testing/web-platform/tests/screen-capture/permissions-policy-video.https.sub.html new file mode 100644 index 0000000000..6740466ef2 --- /dev/null +++ b/testing/web-platform/tests/screen-capture/permissions-policy-video.https.sub.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<body> + <script src="/resources/testharness.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testharnessreport.js" + type="text/javascript{{GET[in-iframe]}}"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="/common/get-host-info.sub.js"></script> + <script src="/permissions-policy/resources/permissions-policy.js"></script> + <script> + 'use strict'; + + async function getDisplayMedia(constraints) { + await test_driver.bless('transient activation for getDisplayMedia()'); + return navigator.mediaDevices.getDisplayMedia(constraints); + } + + async function testGDM({audio, video}) { + let stream; + try { + stream = await getDisplayMedia({audio, video}); + if (stream.getVideoTracks().length == 0) { + throw Error(`requested video track must be present with ` + + `audio ${audio} and video ${video}, or fail`); + } + } finally { + if (stream) { + stream.getTracks().forEach(track => track.stop()); + } + } + } + + if (page_loaded_in_iframe()) { + test_driver.set_test_context(window.parent); + } + const cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN; + run_all_fp_tests_allow_self( + cross_domain, + 'display-capture', + 'NotAllowedError', + async () => { + await testGDM({video: true}); + } + ); + </script> +</body> |