188 lines
8.0 KiB
HTML
188 lines
8.0 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
|
<html>
|
|
<head>
|
|
<script src="../../resources/js-test-pre.js"></script>
|
|
<script src="resources/promise-utils.js"></script>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
let stream;
|
|
let offer;
|
|
|
|
description("Test setting up media between two RTCPeerConnection instances with a single SDP dialog.");
|
|
|
|
if (!window.testRunner) {
|
|
debug("This test can not be run without the testRunner");
|
|
finishJSTest();
|
|
}
|
|
|
|
debug("Create RTCPeerConnection A");
|
|
const pcA = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
|
|
|
|
shouldBe("pcA.signalingState", "'stable'");
|
|
shouldBeNull("pcA.pendingLocalDescription");
|
|
shouldBeNull("pcA.currentLocalDescription");
|
|
shouldBeNull("pcA.pendingRemoteDescription");
|
|
shouldBeNull("pcA.currentRemoteDescription");
|
|
|
|
debug("<br>Create RTCPeerConnection B");
|
|
const pcB = new RTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
|
|
|
|
shouldBe("pcB.signalingState", "'stable'");
|
|
shouldBeNull("pcB.pendingLocalDescription");
|
|
shouldBeNull("pcB.currentLocalDescription");
|
|
shouldBeNull("pcB.pendingRemoteDescription");
|
|
shouldBeNull("pcB.currentRemoteDescription");
|
|
debug("");
|
|
|
|
pcA.ontrack = function () {
|
|
debug("----------");
|
|
testPassed("A: got remote track event");
|
|
debug("----------");
|
|
};
|
|
|
|
pcB.ontrack = function () {
|
|
debug("----------");
|
|
testPassed("B: got remote track event");
|
|
debug("----------");
|
|
};
|
|
|
|
navigator.mediaDevices.getUserMedia({ "audio": true })
|
|
.then(function (s) {
|
|
stream = s;
|
|
|
|
debug("A: add media");
|
|
pcA.addTrack(stream.getAudioTracks()[0], stream);
|
|
|
|
debug("A: create offer");
|
|
return pcA.createOffer();
|
|
})
|
|
.then(function (offer) {
|
|
debug("A: got offer, set it as local description");
|
|
return pcA.setLocalDescription(offer);
|
|
})
|
|
.then(function () {
|
|
debug("A: local offer set");
|
|
shouldBe("pcA.signalingState", "'have-local-offer'");
|
|
shouldBeType("pcA.pendingLocalDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcA.currentLocalDescription");
|
|
|
|
debug("<br>A: send offer to B");
|
|
debug("A --- offer --> B");
|
|
debug("B: got offer from A, set it as remote description");
|
|
return pcB.setRemoteDescription(pcA.localDescription);
|
|
})
|
|
.then(function () {
|
|
debug("B: remote offer set");
|
|
shouldBe("pcB.signalingState", "'have-remote-offer'");
|
|
shouldBeType("pcB.pendingRemoteDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcB.currentRemoteDescription");
|
|
|
|
debug("<br>B: create answer (without local media)");
|
|
return pcB.createAnswer();
|
|
})
|
|
.then(function (answer) {
|
|
debug("B: got answer, set it as local description");
|
|
return pcB.setLocalDescription(answer);
|
|
})
|
|
.then(function () {
|
|
debug("B: local answer set");
|
|
shouldBe("pcB.signalingState", "'stable'");
|
|
shouldBeNull("pcB.pendingLocalDescription");
|
|
shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcB.pendingRemoteDescription");
|
|
shouldBeType("pcB.currentRemoteDescription", "RTCSessionDescription");
|
|
|
|
debug("<br>B: send answer to A");
|
|
debug("A <-- answer -- B");
|
|
debug("A: got answer from B, set it as remote description");
|
|
return pcA.setRemoteDescription(pcB.localDescription);
|
|
})
|
|
.then(function () {
|
|
debug("A: remote answer set");
|
|
shouldBe("pcA.signalingState", "'stable'");
|
|
shouldBeNull("pcA.pendingLocalDescription");
|
|
shouldBeType("pcA.currentLocalDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcA.pendingRemoteDescription");
|
|
shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
|
|
debug("");
|
|
|
|
testPassed("First offer/answer dialog completed")
|
|
debug("========================================<br>")
|
|
|
|
shouldBe("pcB.getSenders().length", "1");
|
|
debug("B: add media (should reuse sender)");
|
|
pcB.addTrack(stream.getAudioTracks()[0], stream);
|
|
shouldBe("pcB.getSenders().length", "1");
|
|
|
|
debug("B: create offer");
|
|
return pcB.createOffer();
|
|
})
|
|
.then(function (offer) {
|
|
debug("B: got offer, set it as local description");
|
|
return pcB.setLocalDescription(offer);
|
|
})
|
|
.then(function () {
|
|
debug("B: local offer set (session update so we have both pending and current local descriptions)");
|
|
shouldBe("pcB.signalingState", "'have-local-offer'");
|
|
shouldBeType("pcB.pendingLocalDescription", "RTCSessionDescription");
|
|
shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
|
|
|
|
debug("<br>B: send offer to A");
|
|
debug("A <-- offer --- B");
|
|
debug("A: got offer from B, set it as remote description");
|
|
return pcA.setRemoteDescription(pcB.localDescription);
|
|
})
|
|
.then(function () {
|
|
debug("A: remote offer set (session update so we have both pending and current remote descriptions)");
|
|
shouldBe("pcA.signalingState", "'have-remote-offer'");
|
|
shouldBeType("pcA.pendingRemoteDescription", "RTCSessionDescription");
|
|
shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
|
|
|
|
debug("<br>A: create answer");
|
|
return pcA.createAnswer();
|
|
})
|
|
.then(function (answer) {
|
|
debug("A: got answer, set it as local description");
|
|
return pcA.setLocalDescription(answer);
|
|
})
|
|
.then(function () {
|
|
debug("A: local answer set");
|
|
shouldBe("pcA.signalingState", "'stable'");
|
|
shouldBeNull("pcA.pendingLocalDescription");
|
|
shouldBeType("pcA.currentLocalDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcA.pendingRemoteDescription");
|
|
shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
|
|
|
|
debug("<br>A: send answer to B");
|
|
debug("A --- answer -> B");
|
|
debug("B: got answer from A, set it as remote description");
|
|
return pcB.setRemoteDescription(pcA.localDescription);
|
|
})
|
|
.then(function () {
|
|
debug("B: remote answer set");
|
|
shouldBe("pcB.signalingState", "'stable'");
|
|
shouldBeNull("pcB.pendingLocalDescription");
|
|
shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
|
|
shouldBeNull("pcB.pendingRemoteDescription");
|
|
shouldBeType("pcB.currentRemoteDescription", "RTCSessionDescription");
|
|
debug("");
|
|
|
|
testPassed("Second offer/answer dialog completed")
|
|
debug("");
|
|
|
|
finishJSTest();
|
|
})
|
|
.catch(function (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>
|