blob: 2becbd3e23efee6ee14988b770c34e8fba9d3455 [file] [log] [blame]
Soares Chenfda87822017-06-05 14:00:301<!doctype html>
2<meta charset=utf-8>
3<title>RTCPeerConnection.prototype.setLocalDescription</title>
4<script src="/resources/testharness.js"></script>
5<script src="/resources/testharnessreport.js"></script>
6<script src="RTCPeerConnection-helper.js"></script>
7<script>
8 'use strict';
9
10 // Test is based on the following editor draft:
Soares Chena01b1e52017-07-07 09:52:0311 // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
Soares Chenfda87822017-06-05 14:00:3012
Rick Waldron1c5c05d2017-06-07 17:54:4213 // The following helper functions are called from RTCPeerConnection-helper.js:
youennfcd17e3b2018-11-04 08:03:5914 // generateDataChannelOffer
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:0915 // assert_session_desc_not_similar
16 // assert_session_desc_similar
Rick Waldron1c5c05d2017-06-07 17:54:4217
Soares Chenfda87822017-06-05 14:00:3018 /*
Soares Chena01b1e52017-07-07 09:52:0319 4.3.2. Interface Definition
20 [Constructor(optional RTCConfiguration configuration)]
21 interface RTCPeerConnection : EventTarget {
22 Promise<void> setRemoteDescription(
23 RTCSessionDescriptionInit description);
24
25 readonly attribute RTCSessionDescription? remoteDescription;
26 readonly attribute RTCSessionDescription? currentRemoteDescription;
27 readonly attribute RTCSessionDescription? pendingRemoteDescription;
28 ...
29 };
30
31 4.6.2. RTCSessionDescription Class
32 dictionary RTCSessionDescriptionInit {
33 required RTCSdpType type;
34 DOMString sdp = "";
35 };
36
37 4.6.1. RTCSdpType
38 enum RTCSdpType {
39 "offer",
40 "pranswer",
41 "answer",
42 "rollback"
43 };
Soares Chenfda87822017-06-05 14:00:3044 */
45
Soares Chenfda87822017-06-05 14:00:3046 promise_test(t => {
47 const pc = new RTCPeerConnection();
Philipp Hancke1622a022018-06-11 10:00:5348 t.add_cleanup(() => pc.close());
Philipp Hanckeeb37a992018-05-30 15:55:0249
50 const states = [];
51 pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
Soares Chenfda87822017-06-05 14:00:3052
Youenn Fablet7b163582018-11-04 07:30:5953 return generateAudioReceiveOnlyOffer(pc)
Soares Chenfda87822017-06-05 14:00:3054 .then(offer1 =>
55 pc.setLocalDescription(offer1)
56 .then(() => generateAnswer(offer1))
57 .then(answer => pc.setRemoteDescription(answer))
58 .then(() => {
59 pc.createDataChannel('test');
Youenn Fablet7b163582018-11-04 07:30:5960 return generateVideoReceiveOnlyOffer(pc);
Soares Chenfda87822017-06-05 14:00:3061 })
62 .then(offer2 =>
63 pc.setLocalDescription(offer2)
64 .then(() => {
65 assert_equals(pc.signalingState, 'have-local-offer');
Jan-Ivar Bruaroey6d3fda52018-07-04 13:49:0966 assert_session_desc_not_similar(offer1, offer2);
67 assert_session_desc_similar(pc.localDescription, offer2);
68 assert_session_desc_similar(pc.currentLocalDescription, offer1);
69 assert_session_desc_similar(pc.pendingLocalDescription, offer2);
Raphael Kubo da Costaa2049832018-07-05 16:39:5670
71 assert_array_equals(states, ['have-local-offer', 'stable', 'have-local-offer']);
Soares Chenfda87822017-06-05 14:00:3072 })));
73 }, 'Calling createOffer() and setLocalDescription() again after one round of local-offer/remote-answer should succeed');
74
Byron Campen [:bwc]f2d6b2d2019-03-11 13:12:2875 promise_test(async t => {
76 const pc1 = new RTCPeerConnection();
77 t.add_cleanup(() => pc1.close());
78
79 const pc2 = new RTCPeerConnection();
80 t.add_cleanup(() => pc2.close());
Philipp Hanckeeb37a992018-05-30 15:55:0281
82 const states = [];
Byron Campen [:bwc]f2d6b2d2019-03-11 13:12:2883 pc1.addEventListener('signalingstatechange', () => states.push(pc1.signalingState));
Soares Chenfda87822017-06-05 14:00:3084
Byron Campen [:bwc]f2d6b2d2019-03-11 13:12:2885 assert_equals(pc1.localDescription, null);
86 assert_equals(pc1.currentLocalDescription, null);
87 assert_equals(pc1.pendingLocalDescription, null);
Philipp Hanckeeb37a992018-05-30 15:55:0288
Byron Campen [:bwc]f2d6b2d2019-03-11 13:12:2889 pc1.createDataChannel('test');
90 const offer = await pc1.createOffer();
91
92 assert_equals(pc1.localDescription, null);
93 assert_equals(pc1.currentLocalDescription, null);
94 assert_equals(pc1.pendingLocalDescription, null);
95
96 await pc1.setLocalDescription(offer);
97
98 assert_session_desc_similar(pc1.localDescription, offer);
99 assert_equals(pc1.currentLocalDescription, null);
100 assert_session_desc_similar(pc1.pendingLocalDescription, offer);
101
102 await pc2.setRemoteDescription(offer);
103 const answer = await pc2.createAnswer();
104 await pc2.setLocalDescription(answer);
105 await pc1.setRemoteDescription(answer);
106
107 assert_equals(pc1.signalingState, 'stable');
108 assert_session_desc_similar(pc1.localDescription, offer);
109 assert_session_desc_similar(pc1.currentLocalDescription, offer);
110 assert_equals(pc1.pendingLocalDescription, null);
111
112 const stream = await getNoiseStream({audio:true});
113 pc2.addTrack(stream.getTracks()[0], stream);
114
115 const reoffer = await pc2.createOffer();
116 await pc2.setLocalDescription(reoffer);
117 await pc1.setRemoteDescription(reoffer);
118 const reanswer = await pc1.createAnswer();
119 await pc1.setLocalDescription(reanswer);
120
121 assert_session_desc_similar(pc1.localDescription, reanswer);
122 assert_session_desc_similar(pc1.currentLocalDescription, reanswer);
123 assert_equals(pc1.pendingLocalDescription, null);
Soares Chenfda87822017-06-05 14:00:30124 }, 'Switching role from answerer to offerer after going back to stable state should succeed');
125
Henrik Boström3d14e692018-06-07 16:45:55126 promise_test(async t => {
127 const pc = new RTCPeerConnection();
128 const offer = await pc.createOffer();
129 let eventSequence = '';
130 const signalingstatechangeResolver = new Resolver();
131 pc.onsignalingstatechange = () => {
132 eventSequence += 'onsignalingstatechange;';
133 signalingstatechangeResolver.resolve();
134 };
135 await pc.setLocalDescription(offer);
136 eventSequence += 'setLocalDescription;';
Youenn Fabletd77afea2018-12-20 22:13:46137 await signalingstatechangeResolver;
Henrik Boström3d14e692018-06-07 16:45:55138 assert_equals(eventSequence, 'onsignalingstatechange;setLocalDescription;');
139 }, 'onsignalingstatechange fires before setLocalDescription resolves');
140
Soares Chenfda87822017-06-05 14:00:30141 /*
Soares Chena01b1e52017-07-07 09:52:03142 TODO
Soares Chena158fe12017-07-10 04:58:34143 4.3.2. setLocalDescription
Soares Chena01b1e52017-07-07 09:52:03144 4. If description.sdp is null and description.type is pranswer, set description.sdp
145 to lastAnswer.
146 7. If description.type is pranswer and description.sdp does not match lastAnswer,
147 reject the promise with a newly created InvalidModificationError and abort these
148 steps.
149 */
150
Soares Chenfda87822017-06-05 14:00:30151</script>