Update WPT mediacapture-streams tests
[WebKit-https.git] / LayoutTests / imported / w3c / web-platform-tests / mediacapture-streams / MediaStream-removetrack.https.html
1 <!doctype html>
2 <html>
3 <head>
4 <title>Removing a track from a MediaStream</title>
5 <link rel="author" title="Dominique Hazael-Massieux" href="mailto:dom@w3.org"/>
6 <link rel="help" href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html#widl-MediaStreamTrackList-remove-void-MediaStreamTrack-track">
7 <link rel="help" href="http://dev.w3.org/2011/webrtc/editor/getusermedia.html#event-mediastream-removetrack">
8 </head>
9 <body>
10 <p class="instructions">When prompted, accept to share your audio stream, then your video stream.</p>
11 <h1 class="instructions">Description</h1>
12 <p class="instructions">This test checks that removinging a track from a MediaStream works as expected.</p>
13 <video id="video" height="120" width="160" autoplay muted></video>
14 <audio id="audio" autoplay muted></audio>
15 <div id='log'></div>
16 <script src=/resources/testharness.js></script>
17 <script src=/resources/testharnessreport.js></script>
18 <script>
19
20 promise_test(async t => {
21   const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
22   const tracks = stream.getTracks();
23   t.add_cleanup(() => tracks.forEach(track => track.stop()));
24   const stream2 = await navigator.mediaDevices.getUserMedia({audio: true});
25   tracks.push(...stream2.getTracks());
26
27   stream.onremovetrack = stream2.onremovetrack = t.step_func(() =>
28     assert_unreached("onremovetrack is not triggered by script itself"));
29
30   assert_equals(stream.getTracks().length, 2, "mediastream starts with 2 tracks");
31   stream.removeTrack(stream.getVideoTracks()[0]);
32   assert_equals(stream.getTracks().length, 1, "mediastream has 1 track left");
33   stream.removeTrack(stream.getAudioTracks()[0]);
34   assert_equals(stream.getTracks().length, 0, "mediastream has no tracks left");
35   stream.removeTrack(stream2.getTracks()[0]); // should not throw
36
37   // Allow time to verify no events fire.
38   await new Promise(r => t.step_timeout(r, 1));
39
40 }, "Tests that a removal from a MediaStream works as expected");
41
42 async function doesEventFire(t, target, name, ms = 1) {
43   const cookie = {};
44   const value = await Promise.race([
45     new Promise(r => target.addEventListener(name, r, {once: true})),
46     new Promise(r => t.step_timeout(r, ms)).then(() => cookie)
47   ]);
48   return value !== cookie;
49 }
50
51 const doEventsFire = (t, target1, target2, name, ms = 1) => Promise.all([
52   doesEventFire(t, target1, "ended", ms),
53   doesEventFire(t, target2, "ended", ms)
54 ]);
55
56 promise_test(async t => {
57   const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
58   const tracks = stream.getTracks();
59
60   audio.srcObject = video.srcObject = stream;
61
62   t.add_cleanup(() => {
63     for (const track of tracks) {
64       track.stop();
65     }
66     audio.srcObject = video.srcObject = null;
67   });
68
69   await Promise.all([
70     new Promise(r => audio.onloadedmetadata = r),
71     new Promise(r => video.onloadedmetadata = r)
72   ]);
73
74   assert_equals(audio.ended, false, "audio element starts out not ended");
75   assert_equals(video.ended, false, "video element starts out not ended");
76
77   stream.removeTrack(stream.getVideoTracks()[0]);
78   {
79     const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
80     assert_equals(audio.ended, false, "audio element unaffected");
81     assert_equals(audioDidEnd, false, "no audio ended event should fire yet");
82     assert_equals(video.ended, false, "video element keeps going with audio track");
83     assert_equals(videoDidEnd, false, "no video ended event should fire yet");
84   }
85   stream.removeTrack(stream.getAudioTracks()[0]);
86   {
87     const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
88     assert_equals(audio.ended, true, "audio element ended because no more audio tracks");
89     assert_equals(audioDidEnd, true, "go audio ended event");
90     assert_equals(video.ended, true, "video element ended because no more tracks");
91     assert_equals(videoDidEnd, true, "got video ended event");
92   }
93 }, "Test that removal from a MediaStream fires ended on media elements (video first)");
94
95 promise_test(async t => {
96   const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
97   const tracks = stream.getTracks();
98
99   audio.srcObject = video.srcObject = stream;
100
101   t.add_cleanup(() => {
102     for (const track of tracks) {
103       track.stop();
104     }
105     audio.srcObject = video.srcObject = null;
106   });
107
108   await Promise.all([
109     new Promise(r => audio.onloadedmetadata = r),
110     new Promise(r => video.onloadedmetadata = r)
111   ]);
112
113   assert_equals(audio.ended, false, "audio element starts out not ended");
114   assert_equals(video.ended, false, "video element starts out not ended");
115
116   stream.removeTrack(stream.getAudioTracks()[0]);
117   {
118     const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
119     assert_equals(audio.ended, true, "audio element ended because no more audio tracks");
120     assert_equals(audioDidEnd, true, "got audio ended event");
121     assert_equals(video.ended, false, "video element keeps going with video track");
122     assert_equals(videoDidEnd, false, "no video ended event should fire yet");
123   }
124   stream.removeTrack(stream.getVideoTracks()[0]);
125   {
126     const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
127     assert_equals(audio.ended, true, "audio element remains ended from before");
128     assert_equals(audioDidEnd, false, "no second audio ended event should fire");
129     assert_equals(video.ended, true, "video element ended because no more tracks");
130     assert_equals(videoDidEnd, true, "got video ended event");
131   }
132 }, "Test that removal from a MediaStream fires ended on media elements (audio first)");
133
134 </script>
135 </body>
136 </html>