mirror of
https://github.com/servo/servo.git
synced 2025-07-02 21:13:39 +01:00
184 lines
6.9 KiB
HTML
184 lines
6.9 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<title>RTCPeerConnection.prototype.ondatachannel</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="RTCPeerConnection-helper.js"></script>
|
|
<script>
|
|
'use strict';
|
|
|
|
// Test is based on the following editor draft:
|
|
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
|
|
|
|
// The following helper functions are called from RTCPeerConnection-helper.js:
|
|
// exchangeIceCandidates
|
|
// doSignalingHandshake
|
|
|
|
/*
|
|
6.2. RTCDataChannel
|
|
When an underlying data transport is to be announced
|
|
2. Let channel be a newly created RTCDataChannel object.
|
|
5. Set channel's readyState attribute to connecting.
|
|
6. Fire a datachannel event named datachannel with channel at the
|
|
RTCPeerConnection object.
|
|
|
|
6.3. RTCDataChannelEvent
|
|
Firing a datachannel event named e with a RTCDataChannel channel means
|
|
that an event with the name e, which does not bubble (except where
|
|
otherwise stated) and is not cancelable (except where otherwise stated),
|
|
and which uses the RTCDataChannelEvent interface with the channel
|
|
attribute set to channel, must be created and dispatched at the given
|
|
target.
|
|
|
|
interface RTCDataChannelEvent : Event {
|
|
readonly attribute RTCDataChannel channel;
|
|
};
|
|
*/
|
|
async_test(t => {
|
|
const localPc = new RTCPeerConnection();
|
|
t.add_cleanup(() => localPc.close());
|
|
const remotePc = new RTCPeerConnection();
|
|
|
|
t.add_cleanup(() => remotePc.close());
|
|
|
|
let eventCount = 0;
|
|
|
|
const onDataChannel = t.step_func_done(event => {
|
|
eventCount++;
|
|
assert_equals(eventCount, 1,
|
|
'Expect data channel event to fire exactly once');
|
|
|
|
assert_true(event instanceof RTCDataChannelEvent,
|
|
'Expect event to be instance of RTCDataChannelEvent');
|
|
|
|
assert_equals(event.bubbles, false);
|
|
assert_equals(event.cancelable, false);
|
|
|
|
const { channel } = event;
|
|
assert_true(channel instanceof RTCDataChannel,
|
|
'Expect channel to be instance of RTCDataChannel');
|
|
|
|
const { readyState } = channel;
|
|
|
|
// The spec requires readyState to be connecting at first,
|
|
// but it may quickly change to open before the callback
|
|
// is invoked, especially with local connections.
|
|
assert_true(readyState === 'connecting' || readyState === 'open',
|
|
'Expect channel ready state to be either connecting or open');
|
|
});
|
|
|
|
localPc.createDataChannel('test');
|
|
|
|
remotePc.addEventListener('datachannel', onDataChannel);
|
|
exchangeIceCandidates(localPc, remotePc);
|
|
doSignalingHandshake(localPc, remotePc);
|
|
}, 'datachannel event should fire when new data channel is announced to the remote peer');
|
|
|
|
/*
|
|
6.2. RTCDataChannel
|
|
interface RTCDataChannel : EventTarget {
|
|
readonly attribute USVString label;
|
|
readonly attribute boolean ordered;
|
|
readonly attribute unsigned short? maxPacketLifeTime;
|
|
readonly attribute unsigned short? maxRetransmits;
|
|
readonly attribute USVString protocol;
|
|
readonly attribute boolean negotiated;
|
|
readonly attribute unsigned short? id;
|
|
readonly attribute RTCPriorityType priority;
|
|
readonly attribute RTCDataChannelState readyState;
|
|
...
|
|
};
|
|
|
|
When an underlying data transport is to be announced
|
|
3. Let configuration be an information bundle received from the
|
|
other peer as a part of the process to establish the underlying
|
|
data transport described by the WebRTC DataChannel Protocol
|
|
specification [RTCWEB-DATA-PROTOCOL].
|
|
4. Initialize channel's label, ordered, maxPacketLifeTime,
|
|
maxRetransmits, protocol, negotiated and id attributes to their
|
|
corresponding values in configuration.
|
|
*/
|
|
async_test(t => {
|
|
const localPc = new RTCPeerConnection();
|
|
t.add_cleanup(() => localPc.close());
|
|
const remotePc = new RTCPeerConnection();
|
|
|
|
t.add_cleanup(() => remotePc.close());
|
|
|
|
const onDataChannel = t.step_func_done(event => {
|
|
const remoteChannel = event.channel;
|
|
assert_true(remoteChannel instanceof RTCDataChannel,
|
|
'Expect channel to be instance of RTCDataChannel');
|
|
|
|
assert_equals(remoteChannel.label, 'test');
|
|
assert_equals(remoteChannel.id, 8);
|
|
assert_equals(remoteChannel.ordered, false);
|
|
assert_equals(remoteChannel.maxRetransmits, 1);
|
|
assert_equals(remoteChannel.protocol, 'custom');
|
|
assert_equals(remoteChannel.priority, 'high');
|
|
});
|
|
|
|
const localChannel = localPc.createDataChannel('test', {
|
|
id: 8,
|
|
ordered: false,
|
|
maxRetransmits: 1,
|
|
protocol: 'custom',
|
|
priority: 'high'
|
|
});
|
|
|
|
assert_equals(localChannel.label, 'test');
|
|
assert_equals(localChannel.id, 8);
|
|
assert_equals(localChannel.ordered, false);
|
|
assert_equals(localChannel.maxRetransmits, 1);
|
|
assert_equals(localChannel.protocol, 'custom');
|
|
assert_equals(localChannel.priority, 'high');
|
|
|
|
remotePc.addEventListener('datachannel', onDataChannel);
|
|
exchangeIceCandidates(localPc, remotePc);
|
|
doSignalingHandshake(localPc, remotePc);
|
|
}, 'Data channel created on remote peer should match the same configuration as local peer');
|
|
|
|
/*
|
|
6.2. RTCDataChannel
|
|
Dictionary RTCDataChannelInit Members
|
|
negotiated
|
|
The default value of false tells the user agent to announce the
|
|
channel in-band and instruct the other peer to dispatch a corresponding
|
|
RTCDataChannel object. If set to true, it is up to the application
|
|
to negotiate the channel and create a RTCDataChannel object with the
|
|
same id at the other peer.
|
|
*/
|
|
async_test(t => {
|
|
const localPc = new RTCPeerConnection();
|
|
t.add_cleanup(() => localPc.close());
|
|
const remotePc = new RTCPeerConnection();
|
|
|
|
t.add_cleanup(() => remotePc.close());
|
|
|
|
const onDataChannel = t.unreached_func('datachannel event should not be fired');
|
|
|
|
localPc.createDataChannel('test', {
|
|
negotiated: true
|
|
});
|
|
|
|
remotePc.addEventListener('datachannel', onDataChannel);
|
|
exchangeIceCandidates(localPc, remotePc);
|
|
doSignalingHandshake(localPc, remotePc);
|
|
|
|
t.step_timeout(t.step_func_done(), 200);
|
|
}, 'Data channel created with negotiated set to true should not fire datachannel event on remote peer');
|
|
|
|
/*
|
|
Non-testable
|
|
6.2. RTCDataChannel
|
|
When an underlying data transport is to be announced
|
|
1. If the associated RTCPeerConnection object's [[isClosed]] slot
|
|
is true, abort these steps.
|
|
|
|
The above step is not testable because to reach it we would have to
|
|
close the peer connection after the remote peer call
|
|
setLocalDescription(answer) but before the underlying data transport
|
|
is connected. This require the promise callback for setLocalDescription()
|
|
to be called at the right moment, which is not always possible.
|
|
*/
|
|
</script>
|