chromium/third_party/blink/web_tests/fast/peerconnection/RTCPeerconnection-insertable-streams.html

<!DOCTYPE html>
<html>
  <head>
    <title>RTCPeerConnection Insertable Streams</title>
    <script src="../../resources/testharness.js"></script>
    <script src="../../resources/testharnessreport.js"></script>
    <script src="resources/RTCPeerConnection-helper.js"></script>
    <script src='../mediacapture-streams/permission-helper.js'></script>
  </head>
  <body>
    <script>
// Tests for the legacy variant of https://github.com/w3c/webrtc-encoded-transform
// See https://github.com/w3c/webrtc-encoded-transform/pull/111
// for the specification
promise_test(async t => {
  const pc = new RTCPeerConnection({encodedInsertableStreams: true});
  t.add_cleanup(() => pc.close());
  const configuration = pc.getConfiguration();
  assert_true(configuration.encodedInsertableStreams);
}, 'getConfiguration returns the encodedInsertableStreams parameter');

promise_test(async t => {
  const pc = new RTCPeerConnection({encodedInsertableStreams: false});
  t.add_cleanup(() => pc.close());
  assert_throws_dom('InvalidModificationError', () => {
    pc.setConfiguration({encodedInsertableStreams: true});
  })
}, 'setConfiguration rejects attempts to modify the encodedInsertableStreams parameter with an InvalidModificationError');

async function getOutboundStats(videoSender) {
      const stats = await videoSender.getStats();
      return [...stats.values()].find(s => s.type=='outbound-rtp');
}

async function getInboundStats(videoSender) {
      const stats = await videoSender.getStats();
      return [...stats.values()].find(s => s.type=='inbound-rtp');
}

promise_test(async t => {
  const caller = new RTCPeerConnection({encodedInsertableStreams: true});
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection();
  t.add_cleanup(() => callee.close());

  const stream = await navigator.mediaDevices.getUserMedia({video:true});
  const videoTrack = stream.getVideoTracks()[0];
  t.add_cleanup(() => videoTrack.stop());

  const videoSender = caller.addTrack(videoTrack)
  await exchangeIceCandidates(caller, callee);
  await exchangeOfferAnswer(caller, callee);

  // Wait until we've sent a frame to be transformed.
  await t.step_wait(async () => {
    const outboundStats = await getOutboundStats(videoSender);
    assert_true(!!outboundStats);
    return outboundStats.framesSent > 0;
  }, "Wait for a frame to be encoded", 3000);

  // Assert we've not actually sent any packets.
  const outboundStats = await getOutboundStats(videoSender);
  assert_equals(outboundStats.packetsSent, 0);
}, 'Senders with encodedInsertableStreams:true but no transform don\'t send packets');


promise_test(async t => {
  const caller = new RTCPeerConnection();
  t.add_cleanup(() => caller.close());
  const callee = new RTCPeerConnection({encodedInsertableStreams: true});
  t.add_cleanup(() => callee.close());

  const stream = await navigator.mediaDevices.getUserMedia({video:true});
  const videoTrack = stream.getVideoTracks()[0];
  t.add_cleanup(() => videoTrack.stop());

  const ontrackPromise = new Promise(resolve => {callee.ontrack = resolve});

  const videoSender = caller.addTrack(videoTrack)
  await exchangeIceCandidates(caller, callee);
  await exchangeOfferAnswer(caller, callee);

  await ontrackPromise;

  // Wait until we've received 10 packets.
  await t.step_wait(async () => {
    assert_equals(callee.getReceivers().length, 1);
    const inboundStats = await getInboundStats(callee.getReceivers()[0]);
    assert_true(!!inboundStats);
    return inboundStats.packetsReceived > 10;
  }, "Wait for packets to be received", 3000);

  // Assert we've not handled any frames.
  const inboundStats = await getInboundStats(callee.getReceivers()[0]);
  assert_equals(inboundStats.framesReceived, 0);
}, 'Receivers with encodedInsertableStreams:true but no transform don\'t receive frames');

promise_test(async t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  const transceiver = pc.addTransceiver("video");
  const {readable, writable} = transceiver.sender.createEncodedStreams();
  assert_true(!!readable);
  assert_true(!!writable);
}, 'createEncodedStreams can be called synchronously after sender creation without encodedInsertableStreams param');

promise_test(async t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  const transceiver = pc.addTransceiver("video");
  // Wait for an event loop spin.
  await new Promise(resolve => setTimeout(resolve));

  assert_throws_dom("InvalidStateError", () => {transceiver.sender.createEncodedStreams()});
}, 'createEncodedStreams cannot be called asynchronously after sender creation without encodedInsertableStreams param');

promise_test(async t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  const transceiver = pc.addTransceiver("video");
  const {readable, writable} = transceiver.receiver.createEncodedStreams();
  assert_true(!!readable);
  assert_true(!!writable);
}, 'createEncodedStreams can be called synchronously after receiver creation without encodedInsertableStreams param');

promise_test(async t => {
  const pc = new RTCPeerConnection();
  t.add_cleanup(() => pc.close());
  const transceiver = pc.addTransceiver("video");
  // Wait for an event loop spin.
  await new Promise(resolve => setTimeout(resolve));

  assert_throws_dom("InvalidStateError", () => {transceiver.receiver.createEncodedStreams()});
}, 'createEncodedStreams cannot be called asynchronously after receiver creation without encodedInsertableStreams param');
    </script>
  </body>
</html>