forked from mirrors/gecko-dev
		
	MozReview-Commit-ID: CQzdR66hsXZ --HG-- rename : testing/web-platform/tests/progress-events/interface.html => testing/web-platform/tests/XMLHttpRequest/progressevent-interface.html rename : testing/web-platform/tests/cssom/MediaList.xhtml => testing/web-platform/tests/cssom/MediaList2.xhtml rename : testing/web-platform/tests/old-tests/submission/Microsoft/dragdrop/dragdrop_support.js => testing/web-platform/tests/html/editing/dnd/resources/dragdrop_support.js rename : testing/web-platform/tests/old-tests/submission/Microsoft/structuredclone/echo.js => testing/web-platform/tests/html/infrastructure/safe-passing-of-structured-data/echo.js rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/sandbox_011.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/sandbox_011.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_002.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_002.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_003.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_003.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_006.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_006.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_007.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_007.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_012.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_012.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_023.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_023.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_024.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_024.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_028.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_028.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/iframe_sandbox_029.htm => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/iframe_sandbox_029.htm rename : testing/web-platform/tests/old-tests/submission/Microsoft/sandbox/sandbox.pdf => testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/sandbox.pdf rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/023.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/023.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/050.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/050.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/067.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/067.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/069.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/069.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/075.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/075.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/077.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/077.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/078.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/078.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/079.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/079.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/101.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/101.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/106-import.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-import.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/106-noimport.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/106-noimport.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/107-import.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-import.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/107-noimport.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/107-noimport.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/111.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/111.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/112.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/112.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/119.html => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/119.html rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/css/background.css => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/background.css rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/css/import.css => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/css/import.css rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/count-script-tags.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/count-script-tags.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/find-body.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-body.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/find-foo.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/find-foo.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-1.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-1.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-10.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-10.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-11.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-11.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-2.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-2.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-3.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-3.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-4.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-4.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-5.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-5.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-6.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-6.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-7.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-7.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-8.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-8.js rename : testing/web-platform/tests/old-tests/submission/Opera/script_scheduling/scripts/include-9.js => testing/web-platform/tests/html/semantics/scripting-1/the-script-element/execution-timing/scripts/include-9.js rename : testing/web-platform/tests/assumptions/OWNERS => testing/web-platform/tests/infrastructure/assumptions/OWNERS rename : testing/web-platform/tests/assumptions/canvas-background-ref.html => testing/web-platform/tests/infrastructure/assumptions/canvas-background-ref.html rename : testing/web-platform/tests/assumptions/canvas-background.html => testing/web-platform/tests/infrastructure/assumptions/canvas-background.html rename : testing/web-platform/tests/assumptions/html-elements.html => testing/web-platform/tests/infrastructure/assumptions/html-elements.html rename : testing/web-platform/tests/assumptions/initial-color-ref.html => testing/web-platform/tests/infrastructure/assumptions/initial-color-ref.html rename : testing/web-platform/tests/assumptions/initial-color.html => testing/web-platform/tests/infrastructure/assumptions/initial-color.html rename : testing/web-platform/tests/assumptions/medium-font-size-ref.html => testing/web-platform/tests/infrastructure/assumptions/medium-font-size-ref.html rename : testing/web-platform/tests/assumptions/medium-font-size.html => testing/web-platform/tests/infrastructure/assumptions/medium-font-size.html rename : testing/web-platform/tests/assumptions/min-font-size-ref.html => testing/web-platform/tests/infrastructure/assumptions/min-font-size-ref.html rename : testing/web-platform/tests/assumptions/min-font-size.html => testing/web-platform/tests/infrastructure/assumptions/min-font-size.html rename : testing/web-platform/tests/assumptions/tools/build.sh => testing/web-platform/tests/infrastructure/assumptions/tools/build.sh rename : testing/web-platform/tests/infrastructure/failing-test.html => testing/web-platform/tests/infrastructure/expected-fail/failing-test.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-exception.html => testing/web-platform/tests/requestidlecallback/callback-exception.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-idle-periods.html => testing/web-platform/tests/requestidlecallback/callback-idle-periods.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-iframe.html => testing/web-platform/tests/requestidlecallback/callback-iframe.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-invoked.html => testing/web-platform/tests/requestidlecallback/callback-invoked.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-multiple-calls.html => testing/web-platform/tests/requestidlecallback/callback-multiple-calls.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-removed-frame.html => testing/web-platform/tests/requestidlecallback/callback-removed-frame.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-timeout-with-raf.html => testing/web-platform/tests/requestidlecallback/callback-timeout-with-raf.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-timeout.html => testing/web-platform/tests/requestidlecallback/callback-timeout.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/callback-xhr-sync.html => testing/web-platform/tests/requestidlecallback/callback-xhr-sync.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/cancel-invoked.html => testing/web-platform/tests/requestidlecallback/cancel-invoked.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/idlharness.html => testing/web-platform/tests/requestidlecallback/idlharness.html rename : testing/web-platform/tests/html/webappapis/idle-callbacks/resources/post_name_on_load.html => testing/web-platform/tests/requestidlecallback/resources/post_name_on_load.html rename : testing/web-platform/tests/webrtc/RTCDTMFSender-insertDTMF.html => testing/web-platform/tests/webrtc/RTCDTMFSender-insertDTMF.https.html rename : testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange-long.html => testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange-long.https.html rename : testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.html => testing/web-platform/tests/webrtc/RTCDTMFSender-ontonechange.https.html rename : testing/web-platform/tests/webrtc/RTCPeerConnection-addTrack.html => testing/web-platform/tests/webrtc/RTCPeerConnection-addTrack.https.html rename : testing/web-platform/tests/webrtc/RTCPeerConnection-ontrack.html => testing/web-platform/tests/webrtc/RTCPeerConnection-ontrack.https.html rename : testing/web-platform/tests/webrtc/RTCPeerConnection-removeTrack.html => testing/web-platform/tests/webrtc/RTCPeerConnection-removeTrack.https.html rename : testing/web-platform/tests/webrtc/RTCRtpReceiver-getContributingSources.html => testing/web-platform/tests/webrtc/RTCRtpReceiver-getContributingSources.https.html rename : testing/web-platform/tests/webrtc/RTCRtpReceiver-getSynchronizationSources.html => testing/web-platform/tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html
		
			
				
	
	
		
			285 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!doctype html>
 | 
						|
