diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/mediacapture-extensions | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/mediacapture-extensions')
3 files changed, 653 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mediacapture-extensions/GUM-backgroundBlur.https.html b/testing/web-platform/tests/mediacapture-extensions/GUM-backgroundBlur.https.html new file mode 100644 index 0000000000..605a4e0831 --- /dev/null +++ b/testing/web-platform/tests/mediacapture-extensions/GUM-backgroundBlur.https.html @@ -0,0 +1,150 @@ +<!DOCTYPE html> +<html> +<head> +<title>Test background blur support</title> +<link rel="help" href="https://w3c.github.io/mediacapture-extensions/"> +</head> +<body> +<h1 class="instructions">Description</h1> +<p class="instructions">This test checks background blur support.</p> +<div id='log'></div> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +"use strict"; + +const constraintSet = { + backgroundBlur: true +}; + +Object.keys(constraintSet).forEach(property => { + test(t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + assert_implements_optional( + supportedConstraints[property], + `Optional property ${property} not in supported constraints`); + }, `Test getSupportedConstraints().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + assert_equals(typeof videoTrack.getCapabilities, 'function'); + const capabilities = videoTrack.getCapabilities(); + assert_equals(typeof capabilities, 'object'); + + if (!supportedConstraints[property]) { + assert_false(property in capabilities); + } + + assert_implements_optional( + property in capabilities, + `Optional property ${property} not in capabilities`); + + // Accept [false], [false, true], [true] and [true, false]. + assert_array_equals( + capabilities[property], + capabilities[property].length == 1 + ? [!!capabilities[property][0]] + : [!!capabilities[property][0], !capabilities[property][0]]); + }, `Test getCapabilities().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + const capabilities = videoTrack.getCapabilities(); + + assert_equals(typeof videoTrack.getSettings, 'function'); + const settings = videoTrack.getSettings(); + assert_equals(typeof settings, 'object'); + + if (!supportedConstraints[property] || !(property in capabilities)) + assert_false(property in settings); + + assert_implements_optional( + property in capabilities, + `Optional property ${property} not in capabilities`); + + assert_in_array(settings[property], capabilities[property]); + }, `Test getSettings().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + const capabilities = videoTrack.getCapabilities(); + const constraints = {advanced: [{ + [property]: constraintSet[property] + }]}; + const oldSettings = videoTrack.getSettings(); + + if (supportedConstraints[property] && !(property in capabilities)) { + // The user agent supports |constraints| but |videoTrack| is not capable + // to apply them. + await videoTrack.applyConstraints(constraints).then( + () => { + assert_unreached('Unexpected success applying constraints'); + }, + error => {}); + } else { + // The user agent does not support |constraints| and will ignore them or + // the user agent supports |constraints| and |videoTrack| is capable to + // apply them. + await videoTrack.applyConstraints(constraints).then( + () => {}, + error => { + assert_unreached(`Error applying constraints: ${error.message}`); + }); + } + + assert_equals(typeof videoTrack.getConstraints, 'function'); + const appliedConstraints = videoTrack.getConstraints(); + assert_equals(typeof appliedConstraints, 'object'); + const newSettings = videoTrack.getSettings(); + + if (!supportedConstraints[property] || !(property in capabilities)) { + // The user agent does not support |constraints| and ignored them or + // the user agent supports |constraints| but |videoTrack| was not capable + // to apply them. + assert_object_equals(appliedConstraints, {}); + } else { + // The user agent supports |constraints| and |videoTrack| was capable to + // apply them. + assert_object_equals(appliedConstraints, constraints); + } + + if (!supportedConstraints[property] || !(property in capabilities) || + !capabilities[property].includes(constraintSet[property])) { + // The user agent does not support |constraints| and ignored them or + // the user agent supports |constraints| but |videoTrack| was not capable + // to apply them or the user agent supports |constraints| and + // |videoTrack| was capable to apply them but could not satisfy advanced + // constraints and skipped them. + assert_object_equals(newSettings, oldSettings); + } else { + // The user agent supports |constraints| and |videoTrack| was capable to + // apply them and could satisfy advanced constraints. + assert_equals(newSettings[property], constraintSet[property]); + } + }, `Test applyConstraints() with ${property}`); +}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/mediacapture-extensions/GUM-faceFraming.https.html b/testing/web-platform/tests/mediacapture-extensions/GUM-faceFraming.https.html new file mode 100644 index 0000000000..ef45720621 --- /dev/null +++ b/testing/web-platform/tests/mediacapture-extensions/GUM-faceFraming.https.html @@ -0,0 +1,150 @@ +<!DOCTYPE html> +<html> +<head> +<title>Test face framing support</title> +<link rel="help" href="https://w3c.github.io/mediacapture-extensions/"> +</head> +<body> +<h1 class="instructions">Description</h1> +<p class="instructions">This test checks face framing support.</p> +<div id='log'></div> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +"use strict"; + +const constraintSet = { + faceFraming: true +}; + +Object.keys(constraintSet).forEach(property => { + test(t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + assert_implements_optional( + supportedConstraints[property], + `Optional property ${property} not in supported constraints`); + }, `Test getSupportedConstraints().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + assert_equals(typeof videoTrack.getCapabilities, 'function'); + const capabilities = videoTrack.getCapabilities(); + assert_equals(typeof capabilities, 'object'); + + if (!supportedConstraints[property]) { + assert_false(property in capabilities); + } + + assert_implements_optional( + property in capabilities, + `Optional property ${property} not in capabilities`); + + // Accept [false], [false, true], [true] and [true, false]. + assert_array_equals( + capabilities[property], + capabilities[property].length == 1 + ? [!!capabilities[property][0]] + : [!!capabilities[property][0], !capabilities[property][0]]); + }, `Test getCapabilities().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + const capabilities = videoTrack.getCapabilities(); + + assert_equals(typeof videoTrack.getSettings, 'function'); + const settings = videoTrack.getSettings(); + assert_equals(typeof settings, 'object'); + + if (!supportedConstraints[property] || !(property in capabilities)) + assert_false(property in settings); + + assert_implements_optional( + property in capabilities, + `Optional property ${property} not in capabilities`); + + assert_in_array(settings[property], capabilities[property]); + }, `Test getSettings().${property}`); + + promise_test(async t => { + const supportedConstraints = + navigator.mediaDevices.getSupportedConstraints(); + + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + assert_equals(stream.getAudioTracks().length, 0); + assert_equals(stream.getVideoTracks().length, 1); + const [videoTrack] = stream.getVideoTracks(); + + const capabilities = videoTrack.getCapabilities(); + const constraints = { + [property]: {exact: constraintSet[property]} + }; + const oldSettings = videoTrack.getSettings(); + + if (supportedConstraints[property] && !(property in capabilities)) { + // The user agent supports |constraints| but |videoTrack| is not capable + // to apply them. + await videoTrack.applyConstraints(constraints).then( + () => { + assert_unreached('Unexpected success applying constraints'); + }, + error => {}); + } else { + // The user agent does not support |constraints| and will ignore them or + // the user agent supports |constraints| and |videoTrack| is capable to + // apply them. + await videoTrack.applyConstraints(constraints).then( + () => {}, + error => { + assert_unreached(`Error applying constraints: ${error.message}`); + }); + } + + assert_equals(typeof videoTrack.getConstraints, 'function'); + const appliedConstraints = videoTrack.getConstraints(); + assert_equals(typeof appliedConstraints, 'object'); + const newSettings = videoTrack.getSettings(); + + if (!supportedConstraints[property] || !(property in capabilities)) { + // The user agent does not support |constraints| and ignored them or + // the user agent supports |constraints| but |videoTrack| was not capable + // to apply them. + assert_object_equals(appliedConstraints, {}); + } else { + // The user agent supports |constraints| and |videoTrack| was capable to + // apply them. + assert_object_equals(appliedConstraints, constraints); + } + + if (!supportedConstraints[property] || !(property in capabilities) || + !capabilities[property].includes(constraintSet[property])) { + // The user agent does not support |constraints| and ignored them or + // the user agent supports |constraints| but |videoTrack| was not capable + // to apply them or the user agent supports |constraints| and + // |videoTrack| was capable to apply them but could not satisfy advanced + // constraints and skipped them. + assert_object_equals(newSettings, oldSettings); + } else { + // The user agent supports |constraints| and |videoTrack| was capable to + // apply them and could satisfy advanced constraints. + assert_equals(newSettings[property], constraintSet[property]); + } + }, `Test applyConstraints() with ${property}`); +}); +</script> +</body> +</html> diff --git a/testing/web-platform/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html b/testing/web-platform/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html new file mode 100644 index 0000000000..f1b6a2074a --- /dev/null +++ b/testing/web-platform/tests/mediacapture-extensions/MediaStreamTrack-video-stats.https.html @@ -0,0 +1,353 @@ +<!doctype html> +<meta charset=utf-8> +<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'; + +async function getFrameStatsUntil(track, condition) { + while (true) { + const stats = track.stats.toJSON(); + if (condition(stats)) { + return stats; + } + // Repeat in the next task execution cycle. + await Promise.resolve(); + } +} + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + const firstStats = + await getFrameStatsUntil(track, stats => stats.totalFrames > 0); + await getFrameStatsUntil(track, + stats => stats.totalFrames > firstStats.totalFrames); +}, `totalFrames increases over time`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // `deliveredFrames` increments for each deliverable frame, even if the + // `track` does not have any sink. + const firstStats = await getFrameStatsUntil( + track, stats => stats.deliveredFrames > 0); + await getFrameStatsUntil( + track, stats => stats.deliveredFrames > firstStats.deliveredFrames); +}, `deliveredFrames increases, even without sinks`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(track.getSettings().frameRate, 10); + await track.applyConstraints({frameRate:{ideal:10}}); + + await getFrameStatsUntil(track, stats => stats.discardedFrames > 0); +}, `discardedFrames increases when frameRate decimation is happening`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // Hold a reference directly to the [SameObject] stats, bypassing the + // `track.stats` getter in the subsequent getting of `totalFrames`. + const stats = track.stats; + const firstTotalFrames = stats.totalFrames; + while (stats.totalFrames == firstTotalFrames) { + await Promise.resolve(); + } + assert_greater_than(stats.totalFrames, firstTotalFrames); +}, `Counters increase even if we don't call the track.stats getter`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + const firstTotalFrames = track.stats.totalFrames; + // Busy-loop for 100 ms, all within the same task execution cycle. + const firstTimeMs = performance.now(); + while (performance.now() - firstTimeMs < 100) {} + // The frame counter should not have changed. + assert_equals(track.stats.totalFrames, firstTotalFrames); +}, `Counters do not increase in the same task execution cycle`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(track.getSettings().frameRate, 10); + await track.applyConstraints({frameRate:{ideal:10}}); + + // Wait until we have both delivered and discarded frames. + const stats = await getFrameStatsUntil(track, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // This test assumes that no frames are dropped, otherwise `totalFrames` can + // be greater than the sum of `deliveredFrames` and `discardedFrames`. + assert_equals(stats.totalFrames, + stats.deliveredFrames + stats.discardedFrames); +}, `totalFrames is the sum of deliveredFrames and discardedFrames`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + const a = track.stats; + await getFrameStatsUntil(track, stats => stats.totalFrames > 0); + const b = track.stats; + // The counters may have changed, but `a` and `b` are still the same object. + assert_equals(a, b); +}, `SameObject policy applies`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(track.getSettings().frameRate, 10); + await track.applyConstraints({frameRate:{ideal:10}}); + + // Wait for media to flow before disabling the `track`. + const initialStats = await getFrameStatsUntil(track, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0 && + stats.totalFrames > 10); + track.enabled = false; + // Upon disabling, the counters are not reset. + const disabledSnapshot = track.stats.toJSON(); + assert_greater_than_equal(disabledSnapshot.deliveredFrames, + initialStats.deliveredFrames); + assert_greater_than_equal(disabledSnapshot.discardedFrames, + initialStats.discardedFrames); + assert_greater_than_equal(disabledSnapshot.totalFrames, + initialStats.totalFrames); + + // Wait enough time that frames should have been produced. + await new Promise(r => t.step_timeout(r, 500)); + + // Frame metrics should be frozen, but because `enabled = false` does not + // return a promise, we allow some lee-way in case a frame was still in flight + // during the disabling. + assert_approx_equals( + track.stats.deliveredFrames, disabledSnapshot.deliveredFrames, 1); + assert_approx_equals( + track.stats.discardedFrames, disabledSnapshot.discardedFrames, 1); + assert_approx_equals( + track.stats.totalFrames, disabledSnapshot.totalFrames, 1); +}, `Stats are frozen while disabled`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(track.getSettings().frameRate, 10); + await track.applyConstraints({frameRate:{ideal:10}}); + + // Wait for media to flow before disabling the `track`. + const initialStats = await getFrameStatsUntil(track, stats => + stats.deliveredFrames > 10 && stats.discardedFrames > 10); + track.enabled = false; + + // Re-enable the track. The stats counters should be greater than or equal to + // what they were previously. + track.enabled = true; + assert_greater_than_equal(track.stats.deliveredFrames, + initialStats.deliveredFrames); + assert_greater_than_equal(track.stats.discardedFrames, + initialStats.discardedFrames); + assert_greater_than_equal(track.stats.totalFrames, + initialStats.totalFrames); +}, `Disabling and re-enabling does not reset the counters`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [originalTrack] = stream.getTracks(); + t.add_cleanup(() => originalTrack.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(originalTrack.getSettings().frameRate, 10); + await originalTrack.applyConstraints({frameRate:{ideal:10}}); + + // Wait for media to flow before disabling the `track`. + await getFrameStatsUntil(originalTrack, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + originalTrack.enabled = false; + const originalTrackInitialStats = originalTrack.stats.toJSON(); + + // Clone the track, its counters should be zero initially. + // This is not racy because the cloned track is also disabled. + const clonedTrack = originalTrack.clone(); + t.add_cleanup(() => clonedTrack.stop()); + const clonedTrackStats = clonedTrack.stats.toJSON(); + assert_equals(clonedTrackStats.deliveredFrames, 0); + assert_equals(clonedTrackStats.discardedFrames, 0); + assert_equals(clonedTrackStats.totalFrames, 0); + + // Enabled the cloned track and wait for media to flow. + clonedTrack.enabled = true; + await getFrameStatsUntil(clonedTrack, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // This does not affect the original track's stats, which are still frozen due + // to the original track being disabled. + assert_equals(originalTrack.stats.deliveredFrames, + originalTrackInitialStats.deliveredFrames); + assert_equals(originalTrack.stats.discardedFrames, + originalTrackInitialStats.discardedFrames); + assert_equals(originalTrack.stats.totalFrames, + originalTrackInitialStats.totalFrames); +}, `New stats baselines when a track is cloned from a disabled track`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [originalTrack] = stream.getTracks(); + t.add_cleanup(() => originalTrack.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(originalTrack.getSettings().frameRate, 10); + await originalTrack.applyConstraints({frameRate:{ideal:10}}); + + // Wait for media to flow. + await getFrameStatsUntil(originalTrack, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // Clone the track. While its counters should initially be zero, it would be + // racy to assert that they are exactly zero because media is flowing. + const clonedTrack = originalTrack.clone(); + t.add_cleanup(() => clonedTrack.stop()); + + // Ensure that as media continues to flow, the cloned track will necessarily + // have less frames than the original track on all accounts since its counters + // will have started from zero. + const clonedTrackStats = await getFrameStatsUntil(clonedTrack, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + assert_less_than(clonedTrackStats.deliveredFrames, + originalTrack.stats.deliveredFrames); + assert_less_than(clonedTrackStats.discardedFrames, + originalTrack.stats.discardedFrames); + assert_less_than(clonedTrackStats.totalFrames, + originalTrack.stats.totalFrames); +}, `New stats baselines when a track is cloned from an enabled track`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ + video:{frameRate:{ideal:20}} + }); + const [originalTrack] = stream.getTracks(); + t.add_cleanup(() => originalTrack.stop()); + + // Assert test prerequisite is met: frames will be discarded if the track is + // opened with a higher frame rate than we apply after it is opened. + assert_greater_than(originalTrack.getSettings().frameRate, 10); + await originalTrack.applyConstraints({frameRate:{ideal:10}}); + + // Wait for media to flow. + await getFrameStatsUntil(originalTrack, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // Clone and wait for media to flow. + const cloneA = originalTrack.clone(); + t.add_cleanup(() => cloneA.stop()); + await getFrameStatsUntil(cloneA, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // Clone the clone and wait for media to flow. + const cloneB = cloneA.clone(); + t.add_cleanup(() => cloneB.stop()); + await getFrameStatsUntil(cloneB, stats => + stats.deliveredFrames > 0 && stats.discardedFrames > 0); + + // Because every clone reset its counters and every waits for media before + // cloning, this must be true: originalStats > cloneAStats > cloneBStats. + const originalStats = originalTrack.stats.toJSON(); + const cloneAStats = cloneA.stats.toJSON(); + const cloneBStats = cloneB.stats.toJSON(); + assert_greater_than(originalStats.totalFrames, cloneAStats.totalFrames); + assert_greater_than(cloneAStats.totalFrames, cloneBStats.totalFrames); +}, `New stats baselines for the clone of a clone`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video:true}); + const [originalTrack] = stream.getTracks(); + t.add_cleanup(() => originalTrack.stop()); + + // Wait for some frames and assert that no frames are discarded. + const firstStats = await getFrameStatsUntil(originalTrack, stats => + stats.deliveredFrames > 20); + assert_equals(firstStats.discardedFrames, 0); + // Make a clone that discards almost all frames. This should not affect the + // discarded frames counter of the original track. + const clonedTrack = originalTrack.clone(); + await clonedTrack.applyConstraints({frameRate:{ideal:1}}); + // Wait for some more frames. There should still be no frames discarded. + const secondStats = await getFrameStatsUntil(originalTrack, stats => + stats.deliveredFrames > 40); + assert_equals(secondStats.discardedFrames, 0); +}, `A low FPS clone does not affect the original track's discardedFrames`); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({audio:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + assert_equals(track.stats, null); +}, `track.stats is null on audio tracks`); + +promise_test(async t => { + const canvas = document.createElement('canvas'); + const stream = canvas.captureStream(10); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + assert_equals(track.stats, null); +}, `track.stats is null on non-device tracks, such as canvas`); + +promise_test(async t => { + // getDisplayMedia() requires inducing a user gesture. + const p = new Promise(r => button.onclick = r); + await test_driver.click(button); + await p; + + const stream = await navigator.mediaDevices.getDisplayMedia({video:true}); + const [track] = stream.getTracks(); + t.add_cleanup(() => track.stop()); + + await getFrameStatsUntil(track, stats => stats.totalFrames > 0) +}, `track.stats is supported on getDisplayMedia tracks`); +</script> |