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-record/MediaRecorder-stop.html | |
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-record/MediaRecorder-stop.html')
-rw-r--r-- | testing/web-platform/tests/mediacapture-record/MediaRecorder-stop.html | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/testing/web-platform/tests/mediacapture-record/MediaRecorder-stop.html b/testing/web-platform/tests/mediacapture-record/MediaRecorder-stop.html new file mode 100644 index 0000000000..d6ce370772 --- /dev/null +++ b/testing/web-platform/tests/mediacapture-record/MediaRecorder-stop.html @@ -0,0 +1,197 @@ +<!doctype html> +<html> +<head> + <title>MediaRecorder Stop</title> + <meta name=variant content="?mimeType=''"> + <meta name=variant content="?mimeType=video/webm;codecs=vp8,opus"> + <meta name=variant content="?mimeType=video/webm;codecs=vp9,opus"> + <meta name=variant content="?mimeType=video/webm;codecs=av1,opus"> + <meta name=variant content="?mimeType=video/mp4;codecs=avc1,mp4a.40.2"> + <link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html#mediarecorder"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="utils/sources.js"></script> +</head> +<body> +<script> + function recordEvents(target, events) { + let arr = []; + for (let ev of events) { + target.addEventListener(ev, _ => arr.push(ev)); + } + return arr; + } + + // This function is used to check that elements of |actual| is a sub + // sequence in the |expected| sequence. + function assertSequenceIn(actual, expected) { + let i = 0; + for (event of actual) { + const j = expected.slice(i).indexOf(event); + assert_greater_than_equal( + j, 0, "Sequence element " + event + " is not included in " + + expected.slice(i)); + // Ensure duplicates in actual aren't silently accepted by skipping + // past the matched element. + i = j + 1; + } + return true; + } + + function doneWithUnsupportedType(mimeType) { + if (mimeType) { + assert_implements_optional(MediaRecorder.isTypeSupported(mimeType), + `"${mimeType}" for MediaRecorder is not supported`); + } + } + + const params = new URLSearchParams(window.location.search); + const mimeType = params.get('mimeType'); + const tag = `mimeType "${mimeType}"`; + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream: video} = createVideoStream(t); + const recorder = new MediaRecorder(video, {mimeType}); + const events = recordEvents(recorder, + ["start", "stop", "dataavailable", "pause", "resume", "error"]); + assert_equals(video.getVideoTracks().length, 1, "video mediastream starts with one track"); + recorder.start(); + assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully"); + video.getVideoTracks()[0].stop(); + assert_equals(recorder.state, "recording", "MediaRecorder state should be recording immediately following last track ending"); + const event = await new Promise(r => recorder.onstop = r); + + assert_equals(event.type, "stop", "the event type should be stop"); + assert_true(event.isTrusted, "isTrusted should be true when the event is created by C++"); + assert_equals(recorder.state, "inactive", "MediaRecorder is inactive after stop event"); + + // As the test is written, it's not guaranteed that + // onstart/ondataavailable is invoked, but it's fine if they are. + // The stop element is guaranteed to be in events when we get here. + assertSequenceIn(events, ["start", "dataavailable", "stop"]); + }, "MediaRecorder will stop recording and fire a stop event when all tracks are ended"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream: video} = createVideoStream(t); + const recorder = new MediaRecorder(video, {mimeType}); + const events = recordEvents(recorder, + ["start", "stop", "dataavailable", "pause", "resume", "error"]); + recorder.start(); + assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully"); + recorder.stop(); + assert_equals(recorder.state, "inactive", "MediaRecorder state should be inactive immediately following stop() call"); + + const event = await new Promise (r => recorder.onstop = r); + assert_equals(event.type, "stop", "the event type should be stop"); + assert_true(event.isTrusted, "isTrusted should be true when the event is created by C++"); + assert_equals(recorder.state, "inactive", "MediaRecorder is inactive after stop event"); + + // As the test is written, it's not guaranteed that + // onstart/ondataavailable is invoked, but it's fine if they are. + // The stop element is guaranteed to be in events when we get here. + assertSequenceIn(events, ["start", "dataavailable", "stop"]); + }, "MediaRecorder will stop recording and fire a stop event when stop() is called"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const recorder = new MediaRecorder(createVideoStream(t).stream, {mimeType}); + recorder.stop(); + await Promise.race([ + new Promise((_, reject) => recorder.onstop = + _ => reject(new Error("onstop should never have been called"))), + new Promise(r => t.step_timeout(r, 0))]); + }, "MediaRecorder will not fire an exception when stopped after creation"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const recorder = new MediaRecorder(createVideoStream(t).stream, {mimeType}); + recorder.start(); + recorder.stop(); + const event = await new Promise(r => recorder.onstop = r); + recorder.stop(); + await Promise.race([ + new Promise((_, reject) => recorder.onstop = + _ => reject(new Error("onstop should never have been called"))), + new Promise(r => t.step_timeout(r, 0))]); + }, "MediaRecorder will not fire an exception when stopped after having just been stopped"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream} = createVideoStream(t); + const recorder = new MediaRecorder(stream, {mimeType}); + recorder.start(); + stream.getVideoTracks()[0].stop(); + const event = await new Promise(r => recorder.onstop = r); + recorder.stop(); + await Promise.race([ + new Promise((_, reject) => recorder.onstop = + _ => reject(new Error("onstop should never have been called"))), + new Promise(r => t.step_timeout(r, 0))]); + }, "MediaRecorder will not fire an exception when stopped after having just been spontaneously stopped"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream} = createAudioVideoStream(t); + const recorder = new MediaRecorder(stream, {mimeType}); + const events = []; + const startPromise = new Promise(resolve => recorder.onstart = resolve); + const stopPromise = new Promise(resolve => recorder.onstop = resolve); + + startPromise.then(() => events.push("start")); + stopPromise.then(() => events.push("stop")); + + recorder.start(); + recorder.stop(); + + await stopPromise; + assert_array_equals(events, ["start", "stop"]); + }, "MediaRecorder will fire start event even if stopped synchronously"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream} = createAudioVideoStream(t); + const recorder = new MediaRecorder(stream, {mimeType}); + const events = []; + const startPromise = new Promise(resolve => recorder.onstart = resolve); + const stopPromise = new Promise(resolve => recorder.onstop = resolve); + const errorPromise = new Promise(resolve => recorder.onerror = resolve); + const dataPromise = new Promise(resolve => recorder.ondataavailable = resolve); + + startPromise.then(() => events.push("start")); + stopPromise.then(() => events.push("stop")); + errorPromise.then(() => events.push("error")); + dataPromise.then(() => events.push("data")); + + recorder.start(); + stream.removeTrack(stream.getAudioTracks()[0]); + + await stopPromise; + assert_array_equals(events, ["start", "error", "data", "stop"]); + }, "MediaRecorder will fire start event even if a track is removed synchronously"); + + promise_test(async t => { + doneWithUnsupportedType(mimeType); + + const {stream} = createFlowingAudioVideoStream(t); + const recorder = new MediaRecorder(stream, {mimeType}); + const events = recordEvents(recorder, + ["start", "stop", "dataavailable", "pause", "resume", "error"]); + const dataPromise = new Promise(r => recorder.ondataavailable = r); + recorder.start(0); + await dataPromise; + recorder.stop(); + await new Promise (r => recorder.onstop = r); + assertSequenceIn(events, ["start", "dataavailable", "stop"]); + }, "MediaRecorder will fire only start and stop events in a basic recording flow."); + +</script> +</body> +</html> |