<!DOCTYPE HTML>
<html>
<head>
  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
</head>
<body>
<pre id="test">
<iframe id="iframe" onload="iframeLoaded()" srcdoc="
  <script type='application/javascript'>
  document.gUM = (constraints, success, failure) =>
    navigator.mediaDevices.getUserMedia(constraints).then(success, failure);
  </script>">
</iframe>
<script type="application/javascript">
  "use strict";
  let iframeLoadedPromise = {};
  iframeLoadedPromise.promise = new Promise(r => {
    iframeLoadedPromise.resolve = r;
  });;
  function iframeLoaded() {
    iframeLoadedPromise.resolve();
  }

  createHTML({
    title: "getUserMedia MediaStreamTrack 'ended' event on navigating",
    bug: "1208373",
  });

  runTest(async () => {
    await iframeLoadedPromise.promise;
    let iframe = document.getElementById("iframe");
    let stream;
    // We're passing callbacks into a method in the iframe here, because
    // a Promise created in the iframe is unusable after the iframe has
    // navigated away (see bug 1269400 for details).
    return new Promise((resolve, reject) =>
        iframe.contentDocument.gUM({audio: true, video: true}, resolve, reject))
      .then(s => {
        // We're cloning a stream containing identical tracks (an original
        // and its clone) to test that ended works both for originals
        // clones when they're both owned by the same MediaStream.
        // (Bug 1274221)
        stream = new MediaStream([].concat(s.getTracks(), s.getTracks())
                                   .map(t => t.clone())).clone();
        var allTracksEnded = Promise.all(stream.getTracks().map(t => {
          info("Set up ended handler for track " + t.id);
          return haveEvent(t, "ended", wait(50000))
            .then(event => {
              info("ended handler invoked for track " + t.id);
              is(event.target, t, "Target should be correct");
            }, e => e ? Promise.reject(e)
                      : ok(false, "ended event never raised for track " + t.id));
        }));
        stream.getTracks().forEach(t =>
          is(t.readyState, "live",
             "Non-ended track should have readyState 'live'"));
        iframe.srcdoc = "";
        info("iframe has been reset. Waiting for tracks to end.");
        return allTracksEnded;
      })
      .then(() => stream.getTracks().forEach(t =>
        is(t.readyState, "ended",
           "Ended track should have readyState 'ended'")));
  });
</script>
</pre>
</body>
</html>
