| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 1 | <!doctype html> |
| 2 | <meta charset=utf-8> |
| 3 | <title>RTCPeerConnection.prototype.ondatachannel</title> |
| 4 | <script src="/resources/testharness.js"></script> |
| 5 | <script src="/resources/testharnessreport.js"></script> |
| 6 | <script src="RTCPeerConnection-helper.js"></script> |
| 7 | <script> |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 8 | 'use strict'; |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 9 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 10 | // Test is based on the following revision: |
| 11 | // https://rawgit.com/w3c/webrtc-pc/1cc5bfc3ff18741033d804c4a71f7891242fb5b3/webrtc.html |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 12 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 13 | // The following helper functions are called from RTCPeerConnection-helper.js: |
| 14 | // exchangeIceCandidates |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 15 | // exchangeOfferAnswer |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 16 | // createDataChannelPair |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 17 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 18 | /* |
| 19 | 6.2. RTCDataChannel |
| 20 | When an underlying data transport is to be announced (the other peer created a channel with |
| 21 | negotiated unset or set to false), the user agent of the peer that did not initiate the |
| 22 | creation process MUST queue a task to run the following steps: |
| 23 | 2. Let channel be a newly created RTCDataChannel object. |
| 24 | 7. Set channel's [[ReadyState]] to open (but do not fire the open event, yet). |
| 25 | 8. Fire a datachannel event named datachannel with channel at the RTCPeerConnection object. |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 26 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 27 | 6.3. RTCDataChannelEvent |
| 28 | Firing a datachannel event named e with an RTCDataChannel channel means that an event with the |
| 29 | name e, which does not bubble (except where otherwise stated) and is not cancelable (except |
| 30 | where otherwise stated), and which uses the RTCDataChannelEvent interface with the channel |
| 31 | attribute set to channel, MUST be created and dispatched at the given target. |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 32 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 33 | interface RTCDataChannelEvent : Event { |
| 34 | readonly attribute RTCDataChannel channel; |
| 35 | }; |
| 36 | */ |
| 37 | promise_test(async (t) => { |
| 38 | const resolver = new Resolver(); |
| 39 | const pc1 = new RTCPeerConnection(); |
| 40 | const pc2 = new RTCPeerConnection(); |
| 41 | t.add_cleanup(() => pc1.close()); |
| 42 | t.add_cleanup(() => pc2.close()); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 43 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 44 | let eventCount = 0; |
| Philipp Hancke | 1622a02 | 2018-06-11 10:00:53 | [diff] [blame] | 45 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 46 | pc2.ondatachannel = t.step_func((event) => { |
| 47 | eventCount++; |
| 48 | assert_equals(eventCount, 1, |
| 49 | 'Expect data channel event to fire exactly once'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 50 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 51 | assert_true(event instanceof RTCDataChannelEvent, |
| 52 | 'Expect event to be instance of RTCDataChannelEvent'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 53 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 54 | assert_equals(event.bubbles, false); |
| 55 | assert_equals(event.cancelable, false); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 56 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 57 | const dc = event.channel; |
| 58 | assert_true(dc instanceof RTCDataChannel, |
| 59 | 'Expect channel to be instance of RTCDataChannel'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 60 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 61 | // The channel should be in the 'open' state already. |
| 62 | // See: https://github.com/w3c/webrtc-pc/pull/1851 |
| 63 | assert_equals(dc.readyState, 'open', |
| 64 | 'Expect channel ready state to be open'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 65 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 66 | resolver.resolve(); |
| 67 | }); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 68 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 69 | pc1.createDataChannel('fire-me!'); |
| 70 | |
| 71 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 72 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 73 | |
| 74 | await resolver; |
| 75 | }, 'Data channel event should fire when new data channel is announced to the remote peer'); |
| 76 | |
| 77 | /* |
| 78 | Since the channel should be in the 'open' state when dispatching via the 'datachannel' event, |
| 79 | we should be able to send data in the event handler. |
| 80 | */ |
| 81 | promise_test(async (t) => { |
| 82 | const resolver = new Resolver(); |
| 83 | const pc1 = new RTCPeerConnection(); |
| 84 | const pc2 = new RTCPeerConnection(); |
| 85 | t.add_cleanup(() => pc1.close()); |
| 86 | t.add_cleanup(() => pc2.close()); |
| 87 | |
| 88 | const message = 'meow meow!'; |
| 89 | |
| 90 | pc2.ondatachannel = t.step_func((event) => { |
| 91 | const dc2 = event.channel; |
| 92 | dc2.send(message); |
| 93 | }); |
| 94 | |
| 95 | const dc1 = pc1.createDataChannel('fire-me!'); |
| 96 | dc1.onmessage = t.step_func((event) => { |
| 97 | assert_equals(event.data, message, |
| 98 | 'Received data should be equal to sent data'); |
| 99 | |
| 100 | resolver.resolve(); |
| 101 | }); |
| 102 | |
| 103 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 104 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 105 | |
| 106 | await resolver; |
| 107 | }, 'Should be able to send data in a datachannel event handler'); |
| 108 | |
| 109 | /* |
| 110 | 6.2. RTCDataChannel |
| 111 | When an underlying data transport is to be announced (the other peer created a channel with |
| 112 | negotiated unset or set to false), the user agent of the peer that did not initiate the |
| 113 | creation process MUST queue a task to run the following steps: |
| 114 | 8. Fire a datachannel event named datachannel with channel at the RTCPeerConnection object. |
| 115 | 9. If the channel's [[ReadyState]] is still open, announce the data channel as open. |
| 116 | */ |
| 117 | promise_test(async (t) => { |
| 118 | const resolver = new Resolver(); |
| 119 | const pc1 = new RTCPeerConnection(); |
| 120 | const pc2 = new RTCPeerConnection(); |
| 121 | t.add_cleanup(() => pc1.close()); |
| 122 | t.add_cleanup(() => pc2.close()); |
| 123 | |
| 124 | pc2.ondatachannel = t.step_func((event) => { |
| 125 | const dc = event.channel; |
| 126 | dc.onopen = t.step_func(() => { |
| 127 | assert_unreached('Open event should not fire'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 128 | }); |
| 129 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 130 | // This should prevent triggering the 'open' event |
| 131 | dc.close(); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 132 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 133 | // Wait a bit to ensure the 'open' event does NOT fire |
| 134 | t.step_timeout(() => resolver.resolve(), 500); |
| 135 | }); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 136 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 137 | pc1.createDataChannel('fire-me!'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 138 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 139 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 140 | await exchangeOfferAnswer(pc1, pc2); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 141 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 142 | await resolver; |
| 143 | }, 'Open event should not be raised when closing the channel in the datachannel event'); |
| Philipp Hancke | 1622a02 | 2018-06-11 10:00:53 | [diff] [blame] | 144 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 145 | // Added this test as a result of the discussion in |
| 146 | // https://github.com/w3c/webrtc-pc/pull/1851#discussion_r185976747 |
| 147 | promise_test(async (t) => { |
| 148 | const resolver = new Resolver(); |
| 149 | const pc1 = new RTCPeerConnection(); |
| 150 | const pc2 = new RTCPeerConnection(); |
| 151 | t.add_cleanup(() => pc1.close()); |
| 152 | t.add_cleanup(() => pc2.close()); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 153 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 154 | pc2.ondatachannel = t.step_func((event) => { |
| 155 | const dc = event.channel; |
| 156 | dc.onopen = t.step_func((event) => { |
| 157 | resolver.resolve(); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 158 | }); |
| 159 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 160 | // This should NOT prevent triggering the 'open' event since it enqueues at least two tasks |
| 161 | t.step_timeout(() => { |
| 162 | t.step_timeout(() => { |
| 163 | dc.close() |
| 164 | }, 1); |
| 165 | }, 1); |
| 166 | }); |
| 167 | |
| 168 | pc1.createDataChannel('fire-me!'); |
| 169 | |
| 170 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 171 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 172 | |
| 173 | await resolver; |
| 174 | }, 'Open event should be raised when closing the channel in the datachannel event after ' + |
| 175 | 'enqueuing a task'); |
| 176 | |
| 177 | |
| 178 | /* |
| 179 | Combination of the two tests above (send and close). |
| 180 | */ |
| 181 | promise_test(async (t) => { |
| 182 | const resolver = new Resolver(); |
| 183 | const pc1 = new RTCPeerConnection(); |
| 184 | const pc2 = new RTCPeerConnection(); |
| 185 | t.add_cleanup(() => pc1.close()); |
| 186 | t.add_cleanup(() => pc2.close()); |
| 187 | |
| 188 | const message = 'meow meow!'; |
| 189 | |
| 190 | pc2.ondatachannel = t.step_func((event) => { |
| 191 | const dc2 = event.channel; |
| 192 | dc2.onopen = t.step_func(() => { |
| 193 | assert_unreached('Open event should not fire'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 194 | }); |
| 195 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 196 | // This should send but still prevent triggering the 'open' event |
| 197 | dc2.send(message); |
| 198 | dc2.close(); |
| 199 | }); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 200 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 201 | const dc1 = pc1.createDataChannel('fire-me!'); |
| 202 | dc1.onmessage = t.step_func((event) => { |
| 203 | assert_equals(event.data, message, |
| 204 | 'Received data should be equal to sent data'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 205 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 206 | resolver.resolve(); |
| 207 | }); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 208 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 209 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 210 | await exchangeOfferAnswer(pc1, pc2); |
| Philipp Hancke | 1622a02 | 2018-06-11 10:00:53 | [diff] [blame] | 211 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 212 | await resolver; |
| 213 | }, 'Open event should not be raised when sending and immediately closing the channel in the ' + |
| 214 | 'datachannel event'); |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 215 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 216 | /* |
| 217 | 6.2. RTCDataChannel |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 218 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 219 | interface RTCDataChannel : EventTarget { |
| 220 | readonly attribute USVString label; |
| 221 | readonly attribute boolean ordered; |
| 222 | readonly attribute unsigned short? maxPacketLifeTime; |
| 223 | readonly attribute unsigned short? maxRetransmits; |
| 224 | readonly attribute USVString protocol; |
| 225 | readonly attribute boolean negotiated; |
| 226 | readonly attribute unsigned short? id; |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 227 | readonly attribute RTCDataChannelState readyState; |
| 228 | ... |
| 229 | }; |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 230 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 231 | When an underlying data transport is to be announced (the other peer created a channel with |
| 232 | negotiated unset or set to false), the user agent of the peer that did not initiate the |
| 233 | creation process MUST queue a task to run the following steps: |
| 234 | 2. Let channel be a newly created RTCDataChannel object. |
| 235 | 3. Let configuration be an information bundle received from the other peer as a part of the |
| 236 | process to establish the underlying data transport described by the WebRTC DataChannel |
| 237 | Protocol specification [RTCWEB-DATA-PROTOCOL]. |
| 238 | 4. Initialize channel's [[DataChannelLabel]], [[Ordered]], [[MaxPacketLifeTime]], |
| 239 | [[MaxRetransmits]], [[DataChannelProtocol]], and [[DataChannelId]] internal slots to the |
| 240 | corresponding values in configuration. |
| 241 | 5. Initialize channel's [[Negotiated]] internal slot to false. |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 242 | 7. Set channel's [[ReadyState]] slot to connecting. |
| 243 | 8. Fire a datachannel event named datachannel with channel at the RTCPeerConnection object. |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 244 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 245 | Note: More exhaustive tests are defined in RTCDataChannel-dcep |
| 246 | */ |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 247 | |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 248 | promise_test(async (t) => { |
| 249 | const resolver = new Resolver(); |
| 250 | const pc1 = new RTCPeerConnection(); |
| 251 | const pc2 = new RTCPeerConnection(); |
| 252 | t.add_cleanup(() => pc1.close()); |
| 253 | t.add_cleanup(() => pc2.close()); |
| 254 | |
| 255 | const dc1 = pc1.createDataChannel('test', { |
| 256 | ordered: false, |
| 257 | maxRetransmits: 1, |
| Dominique Hazael-Massieux | 24221e0 | 2020-09-30 14:08:28 | [diff] [blame] | 258 | protocol: 'custom' |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 259 | }); |
| 260 | |
| 261 | assert_equals(dc1.label, 'test'); |
| 262 | assert_equals(dc1.ordered, false); |
| 263 | assert_equals(dc1.maxPacketLifeTime, null); |
| 264 | assert_equals(dc1.maxRetransmits, 1); |
| 265 | assert_equals(dc1.protocol, 'custom'); |
| 266 | assert_equals(dc1.negotiated, false); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 267 | |
| 268 | pc2.ondatachannel = t.step_func((event) => { |
| 269 | const dc2 = event.channel; |
| 270 | assert_true(dc2 instanceof RTCDataChannel, |
| 271 | 'Expect channel to be instance of RTCDataChannel'); |
| 272 | |
| 273 | assert_equals(dc2.label, 'test'); |
| 274 | assert_equals(dc2.ordered, false); |
| 275 | assert_equals(dc2.maxPacketLifeTime, null); |
| 276 | assert_equals(dc2.maxRetransmits, 1); |
| 277 | assert_equals(dc2.protocol, 'custom'); |
| 278 | assert_equals(dc2.negotiated, false); |
| 279 | assert_equals(dc2.id, dc1.id); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 280 | |
| 281 | resolver.resolve(); |
| 282 | }); |
| 283 | |
| 284 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 285 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 286 | |
| 287 | await resolver; |
| 288 | }, 'In-band negotiated channel created on remote peer should match the same configuration as local ' + |
| 289 | 'peer'); |
| 290 | |
| 291 | promise_test(async (t) => { |
| 292 | const resolver = new Resolver(); |
| 293 | const pc1 = new RTCPeerConnection(); |
| 294 | const pc2 = new RTCPeerConnection(); |
| 295 | t.add_cleanup(() => pc1.close()); |
| 296 | t.add_cleanup(() => pc2.close()); |
| 297 | |
| 298 | const dc1 = pc1.createDataChannel(''); |
| 299 | |
| 300 | assert_equals(dc1.label, ''); |
| 301 | assert_equals(dc1.ordered, true); |
| 302 | assert_equals(dc1.maxPacketLifeTime, null); |
| 303 | assert_equals(dc1.maxRetransmits, null); |
| 304 | assert_equals(dc1.protocol, ''); |
| 305 | assert_equals(dc1.negotiated, false); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 306 | |
| 307 | pc2.ondatachannel = t.step_func((event) => { |
| 308 | const dc2 = event.channel; |
| 309 | assert_true(dc2 instanceof RTCDataChannel, |
| 310 | 'Expect channel to be instance of RTCDataChannel'); |
| 311 | |
| 312 | assert_equals(dc2.label, ''); |
| 313 | assert_equals(dc2.ordered, true); |
| 314 | assert_equals(dc2.maxPacketLifeTime, null); |
| 315 | assert_equals(dc2.maxRetransmits, null); |
| 316 | assert_equals(dc2.protocol, ''); |
| 317 | assert_equals(dc2.negotiated, false); |
| 318 | assert_equals(dc2.id, dc1.id); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 319 | |
| 320 | resolver.resolve(); |
| 321 | }); |
| 322 | |
| 323 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 324 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 325 | |
| 326 | await resolver; |
| 327 | }, 'In-band negotiated channel created on remote peer should match the same (default) ' + |
| 328 | 'configuration as local peer'); |
| 329 | |
| 330 | /* |
| 331 | 6.2. RTCDataChannel |
| 332 | Dictionary RTCDataChannelInit Members |
| 333 | negotiated |
| 334 | The default value of false tells the user agent to announce the |
| 335 | channel in-band and instruct the other peer to dispatch a corresponding |
| 336 | RTCDataChannel object. If set to true, it is up to the application |
| 337 | to negotiate the channel and create a RTCDataChannel object with the |
| 338 | same id at the other peer. |
| 339 | */ |
| 340 | promise_test(async (t) => { |
| 341 | const resolver = new Resolver(); |
| 342 | const pc1 = new RTCPeerConnection(); |
| 343 | const pc2 = new RTCPeerConnection(); |
| 344 | t.add_cleanup(() => pc1.close()); |
| 345 | t.add_cleanup(() => pc2.close()); |
| 346 | |
| 347 | pc2.ondatachannel = t.unreached_func('datachannel event should not be fired'); |
| 348 | |
| 349 | pc1.createDataChannel('test', { |
| Harald Alvestrand | f6cf3bd | 2019-04-04 12:39:57 | [diff] [blame] | 350 | negotiated: true, |
| 351 | id: 42 |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 352 | }); |
| 353 | |
| 354 | exchangeIceCandidates(pc1, pc2); |
| Jan-Ivar Bruaroey | e880d97 | 2020-05-11 17:30:24 | [diff] [blame] | 355 | await exchangeOfferAnswer(pc1, pc2); |
| youennf | 0e97d09 | 2019-03-23 18:02:56 | [diff] [blame] | 356 | |
| 357 | // Wait a bit to ensure the 'datachannel' event does NOT fire |
| 358 | t.step_timeout(() => resolver.resolve(), 500); |
| 359 | await resolver; |
| 360 | }, 'Negotiated channel should not fire datachannel event on remote peer'); |
| 361 | |
| 362 | /* |
| 363 | Non-testable |
| 364 | 6.2. RTCDataChannel |
| 365 | When an underlying data transport is to be announced |
| 366 | 1. If the associated RTCPeerConnection object's [[isClosed]] slot |
| 367 | is true, abort these steps. |
| 368 | |
| 369 | The above step is not testable because to reach it we would have to |
| 370 | close the peer connection just between receiving the in-band negotiated data |
| 371 | channel via DCEP and firing the datachannel event. |
| 372 | */ |
| Soares Chen | 6d8970d | 2017-06-12 16:02:23 | [diff] [blame] | 373 | </script> |