<meta charset=utf-8>
 | 
						|
<title>RTCPeerConnection.prototype.addTrack</title>
 | 
						|
<script src="/resources/testharness.js"></script>
 | 
						|
<script src="/resources/testharnessreport.js"></script>
 | 
						|
<script src="RTCPeerConnection-helper.js"></script>
 | 
						|
<script>
 | 
						|
  'use strict';
 | 
						|
 | 
						|
  // Test is based on the following editor draft:
 | 
						|
  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
 | 
						|
 | 
						|
  // The following helper functions are called from RTCPeerConnection-helper.js:
 | 
						|
  // generateMediaStreamTrack
 | 
						|
 | 
						|
  /*
 | 
						|
    5.1.  RTCPeerConnection Interface Extensions
 | 
						|
      partial interface RTCPeerConnection {
 | 
						|
        ...
 | 
						|
        sequence<RTCRtpSender>      getSenders();
 | 
						|
        sequence<RTCRtpReceiver>    getReceivers();
 | 
						|
        sequence<RTCRtpTransceiver> getTransceivers();
 | 
						|
        RTCRtpSender                addTrack(MediaStreamTrack track,
 | 
						|
                                             MediaStream... streams);
 | 
						|
        RTCRtpTransceiver           addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
 | 
						|
                                                   optional RTCRtpTransceiverInit init);
 | 
						|
      };
 | 
						|
 | 
						|
      Note
 | 
						|
        While addTrack checks if the MediaStreamTrack given as an argument is
 | 
						|
        already being sent to avoid sending the same MediaStreamTrack twice,
 | 
						|
        the other ways do not, allowing the same MediaStreamTrack to be sent
 | 
						|
        several times simultaneously.
 | 
						|
   */
 | 
						|
 | 
						|
  /*
 | 
						|
    5.1.  addTrack
 | 
						|
      4.  If connection's [[isClosed]] slot is true, throw an InvalidStateError.
 | 
						|
   */
 | 
						|
  promise_test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    return navigator.mediaDevices.getUserMedia({ audio: true })
 | 
						|
    .then(mediaStream => {
 | 
						|
      const tracks = mediaStream.getTracks();
 | 
						|
      assert_greater_than(tracks.length, 0,
 | 
						|
        'Expect getUserMedia to return at least one audio track');
 | 
						|
 | 
						|
      const track = tracks[0];
 | 
						|
 | 
						|
      pc.close();
 | 
						|
      assert_throws('InvalidStateError', () => pc.addTrack(track, mediaStream))
 | 
						|
    });
 | 
						|
  }, 'addTrack when pc is closed should throw InvalidStateError');
 | 
						|
 | 
						|
  /*
 | 
						|
    5.1.  addTrack
 | 
						|
      8.  If sender is null, run the following steps:
 | 
						|
          1.  Create an RTCRtpSender with track and streams and let sender be
 | 
						|
              the result.
 | 
						|
          2.  Create an RTCRtpReceiver with track.kind as kind and let receiver
 | 
						|
              be the result.
 | 
						|
          3.  Create an RTCRtpTransceiver with sender and receiver and let
 | 
						|
              transceiver be the result.
 | 
						|
          4.  Add transceiver to connection's set of transceivers.
 | 
						|
   */
 | 
						|
  promise_test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    return navigator.mediaDevices.getUserMedia({ audio: true })
 | 
						|
    .then(mediaStream => {
 | 
						|
      const tracks = mediaStream.getTracks();
 | 
						|
      assert_greater_than(tracks.length, 0,
 | 
						|
        'Expect getUserMedia to return at least one audio track');
 | 
						|
 | 
						|
      const track = tracks[0];
 | 
						|
      const sender = pc.addTrack(track);
 | 
						|
 | 
						|
      assert_true(sender instanceof RTCRtpSender,
 | 
						|
        'Expect sender to be instance of RTCRtpSender');
 | 
						|
 | 
						|
      assert_equals(sender.track, track,
 | 
						|
        `Expect sender's track to be the added track`);
 | 
						|
 | 
						|
      const transceivers = pc.getTransceivers();
 | 
						|
      assert_equals(transceivers.length, 1,
 | 
						|
        'Expect only one transceiver with sender added');
 | 
						|
 | 
						|
      const [transceiver] = transceivers;
 | 
						|
      assert_equals(transceiver.sender, sender);
 | 
						|
 | 
						|
      assert_array_equals([sender], pc.getSenders(),
 | 
						|
        'Expect only one sender with given track added');
 | 
						|
 | 
						|
      const { receiver } = transceiver;
 | 
						|
      assert_equals(receiver.track.kind, 'audio');
 | 
						|
      assert_array_equals([transceiver.receiver], pc.getReceivers(),
 | 
						|
        'Expect only one receiver associated with transceiver added');
 | 
						|
    });
 | 
						|
  }, 'addTrack with single track argument and no mediaStream should succeed');
 | 
						|
 | 
						|
  promise_test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    return navigator.mediaDevices.getUserMedia({ audio: true })
 | 
						|
    .then(mediaStream => {
 | 
						|
      const tracks = mediaStream.getTracks();
 | 
						|
      assert_greater_than(tracks.length, 0,
 | 
						|
        'Expect getUserMedia to return at least one audio track');
 | 
						|
 | 
						|
      const track = tracks[0];
 | 
						|
      const sender = pc.addTrack(track, mediaStream);
 | 
						|
 | 
						|
      assert_true(sender instanceof RTCRtpSender,
 | 
						|
        'Expect sender to be instance of RTCRtpSender');
 | 
						|
 | 
						|
      assert_equals(sender.track, track,
 | 
						|
        `Expect sender's track to be the added track`);
 | 
						|
    });
 | 
						|
  }, 'addTrack with single track argument and single mediaStream should succeed');
 | 
						|
 | 
						|
  promise_test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    return navigator.mediaDevices.getUserMedia({ audio: true })
 | 
						|
    .then(mediaStream => {
 | 
						|
      const tracks = mediaStream.getTracks();
 | 
						|
      assert_greater_than(tracks.length, 0,
 | 
						|
        'Expect getUserMedia to return at least one audio track');
 | 
						|
 | 
						|
      const track = tracks[0];
 | 
						|
      const mediaStream2 = new MediaStream([track]);
 | 
						|
      const sender = pc.addTrack(track, mediaStream, mediaStream2);
 | 
						|
 | 
						|
      assert_true(sender instanceof RTCRtpSender,
 | 
						|
        'Expect sender to be instance of RTCRtpSender');
 | 
						|
 | 
						|
      assert_equals(sender.track, track,
 | 
						|
        `Expect sender's track to be the added track`);
 | 
						|
    });
 | 
						|
  }, 'addTrack with single track argument and multiple mediaStreams should succeed');
 | 
						|
 | 
						|
  /*
 | 
						|
    5.1.  addTrack
 | 
						|
      5.  Let senders be the result of executing the CollectSenders algorithm.
 | 
						|
          If an RTCRtpSender for track already exists in senders, throw an
 | 
						|
          InvalidAccessError.
 | 
						|
   */
 | 
						|
  promise_test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    return navigator.mediaDevices.getUserMedia({ audio: true })
 | 
						|
    .then(mediaStream => {
 | 
						|
      const tracks = mediaStream.getTracks();
 | 
						|
      assert_greater_than(tracks.length, 0,
 | 
						|
        'Expect getUserMedia to return at least one audio track');
 | 
						|
 | 
						|
      const track = tracks[0];
 | 
						|
 | 
						|
      pc.addTrack(track, mediaStream);
 | 
						|
      assert_throws('InvalidAccessError', () => pc.addTrack(track, mediaStream));
 | 
						|
    });
 | 
						|
  }, 'Adding the same track multiple times should throw InvalidAccessError');
 | 
						|
 | 
						|
  /*
 | 
						|
    5.1.  addTrack
 | 
						|
      6.  The steps below describe how to determine if an existing sender can
 | 
						|
          be reused.
 | 
						|
 | 
						|
          If any RTCRtpSender object in senders matches all the following
 | 
						|
          criteria, let sender be that object, or null otherwise:
 | 
						|
            - The sender's track is null.
 | 
						|
            - The transceiver kind of the RTCRtpTransceiver, associated with
 | 
						|
              the sender, matches track's kind.
 | 
						|
            - The sender has never been used to send. More precisely, the
 | 
						|
              RTCRtpTransceiver associated with the sender has never had a
 | 
						|
              currentDirection of sendrecv or sendonly.
 | 
						|
      7.  If sender is not null, run the following steps to use that sender:
 | 
						|
          1.  Set sender.track to track.
 | 
						|
          3.  Enable sending direction on the RTCRtpTransceiver associated
 | 
						|
              with sender.
 | 
						|
   */
 | 
						|
  test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    const transceiver = pc.addTransceiver('audio', { direction: 'recvonly' });
 | 
						|
    assert_equals(transceiver.sender.track, null);
 | 
						|
    assert_equals(transceiver.direction, 'recvonly');
 | 
						|
 | 
						|
    const track = generateMediaStreamTrack('audio');
 | 
						|
    const sender = pc.addTrack(track);
 | 
						|
 | 
						|
    assert_equals(sender, transceiver.sender);
 | 
						|
    assert_equals(sender.track, track);
 | 
						|
    assert_equals(transceiver.direction, 'sendrecv');
 | 
						|
    assert_array_equals([sender], pc.getSenders());
 | 
						|
 | 
						|
  }, 'addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender');
 | 
						|
 | 
						|
  test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    const transceiver = pc.addTransceiver('audio');
 | 
						|
    assert_equals(transceiver.sender.track, null);
 | 
						|
    assert_equals(transceiver.direction, 'sendrecv');
 | 
						|
 | 
						|
    const track = generateMediaStreamTrack('audio');
 | 
						|
    const sender = pc.addTrack(track);
 | 
						|
 | 
						|
    assert_equals(sender.track, track);
 | 
						|
    assert_not_equals(sender, transceiver.sender);
 | 
						|
 | 
						|
    const senders = pc.getSenders();
 | 
						|
    assert_equals(senders.length, 2,
 | 
						|
      'Expect 2 senders added to connection');
 | 
						|
 | 
						|
    assert_true(senders.includes(sender),
 | 
						|
      'Expect senders list to include sender');
 | 
						|
 | 
						|
    assert_true(senders.includes(transceiver.sender),
 | 
						|
      `Expect senders list to include first transceiver's sender`);
 | 
						|
 | 
						|
  }, 'addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender');
 | 
						|
 | 
						|
  test(t => {
 | 
						|
    const pc = new RTCPeerConnection();
 | 
						|
 | 
						|
    const transceiver = pc.addTransceiver('video', { direction: 'recvonly' });
 | 
						|
    assert_equals(transceiver.sender.track, null);
 | 
						|
    assert_equals(transceiver.direction, 'recvonly');
 | 
						|
 | 
						|
    const track = generateMediaStreamTrack('audio');
 | 
						|
    const sender = pc.addTrack(track);
 | 
						|
 | 
						|
    assert_equals(sender.track, track);
 | 
						|
    assert_not_equals(sender, transceiver.sender);
 | 
						|
 | 
						|
    const senders = pc.getSenders();
 | 
						|
    assert_equals(senders.length, 2,
 | 
						|
      'Expect 2 senders added to connection');
 | 
						|
 | 
						|
    assert_true(senders.includes(sender),
 | 
						|
      'Expect senders list to include sender');
 | 
						|
 | 
						|
    assert_true(senders.includes(transceiver.sender),
 | 
						|
      `Expect senders list to include first transceiver's sender`);
 | 
						|
 | 
						|
  }, 'addTrack with existing sender with null track, different kind, and recvonly direction should create new sender');
 | 
						|
 | 
						|
  /*
 | 
						|
    TODO
 | 
						|
      5.1.  addTrack
 | 
						|
        3.  Let streams be a list of MediaStream objects constructed from the
 | 
						|
            method's remaining arguments, or an empty list if the method was
 | 
						|
            called with a single argument.
 | 
						|
        6.  The steps below describe how to determine if an existing sender can
 | 
						|
            be reused. Doing so will cause future calls to createOffer and
 | 
						|
            createAnswer to mark the corresponding media description as sendrecv
 | 
						|
            or sendonly and add the MSID of the track added, as defined in [JSEP]
 | 
						|
            (section 5.2.2. and section 5.3.2.).
 | 
						|
        9.  A track could have contents that are inaccessible to the application.
 | 
						|
            This can be due to being marked with a peerIdentity option or anything
 | 
						|
            that would make a track CORS cross-origin. These tracks can be supplied
 | 
						|
            to the addTrack method, and have an RTCRtpSender created for them, but
 | 
						|
            content must not be transmitted, unless they are also marked with
 | 
						|
            peerIdentity and they meet the requirements for sending (see isolated
 | 
						|
            streams and RTCPeerConnection).
 | 
						|
 | 
						|
            All other tracks that are not accessible to the application must not be
 | 
						|
            sent to the peer, with silence (audio), black frames (video) or
 | 
						|
            equivalently absent content being sent in place of track content.
 | 
						|
 | 
						|
            Note that this property can change over time.
 | 
						|
 | 
						|
    Non-Testable
 | 
						|
      5.1.  addTrack
 | 
						|
        7.  If sender is not null, run the following steps to use that sender:
 | 
						|
          2.  Set sender's [[associated MediaStreams]] to streams.
 | 
						|
 | 
						|
    Tested in RTCPeerConnection-onnegotiationneeded.html:
 | 
						|
      5.1. addTrack
 | 
						|
        10. Update the negotiation-needed flag for connection.
 | 
						|
 | 
						|
   */
 | 
						|
</script>
 |