tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaStream-removetrack.https.html (5820B)


      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 src=/resources/testdriver.js></script>
     19 <script src=/resources/testdriver-vendor.js></script>
     20 <script src=permission-helper.js></script>
     21 <script>
     22 
     23 promise_test(async t => {
     24  await setMediaPermission();
     25  const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
     26  const tracks = stream.getTracks();
     27  t.add_cleanup(() => tracks.forEach(track => track.stop()));
     28  const stream2 = await navigator.mediaDevices.getUserMedia({audio: true});
     29  tracks.push(...stream2.getTracks());
     30 
     31  stream.onremovetrack = stream2.onremovetrack = t.step_func(() =>
     32    assert_unreached("onremovetrack is not triggered by script itself"));
     33 
     34  assert_equals(stream.getTracks().length, 2, "mediastream starts with 2 tracks");
     35  stream.removeTrack(stream.getVideoTracks()[0]);
     36  assert_equals(stream.getTracks().length, 1, "mediastream has 1 track left");
     37  stream.removeTrack(stream.getAudioTracks()[0]);
     38  assert_equals(stream.getTracks().length, 0, "mediastream has no tracks left");
     39  stream.removeTrack(stream2.getTracks()[0]); // should not throw
     40 
     41  // Allow time to verify no events fire.
     42  await new Promise(r => t.step_timeout(r, 1));
     43 
     44 }, "Tests that a removal from a MediaStream works as expected");
     45 
     46 async function doesEventFire(t, target, name, ms = 1) {
     47  const cookie = {};
     48  const value = await Promise.race([
     49    new Promise(r => target.addEventListener(name, r, {once: true})),
     50    new Promise(r => t.step_timeout(r, ms)).then(() => cookie)
     51  ]);
     52  return value !== cookie;
     53 }
     54 
     55 const doEventsFire = (t, target1, target2, name, ms = 1) => Promise.all([
     56  doesEventFire(t, target1, "ended", ms),
     57  doesEventFire(t, target2, "ended", ms)
     58 ]);
     59 
     60 promise_test(async t => {
     61  const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
     62  const tracks = stream.getTracks();
     63 
     64  audio.srcObject = video.srcObject = stream;
     65 
     66  t.add_cleanup(() => {
     67    for (const track of tracks) {
     68      track.stop();
     69    }
     70    audio.srcObject = video.srcObject = null;
     71  });
     72 
     73  await Promise.all([
     74    new Promise(r => audio.onloadedmetadata = r),
     75    new Promise(r => video.onloadedmetadata = r)
     76  ]);
     77 
     78  assert_equals(audio.ended, false, "audio element starts out not ended");
     79  assert_equals(video.ended, false, "video element starts out not ended");
     80 
     81  stream.removeTrack(stream.getVideoTracks()[0]);
     82  {
     83    const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
     84    assert_equals(audio.ended, false, "audio element unaffected");
     85    assert_equals(audioDidEnd, false, "no audio ended event should fire yet");
     86    assert_equals(video.ended, false, "video element keeps going with audio track");
     87    assert_equals(videoDidEnd, false, "no video ended event should fire yet");
     88  }
     89  stream.removeTrack(stream.getAudioTracks()[0]);
     90  {
     91    const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
     92    assert_equals(audio.ended, true, "audio element ended because no more audio tracks");
     93    assert_equals(audioDidEnd, true, "go audio ended event");
     94    assert_equals(video.ended, true, "video element ended because no more tracks");
     95    assert_equals(videoDidEnd, true, "got video ended event");
     96  }
     97 }, "Test that removal from a MediaStream fires ended on media elements (video first)");
     98 
     99 promise_test(async t => {
    100  const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
    101  const tracks = stream.getTracks();
    102 
    103  audio.srcObject = video.srcObject = stream;
    104 
    105  t.add_cleanup(() => {
    106    for (const track of tracks) {
    107      track.stop();
    108    }
    109    audio.srcObject = video.srcObject = null;
    110  });
    111 
    112  await Promise.all([
    113    new Promise(r => audio.onloadedmetadata = r),
    114    new Promise(r => video.onloadedmetadata = r)
    115  ]);
    116 
    117  assert_equals(audio.ended, false, "audio element starts out not ended");
    118  assert_equals(video.ended, false, "video element starts out not ended");
    119 
    120  stream.removeTrack(stream.getAudioTracks()[0]);
    121  {
    122    const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
    123    assert_equals(audio.ended, true, "audio element ended because no more audio tracks");
    124    assert_equals(audioDidEnd, true, "got audio ended event");
    125    assert_equals(video.ended, false, "video element keeps going with video track");
    126    assert_equals(videoDidEnd, false, "no video ended event should fire yet");
    127  }
    128  stream.removeTrack(stream.getVideoTracks()[0]);
    129  {
    130    const [audioDidEnd, videoDidEnd] = await doEventsFire(t, audio, video, "ended");
    131    assert_equals(audio.ended, true, "audio element remains ended from before");
    132    assert_equals(audioDidEnd, false, "no second audio ended event should fire");
    133    assert_equals(video.ended, true, "video element ended because no more tracks");
    134    assert_equals(videoDidEnd, true, "got video ended event");
    135  }
    136 }, "Test that removal from a MediaStream fires ended on media elements (audio first)");
    137 
    138 </script>
    139 </body>
    140 </html>