| <!doctype html> |
| |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| <title>RTCPeerConnection No-Media Connection Test</title> |
| </head> |
| <body> |
| <div id="log"></div> |
| <h2>iceConnectionState info</h2> |
| <div id="stateinfo"> |
| </div> |
| |
| <!-- These files are in place when executing on W3C. --> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="RTCPeerConnection-helper.js"></script> |
| <script type="text/javascript"> |
| let gFirstConnection = null; |
| let gSecondConnection = null; |
| |
| function onIceCandidate(otherConnction, event, reject) { |
| try { |
| otherConnction.addIceCandidate(event.candidate); |
| } catch(e) { |
| reject(e); |
| } |
| }; |
| |
| function onIceConnectionStateChange(done, failed, event) { |
| try { |
| assert_equals(event.type, 'iceconnectionstatechange'); |
| assert_not_equals(gFirstConnection.iceConnectionState, "failed", |
| "iceConnectionState of first connection"); |
| assert_not_equals(gSecondConnection.iceConnectionState, "failed", |
| "iceConnectionState of second connection"); |
| const stateinfo = document.getElementById('stateinfo'); |
| stateinfo.innerHTML = 'First: ' + gFirstConnection.iceConnectionState |
| + '<br>Second: ' + gSecondConnection.iceConnectionState; |
| // Note: All these combinations are legal states indicating that the |
| // call has connected. All browsers should end up in completed/completed, |
| // but as of this moment, we've chosen to terminate the test early. |
| // TODO: Revise test to ensure completed/completed is reached. |
| const allowedStates = [ 'connected', 'completed']; |
| if (allowedStates.includes(gFirstConnection.iceConnectionState) && |
| allowedStates.includes(gSecondConnection.iceConnectionState)) { |
| done(); |
| } |
| } catch(e) { |
| failed(e); |
| } |
| }; |
| |
| // This function starts the test. |
| promise_test((test) => { |
| return new Promise(async (resolve, reject) => { |
| gFirstConnection = new RTCPeerConnection(null); |
| test.add_cleanup(() => gFirstConnection.close()); |
| gFirstConnection.onicecandidate = |
| (event) => onIceCandidate(gSecondConnection, event, reject); |
| gFirstConnection.oniceconnectionstatechange = |
| (event) => onIceConnectionStateChange(resolve, reject, event); |
| |
| gSecondConnection = new RTCPeerConnection(null); |
| test.add_cleanup(() => gSecondConnection.close()); |
| gSecondConnection.onicecandidate = |
| (event) => onIceCandidate(gFirstConnection, event, reject); |
| gSecondConnection.oniceconnectionstatechange = |
| (event) => onIceConnectionStateChange(resolve, reject, event); |
| |
| const offer = await generateVideoReceiveOnlyOffer(gFirstConnection); |
| |
| await gFirstConnection.setLocalDescription(offer); |
| |
| // This would normally go across the application's signaling solution. |
| // In our case, the "signaling" is to call this function. |
| |
| await gSecondConnection.setRemoteDescription({ type: 'offer', |
| sdp: offer.sdp }); |
| |
| const answer = await gSecondConnection.createAnswer(); |
| |
| await gSecondConnection.setLocalDescription(answer); |
| |
| assert_equals(gSecondConnection.getSenders().length, 1); |
| assert_not_equals(gSecondConnection.getSenders()[0], null); |
| assert_not_equals(gSecondConnection.getSenders()[0].transport, null); |
| |
| // Similarly, this would go over the application's signaling solution. |
| await gFirstConnection.setRemoteDescription({ type: 'answer', |
| sdp: answer.sdp }); |
| |
| // The test is terminated by onIceConnectionStateChange() calling resolve |
| // once both connections are connected. |
| }) |
| }); |
| </script> |
| |
| </body> |
| </html> |