| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../resources/js-test-pre.js"></script> |
| </head> |
| <body> |
| <script> |
| if (window.internals) |
| internals.useMockRTCPeerConnectionFactory(""); |
| |
| description("Test RTCPeerConnection's legacy MediaStream-based API"); |
| |
| let stream; |
| let otherStream; |
| let audioTrack; |
| let videoTrack; |
| let audioTrackFoundAmongSenders; |
| let videoTrackFoundAmongSenders; |
| let remoteStream; |
| |
| if (window.testRunner) |
| testRunner.setUserMediaPermission(true); |
| else { |
| debug("This test can not be run without the testRunner"); |
| finishJSTest(); |
| } |
| |
| const pc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]}); |
| const remotePc = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]}); |
| |
| debug("Stream sets should be empty initially") |
| shouldBe("pc.getLocalStreams().length", "0"); |
| shouldBe("pc.getRemoteStreams().length", "0"); |
| |
| pc.onaddstream = evt => { |
| testPassed("Got 'addstream' event (before setRemoteDescription promise fulfilled)"); |
| remoteStream = evt.stream; |
| |
| shouldBe("remoteStream.getTracks().length", "2"); |
| |
| shouldBe("pc.getRemoteStreams().length", "1"); |
| shouldBe("pc.getRemoteStreams()[0]", "remoteStream"); |
| |
| shouldBe("pc.getStreamById(remoteStream.id)", "remoteStream"); |
| }; |
| |
| navigator.mediaDevices.getUserMedia({ "audio": true }) |
| .then(s => { |
| stream = s; |
| |
| debug("<br>Test with single track MediaStream"); |
| evalAndLog("audioTrack = stream.getAudioTracks()[0]"); |
| shouldNotThrow("pc.addStream(stream)"); |
| |
| shouldBe("pc.getLocalStreams().length", "1"); |
| shouldBe("pc.getLocalStreams()[0]", "stream"); |
| |
| shouldBe("pc.getStreamById(stream.id)", "stream"); |
| |
| shouldBe("pc.getSenders().length", "1"); |
| shouldBe("pc.getSenders()[0].track", "audioTrack"); |
| |
| debug("Adding the same stream again should be a no-op"); |
| shouldNotThrow("pc.addStream(stream)"); |
| shouldBe("pc.getLocalStreams().length", "1"); |
| |
| return navigator.mediaDevices.getUserMedia({ "audio": true, "video": true }); |
| }) |
| .then(s => { |
| stream = s; |
| |
| debug("<br>Test with audio and video MediaStream"); |
| evalAndLog("audioTrack = stream.getAudioTracks()[0]"); |
| evalAndLog("videoTrack = stream.getVideoTracks()[0]"); |
| |
| shouldNotThrow("pc.addStream(stream)"); |
| |
| shouldBe("pc.getLocalStreams().length", "2"); |
| shouldBeTrue("pc.getLocalStreams().includes(stream)"); |
| |
| shouldBe("pc.getStreamById(stream.id)", "stream"); |
| |
| shouldBe("pc.getSenders().length", "3"); |
| |
| audioTrackFoundAmongSenders = false; |
| videoTrackFoundAmongSenders = false; |
| pc.getSenders().forEach(sender => { |
| if (sender.track === audioTrack) |
| audioTrackFoundAmongSenders = true; |
| else if (sender.track === videoTrack) |
| videoTrackFoundAmongSenders = true; |
| }); |
| |
| shouldBeTrue("audioTrackFoundAmongSenders"); |
| shouldBeTrue("videoTrackFoundAmongSenders"); |
| |
| debug("<br>Test removeStream"); |
| debug("Remove a non-existent stream"); |
| evalAndLog("otherStream = stream.clone()"); |
| shouldNotThrow("pc.removeStream(otherStream)"); |
| |
| debug("Both streams should still be present"); |
| shouldBe("pc.getLocalStreams().length", "2"); |
| |
| shouldNotThrow("pc.removeStream(stream)"); |
| |
| shouldBe("pc.getLocalStreams().length", "1"); |
| shouldBe("pc.getStreamById(stream.id)", "null"); |
| |
| debug("All senders should still be present") |
| shouldBe("pc.getSenders().length", "3"); |
| |
| debug("Removing the same stream again should be a no-op"); |
| shouldNotThrow("pc.removeStream(stream)"); |
| shouldBe("pc.getLocalStreams().length", "1"); |
| |
| debug("<br>Test applying a remote description offering a stream with two tracks"); |
| remotePc.addStream(stream); |
| |
| debug("Create remote offer"); |
| return remotePc.createOffer(); |
| }) |
| .then(remoteOffer => { |
| debug("Got remote offer, set it"); |
| return pc.setRemoteDescription(remoteOffer); |
| }) |
| .then(() => { |
| debug("Remote offer set"); |
| testPassed("End of test promise chain"); |
| debug(""); |
| |
| finishJSTest(); |
| }) |
| .catch(error => { |
| testFailed("Error in promise chain: " + error); |
| finishJSTest(); |
| }); |
| |
| window.jsTestIsAsync = true; |
| window.successfullyParsed = true; |
| </script> |
| <script src="../../resources/js-test-post.js"></script> |
| </body> |
| </html> |