diff options
Diffstat (limited to 'dom/media/webrtc/tests/mochitests/test_peerConnection_replaceTrack.html')
-rw-r--r-- | dom/media/webrtc/tests/mochitests/test_peerConnection_replaceTrack.html | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/dom/media/webrtc/tests/mochitests/test_peerConnection_replaceTrack.html b/dom/media/webrtc/tests/mochitests/test_peerConnection_replaceTrack.html new file mode 100644 index 0000000000..9befc5c564 --- /dev/null +++ b/dom/media/webrtc/tests/mochitests/test_peerConnection_replaceTrack.html @@ -0,0 +1,187 @@ +<!DOCTYPE HTML> +<html> +<head> + <script type="application/javascript" src="pc.js"></script> +</head> +<body> +<pre id="test"> +<script type="application/javascript"> + createHTML({ + bug: "1032839", + title: "Replace video and audio (with WebAudio) tracks", + visible: true + }); + + function allLocalStreamsHaveSender(pc) { + return pc.getLocalStreams() + .every(s => s.getTracks() // Every local stream, + .some(t => pc.getSenders() // should have some track, + .some(sn => sn.track == t))) // that's being sent over |pc|. + } + + function allRemoteStreamsHaveReceiver(pc) { + return pc.getRemoteStreams() + .every(s => s.getTracks() // Every remote stream, + .some(t => pc.getReceivers() // should have some track, + .some(sn => sn.track == t))) // that's being received over |pc|. + } + + function replacetest(wrapper) { + var pc = wrapper._pc; + var oldSenderCount = pc.getSenders().length; + var sender = pc.getSenders().find(sn => sn.track.kind == "video"); + var oldTrack = sender.track; + ok(sender, "We have a sender for video"); + ok(allLocalStreamsHaveSender(pc), + "Shouldn't have any local streams without a corresponding sender"); + ok(allRemoteStreamsHaveReceiver(pc), + "Shouldn't have any remote streams without a corresponding receiver"); + + var newTrack; + var audiotrack; + return getUserMedia({video:true, audio:true}) + .then(newStream => { + window.grip = newStream; + newTrack = newStream.getVideoTracks()[0]; + audiotrack = newStream.getAudioTracks()[0]; + isnot(newTrack, sender.track, "replacing with a different track"); + ok(!pc.getLocalStreams().some(s => s == newStream), + "from a different stream"); + // Use wrapper function, since it updates expected tracks + return wrapper.senderReplaceTrack(sender, newTrack, newStream); + }) + .then(() => { + is(pc.getSenders().length, oldSenderCount, "same sender count"); + is(sender.track, newTrack, "sender.track has been replaced"); + ok(!pc.getSenders().map(sn => sn.track).some(t => t == oldTrack), + "old track not among senders"); + // Spec does not say we add this new track to any stream + ok(!pc.getLocalStreams().some(s => s.getTracks() + .some(t => t == sender.track)), + "track does not exist among pc's local streams"); + return sender.replaceTrack(audiotrack) + .then(() => ok(false, "replacing with different kind should fail"), + e => is(e.name, "TypeError", + "replacing with different kind should fail")); + }); + } + + runNetworkTest(function () { + test = new PeerConnectionTest(); + test.audioCtx = new AudioContext(); + test.setMediaConstraints([{video: true, audio: true}], [{video: true}]); + test.chain.removeAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW"); + + // Test replaceTrack on pcRemote separately since it's video only. + test.chain.append([ + function PC_REMOTE_VIDEOONLY_REPLACE_VIDEOTRACK(test) { + return replacetest(test.pcRemote); + }, + function PC_LOCAL_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW(test) { + return test.pcLocal.waitForMediaFlow(); + } + ]); + + // Replace video twice on pcLocal to make sure it still works + // (does audio twice too, but hey) + test.chain.append([ + function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_1(test) { + return replacetest(test.pcLocal); + }, + function PC_REMOTE_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW_1(test) { + return test.pcRemote.waitForMediaFlow(); + }, + function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_2(test) { + return replacetest(test.pcLocal); + }, + function PC_REMOTE_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW_2(test) { + return test.pcRemote.waitForMediaFlow(); + } + ]); + + test.chain.append([ + function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_WITHSAME(test) { + var pc = test.pcLocal._pc; + var sender = pc.getSenders().find(sn => sn.track.kind == "video"); + ok(sender, "should still have a sender of video"); + return sender.replaceTrack(sender.track) + .then(() => ok(true, "replacing with itself should succeed")); + }, + function PC_REMOTE_NEW_SAME_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW(test) { + return test.pcRemote.waitForMediaFlow(); + } + ]); + + // Replace the gUM audio track on pcLocal with a WebAudio track. + test.chain.append([ + function PC_LOCAL_AUDIOVIDEO_REPLACE_AUDIOTRACK_WEBAUDIO(test) { + var pc = test.pcLocal._pc; + var sender = pc.getSenders().find(sn => sn.track.kind == "audio"); + ok(sender, "track has a sender"); + var oldSenderCount = pc.getSenders().length; + var oldTrack = sender.track; + + var sourceNode = test.audioCtx.createOscillator(); + sourceNode.type = 'sine'; + // We need a frequency not too close to the fake audio track + // (440Hz for loopback devices, 1kHz for fake tracks). + sourceNode.frequency.value = 2000; + sourceNode.start(); + + var destNode = test.audioCtx.createMediaStreamDestination(); + sourceNode.connect(destNode); + var newTrack = destNode.stream.getAudioTracks()[0]; + + return test.pcLocal.senderReplaceTrack( + sender, newTrack, destNode.stream) + .then(() => { + is(pc.getSenders().length, oldSenderCount, "same sender count"); + ok(!pc.getSenders().some(sn => sn.track == oldTrack), + "Replaced track should be removed from senders"); + // TODO: Should PC remove local streams when there are no senders + // associated with it? getLocalStreams() isn't in the spec anymore, + // so I guess it is pretty arbitrary? + is(sender.track, newTrack, "sender.track has been replaced"); + // Spec does not say we add this new track to any stream + ok(!pc.getLocalStreams().some(s => s.getTracks() + .some(t => t == sender.track)), + "track exists among pc's local streams"); + }); + } + ]); + test.chain.append([ + function PC_LOCAL_CHECK_WEBAUDIO_FLOW_PRESENT(test) { + return test.pcRemote.checkReceivingToneFrom(test.audioCtx, test.pcLocal); + } + ]); + test.chain.append([ + function PC_LOCAL_INVALID_ADD_VIDEOTRACKS(test) { + let videoTransceivers = test.pcLocal._pc.getTransceivers() + .filter(transceiver => { + return !transceiver.stopped && + transceiver.receiver.track.kind == "video" && + transceiver.sender.track; + }); + + ok(videoTransceivers.length, + "There is at least one non-stopped video transceiver with a track."); + + videoTransceivers.forEach(transceiver => { + var stream = test.pcLocal._pc.getLocalStreams()[0];; + var track = transceiver.sender.track; + try { + test.pcLocal._pc.addTrack(track, stream); + ok(false, "addTrack existing track should fail"); + } catch (e) { + is(e.name, "InvalidAccessError", + "addTrack existing track should fail"); + } + }); + } + ]); + return test.run(); + }); +</script> +</pre> +</body> +</html> |