mirror of
https://github.com/servo/servo.git
synced 2025-09-14 08:58:21 +01:00
Update web-platform-tests to revision be5419e845d39089ba6dc338c1bd0fa279108317
This commit is contained in:
parent
aa199307c8
commit
2b6f573eb5
3440 changed files with 109438 additions and 41750 deletions
|
@ -1,3 +1,4 @@
|
|||
@snuggs
|
||||
@agouaillard
|
||||
@alvestrand
|
||||
@dontcallmedom
|
||||
|
|
|
@ -172,8 +172,9 @@
|
|||
assert_equals(typeof fingerprint, 'object',
|
||||
'Expect fingerprint to be an object (dictionary)');
|
||||
|
||||
// Can only do simple test as the allowed values may be extended
|
||||
assert_true(/^[a-zA-Z\-]+$/.test(fingerprint.algorithm),
|
||||
// https://www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml
|
||||
const algorithms = ['md2', 'md5', 'sha-1', 'sha-224', 'sha-256', 'sha-384', 'sha-512'];
|
||||
assert_in_array(fingerprint.algorithm, algorithms,
|
||||
'Expect fingerprint.algorithm to be string of algorithm identifier');
|
||||
|
||||
assert_true(/^([0-9a-f]{2}\:)+[0-9a-f]{2}$/.test(fingerprint.value),
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
|
||||
|
||||
pc.setConfiguration({ iceTransportPolicy: 'relay' });
|
||||
assert_equals(pc.getConfiguration(), iceTransportPolicy, 'relay');
|
||||
assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
|
||||
}, `setConfiguration({ iceTransportPolicy: 'relay' }) with initial iceTransportPolicy all should succeed`);
|
||||
|
||||
test(() => {
|
||||
|
@ -72,7 +72,7 @@
|
|||
assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
|
||||
|
||||
pc.setConfiguration({ iceTransportPolicy: 'all' });
|
||||
assert_equals(pc.getConfiguration(), iceTransportPolicy, 'all');
|
||||
assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
|
||||
}, `setConfiguration({ iceTransportPolicy: 'all' }) with initial iceTransportPolicy relay should succeed`);
|
||||
|
||||
test(() => {
|
||||
|
@ -81,7 +81,7 @@
|
|||
|
||||
// default value for iceTransportPolicy is all
|
||||
pc.setConfiguration({});
|
||||
assert_equals(pc.getConfiguration(), iceTransportPolicy, 'all');
|
||||
assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
|
||||
}, `setConfiguration({}) with initial iceTransportPolicy relay should set new value to all`);
|
||||
|
||||
config_test(makePc => {
|
||||
|
|
|
@ -76,8 +76,8 @@ function test_tone_change_events(testFunc, toneChanges, desc) {
|
|||
const now = Date.now();
|
||||
const duration = now - lastEventTime;
|
||||
|
||||
assert_approx_equals(duration, expectedDuration, 150,
|
||||
`Expect tonechange event for "${tone}" to be fired approximately after ${expectedDuration} seconds`);
|
||||
assert_approx_equals(duration, expectedDuration, 250,
|
||||
`Expect tonechange event for "${tone}" to be fired approximately after ${expectedDuration} milliseconds`);
|
||||
|
||||
lastEventTime = now;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
testedTransports.add(dtlsTransport);
|
||||
|
||||
// End the test if both dtlsTransports are tested.
|
||||
if(testedTransports.has(dtlsTransport1) && testedTransports.has(dtslTransport2)) {
|
||||
if(testedTransports.has(dtlsTransport1) && testedTransports.has(dtlsTransport2)) {
|
||||
t.done();
|
||||
}
|
||||
})
|
||||
|
|
|
@ -80,6 +80,8 @@
|
|||
*/
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
assert_throws(new TypeError(), () => pc.addTransceiver('invalid'));
|
||||
}, 'addTransceiver() with string argument as invalid kind should throw TypeError');
|
||||
|
@ -125,6 +127,7 @@
|
|||
*/
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
|
||||
|
@ -170,6 +173,7 @@
|
|||
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
|
||||
|
@ -214,18 +218,24 @@
|
|||
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
const transceiver = pc.addTransceiver('audio', { direction: 'sendonly' });
|
||||
assert_equals(transceiver.direction, 'sendonly');
|
||||
}, `addTransceiver() with direction sendonly should have result transceiver.direction be the same`);
|
||||
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
const transceiver = pc.addTransceiver('audio', { direction: 'inactive' });
|
||||
assert_equals(transceiver.direction, 'inactive');
|
||||
}, `addTransceiver() with direction inactive should have result transceiver.direction be the same`);
|
||||
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
assert_throws(new TypeError(), () =>
|
||||
pc.addTransceiver('audio', { direction: 'invalid' }));
|
||||
|
@ -238,8 +248,9 @@
|
|||
*/
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
const track = generateMediaStreamTrack('audio');
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
const track = generateMediaStreamTrack('audio');
|
||||
const transceiver = pc.addTransceiver(track);
|
||||
const { sender, receiver } = transceiver;
|
||||
|
||||
|
@ -276,8 +287,9 @@
|
|||
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
const track = generateMediaStreamTrack('audio');
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
const track = generateMediaStreamTrack('audio');
|
||||
const transceiver1 = pc.addTransceiver(track);
|
||||
const transceiver2 = pc.addTransceiver(track);
|
||||
|
||||
|
@ -302,7 +314,6 @@
|
|||
|
||||
}, 'addTransceiver(track) multiple times should create multiple transceivers');
|
||||
|
||||
|
||||
/*
|
||||
5.1. addTransceiver
|
||||
6. Verify that each rid value in sendEncodings is composed only of
|
||||
|
@ -310,8 +321,9 @@
|
|||
of 16 characters. If one of the RIDs does not meet these requirements,
|
||||
throw a TypeError.
|
||||
*/
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
|
||||
assert_throws(new TypeError(), () =>
|
||||
|
@ -322,8 +334,9 @@
|
|||
}));
|
||||
}, 'addTransceiver() with rid containing invalid non-alphanumeric characters should throw TypeError');
|
||||
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
assert_idl_attribute(pc, 'addTransceiver');
|
||||
|
||||
assert_throws(new TypeError(), () =>
|
||||
|
@ -334,8 +347,9 @@
|
|||
}));
|
||||
}, 'addTransceiver() with rid longer than 16 characters should throw TypeError');
|
||||
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
pc.addTransceiver('audio', {
|
||||
sendEncodings: [{
|
||||
rid: 'foo'
|
||||
|
@ -353,8 +367,9 @@
|
|||
Aside from rid , all read-only parameters in the RTCRtpEncodingParameters
|
||||
dictionaries, such as ssrc, must be left unset, or an error will be thrown.
|
||||
*/
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_throws('InvalidAccessError', () =>
|
||||
pc.addTransceiver('audio', {
|
||||
|
@ -364,8 +379,9 @@
|
|||
}));
|
||||
}, `addTransceiver() with readonly ssrc set should throw InvalidAccessError`);
|
||||
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_throws('InvalidAccessError', () =>
|
||||
pc.addTransceiver('audio', {
|
||||
|
@ -377,8 +393,9 @@
|
|||
}));
|
||||
}, `addTransceiver() with readonly rtx set should throw InvalidAccessError`);
|
||||
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
assert_throws('InvalidAccessError', () =>
|
||||
pc.addTransceiver('audio', {
|
||||
|
@ -390,8 +407,10 @@
|
|||
}));
|
||||
}, `addTransceiver() with readonly fec set should throw InvalidAccessError`);
|
||||
|
||||
test(() => {
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc.close());
|
||||
|
||||
pc.addTransceiver('audio', {
|
||||
sendEncodings: [{
|
||||
dtx: 'enabled',
|
||||
|
|
|
@ -73,7 +73,7 @@ for (const attr in initialState) {
|
|||
if (!window.pc) {
|
||||
window.pc = new RTCPeerConnection;
|
||||
}
|
||||
assert_equals(pc[attr], initialState[attr]);
|
||||
assert_equals(window.pc[attr], initialState[attr]);
|
||||
}, attr + ' initial value');
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -375,7 +375,7 @@ promise_test(t => {
|
|||
assert_not_equals(channel1.id, null,
|
||||
'Expect channel1.id to be assigned');
|
||||
|
||||
assert_greater_than_equals(channel1.id, 0,
|
||||
assert_greater_than_equal(channel1.id, 0,
|
||||
'Expect channel1.id to be set to valid unsigned short');
|
||||
|
||||
assert_less_than(channel1.id, 65535,
|
||||
|
@ -386,7 +386,7 @@ promise_test(t => {
|
|||
assert_not_equals(channel2.id, null,
|
||||
'Expect channel2.id to be assigned');
|
||||
|
||||
assert_greater_than_equals(channel2.id, 0,
|
||||
assert_greater_than_equal(channel2.id, 0,
|
||||
'Expect channel2.id to be set to valid unsigned short');
|
||||
|
||||
assert_less_than(channel2.id, 65535,
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Test legacy offerToReceiveAudio/Video options</title>
|
||||
<link rel="help" href="https://w3c.github.io/webrtc-pc/#legacy-configuration-extensions">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="RTCPeerConnection-helper.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// Run some tests for both audio and video kinds
|
||||
['audio', 'video'].forEach((kind) => {
|
||||
const capsKind = kind[0].toUpperCase() + kind.slice(1);
|
||||
|
||||
const offerToReceiveTrue = {};
|
||||
offerToReceiveTrue[`offerToReceive${capsKind}`] = true;
|
||||
|
||||
const offerToReceiveFalse = {};
|
||||
offerToReceiveFalse[`offerToReceive${capsKind}`] = false;
|
||||
|
||||
// Start testing
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
const dummy = pc.createDataChannel('foo'); // Just to have something to offer
|
||||
|
||||
return pc.createOffer(offerToReceiveFalse)
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 0,
|
||||
'Expect pc to have no transceivers');
|
||||
});
|
||||
}, `createOffer() with offerToReceive${capsKind} set to false should not create a transceiver`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return pc.createOffer(offerToReceiveTrue)
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'recvonly',
|
||||
'Expect transceiver to have "recvonly" direction');
|
||||
});
|
||||
}, `createOffer() with offerToReceive${capsKind} should create a "recvonly" transceiver`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return pc.createOffer(offerToReceiveTrue)
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'recvonly',
|
||||
'Expect transceiver to have "recvonly" direction');
|
||||
})
|
||||
.then(() => pc.createOffer(offerToReceiveTrue))
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to still have only one transceiver');
|
||||
})
|
||||
;
|
||||
}, `offerToReceive${capsKind} option should be ignored if a non-stopped "recvonly" transceiver exists`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return getTrackFromUserMedia(kind)
|
||||
.then(([track, stream]) => {
|
||||
pc.addTrack(track, stream);
|
||||
return pc.createOffer();
|
||||
})
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'sendrecv',
|
||||
'Expect transceiver to have "sendrecv" direction');
|
||||
})
|
||||
.then(() => pc.createOffer(offerToReceiveTrue))
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to still have only one transceiver');
|
||||
})
|
||||
;
|
||||
}, `offerToReceive${capsKind} option should be ignored if a non-stopped "sendrecv" transceiver exists`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return getTrackFromUserMedia(kind)
|
||||
.then(([track, stream]) => {
|
||||
pc.addTrack(track, stream);
|
||||
return pc.createOffer(offerToReceiveFalse);
|
||||
})
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'sendonly',
|
||||
'Expect transceiver to have "sendonly" direction');
|
||||
})
|
||||
;
|
||||
}, `offerToReceive${capsKind} set to false with a track should create a "sendonly" transceiver`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
pc.addTransceiver(kind, {direction: 'recvonly'});
|
||||
|
||||
return pc.createOffer(offerToReceiveFalse)
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'inactive',
|
||||
'Expect transceiver to have "inactive" direction');
|
||||
})
|
||||
;
|
||||
}, `offerToReceive${capsKind} set to false with a "recvonly" transceiver should change the direction to "inactive"`);
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
|
||||
return getTrackFromUserMedia(kind)
|
||||
.then(([track, stream]) => {
|
||||
pc.addTrack(track, stream);
|
||||
return pc.createOffer();
|
||||
})
|
||||
.then((offer) => pc.setLocalDescription(offer))
|
||||
.then(() => pc2.setRemoteDescription(pc.localDescription))
|
||||
.then(() => pc2.createAnswer())
|
||||
.then((answer) => pc2.setLocalDescription(answer))
|
||||
.then(() => pc.setRemoteDescription(pc2.localDescription))
|
||||
.then(() => pc.createOffer(offerToReceiveFalse))
|
||||
.then((offer) => {
|
||||
assert_equals(pc.getTransceivers().length, 1,
|
||||
'Expect pc to have one transceiver');
|
||||
|
||||
const transceiver = pc.getTransceivers()[0];
|
||||
assert_equals(transceiver.direction, 'sendonly',
|
||||
'Expect transceiver to have "sendonly" direction');
|
||||
})
|
||||
;
|
||||
}, `subsequent offerToReceive${capsKind} set to false with a track should change the direction to "sendonly"`);
|
||||
});
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return pc.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true })
|
||||
.then(() => {
|
||||
assert_equals(pc.getTransceivers().length, 2,
|
||||
'Expect pc to have two transceivers');
|
||||
|
||||
assert_equals(pc.getTransceivers()[0].direction, 'recvonly',
|
||||
'Expect first transceiver to have "recvonly" direction');
|
||||
assert_equals(pc.getTransceivers()[1].direction, 'recvonly',
|
||||
'Expect second transceiver to have "recvonly" direction');
|
||||
});
|
||||
}, 'offerToReceiveAudio and Video should create two "recvonly" transceivers');
|
||||
|
||||
</script>
|
|
@ -10,8 +10,8 @@
|
|||
'use strict';
|
||||
|
||||
// Test is based on the following editor draft:
|
||||
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
|
||||
// https://w3c.github.io/webrtc-stats/archives/20170614/webrtc-stats.html
|
||||
// webrtc-pc 20171130
|
||||
// webrtc-stats 20171122
|
||||
|
||||
// The following helper function is called from RTCPeerConnection-helper.js
|
||||
// getTrackFromUserMedia
|
||||
|
@ -20,39 +20,25 @@
|
|||
// validateStatsReport
|
||||
// assert_stats_report_has_stats
|
||||
|
||||
// The following helper function is called from RTCPeerConnection-helper.js
|
||||
// exchangeIceCandidates
|
||||
// doSignalingHandshake
|
||||
|
||||
/*
|
||||
8.2. RTCPeerConnection Interface Extensions
|
||||
partial interface RTCPeerConnection {
|
||||
Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
|
||||
};
|
||||
|
||||
8.3. RTCStatsReport Object
|
||||
interface RTCStatsReport {
|
||||
readonly maplike<DOMString, object>;
|
||||
};
|
||||
|
||||
8.4. RTCStats Dictionary
|
||||
dictionary RTCStats {
|
||||
DOMHighResTimeStamp timestamp;
|
||||
RTCStatsType type;
|
||||
DOMString id;
|
||||
};
|
||||
|
||||
id
|
||||
Two RTCStats objects, extracted from two different RTCStatsReport objects, MUST
|
||||
have the same id if they were produced by inspecting the same underlying object.
|
||||
|
||||
8.2. getStats
|
||||
1. Let selectorArg be the method's first argument.
|
||||
2. Let connection be the RTCPeerConnection object on which the method was invoked.
|
||||
3. If selectorArg is neither null nor a valid MediaStreamTrack, return a promise
|
||||
rejected with a newly created TypeError.
|
||||
3. If selectorArg is null, let selector be null.
|
||||
4. If selectorArg is a MediaStreamTrack let selector be an RTCRtpSender
|
||||
or RTCRtpReceiver on connection which track member matches selectorArg.
|
||||
If no such sender or receiver exists, or if more than one sender or
|
||||
receiver fit this criteria, return a promise rejected with a newly
|
||||
created InvalidAccessError.
|
||||
5. Let p be a new promise.
|
||||
6. Run the following steps in parallel:
|
||||
1. Gather the stats indicated by selector according to the stats selection algorithm.
|
||||
2. Resolve p with the resulting RTCStatsReport object, containing the gathered stats.
|
||||
*/
|
||||
|
||||
promise_test(() => {
|
||||
const pc = new RTCPeerConnection();
|
||||
return pc.getStats();
|
||||
|
@ -65,9 +51,11 @@
|
|||
|
||||
/*
|
||||
8.2. getStats
|
||||
4. Let selector be a RTCRtpSender or RTCRtpReceiver on connection which track
|
||||
member matches selectorArg. If no such sender or receiver exists, return a promise
|
||||
rejected with a newly created InvalidAccessError.
|
||||
4. If selectorArg is a MediaStreamTrack let selector be an RTCRtpSender
|
||||
or RTCRtpReceiver on connection which track member matches selectorArg.
|
||||
If no such sender or receiver exists, or if more than one sender or
|
||||
receiver fit this criteria, return a promise rejected with a newly
|
||||
created InvalidAccessError.
|
||||
*/
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
@ -94,12 +82,6 @@
|
|||
return pc.getStats(track);
|
||||
}, 'getStats() with track added via addTransceiver should succeed');
|
||||
|
||||
/*
|
||||
8.2. getStats
|
||||
4. Let selector be a RTCRtpSender or RTCRtpReceiver on connection which track
|
||||
member matches selectorArg. If more than one sender or receiver fit this criteria,
|
||||
return a promise rejected with a newly created InvalidAccessError.
|
||||
*/
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
return getTrackFromUserMedia('audio')
|
||||
|
@ -140,7 +122,35 @@
|
|||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, ['peer-connection']);
|
||||
});
|
||||
}, 'getStats() with no argument should return stats report containing peer-connection stats');
|
||||
}, 'getStats() with no argument should return stats report containing peer-connection stats on an empty PC');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
return getTrackFromUserMedia('audio')
|
||||
.then(([track, mediaStream]) => {
|
||||
pc.addTrack(track, mediaStream);
|
||||
return pc.getStats();
|
||||
})
|
||||
.then(statsReport => {
|
||||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, ['peer-connection']);
|
||||
assert_stats_report_has_stats(statsReport, ['outbound-rtp']);
|
||||
});
|
||||
}, 'getStats() with no argument should return stats report containing peer-connection stats and outbound-track-stats');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
return getTrackFromUserMedia('audio')
|
||||
.then(([track, mediaStream]) => {
|
||||
pc.addTrack(track);
|
||||
return pc.getStats();
|
||||
})
|
||||
.then(statsReport => {
|
||||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, ['peer-connection']);
|
||||
assert_stats_report_has_stats(statsReport, ['outbound-rtp']);
|
||||
});
|
||||
}, 'getStats() with no argument should return stats for no-stream tracks');
|
||||
|
||||
/*
|
||||
8.5. The stats selection algorithm
|
||||
|
@ -184,4 +194,150 @@
|
|||
});
|
||||
}, `getStats() on track associated with RtpReceiver should return stats report containing inbound-rtp stats`);
|
||||
|
||||
/*
|
||||
8.6 Mandatory To Implement Stats
|
||||
An implementation MUST support generating statistics of the following types
|
||||
when the corresponding objects exist on a PeerConnection, with the attributes
|
||||
that are listed when they are valid for that object.
|
||||
*/
|
||||
|
||||
const mandatoryStats = [
|
||||
"codec",
|
||||
"inbound-rtp",
|
||||
"outbound-rtp",
|
||||
"remote-inbound-rtp",
|
||||
"remote-outbound-rtp",
|
||||
"peer-connection",
|
||||
"data-channel",
|
||||
"stream",
|
||||
"track",
|
||||
"transport",
|
||||
"candidate-pair",
|
||||
"local-candidate",
|
||||
"remote-candidate",
|
||||
"certificate"
|
||||
];
|
||||
|
||||
async_test(t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
const dataChannel = pc1.createDataChannel('test-channel');
|
||||
|
||||
return navigator.mediaDevices.getUserMedia({
|
||||
audio: true,
|
||||
video: true
|
||||
})
|
||||
.then(t.step_func(mediaStream => {
|
||||
const tracks = mediaStream.getTracks();
|
||||
assert_equals(tracks.length, 2,
|
||||
'Expect media stream to have one audio and one video track');
|
||||
|
||||
let audioTrack;
|
||||
let videoTrack;
|
||||
|
||||
for (const track of tracks) {
|
||||
t.add_cleanup(() => track.stop());
|
||||
|
||||
pc1.addTrack(track, mediaStream);
|
||||
|
||||
if (track.kind === 'audio') {
|
||||
audioTrack = track;
|
||||
} else if (track.kind === 'video') {
|
||||
videoTrack = track;
|
||||
}
|
||||
}
|
||||
|
||||
if (!audioTrack || ! videoTrack) {
|
||||
assert_unreached('Expect mediaStream to have both audio and video streams');
|
||||
}
|
||||
|
||||
const testStatsReport = (pc, statsReport) => {
|
||||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, mandatoryStats);
|
||||
|
||||
const dataChannelStats = findStatsFromReport(statsReport,
|
||||
stats => {
|
||||
return stats.type === 'data-channel' &&
|
||||
stats.dataChannelIdentifier === dataChannel.id;
|
||||
},
|
||||
'Expect data channel stats to be found');
|
||||
|
||||
assert_equals(dataChannelStats.label, 'test-channel');
|
||||
|
||||
const audioTrackStats = findStatsFromReport(statsReport,
|
||||
stats => {
|
||||
return stats.type === 'track' &&
|
||||
stats.trackIdentifier === audioTrack.id;
|
||||
},
|
||||
'Expect audio track stats to be found');
|
||||
|
||||
assert_equals(audioTrackStats.kind, 'audio');
|
||||
|
||||
const videoTrackStats = findStatsFromReport(statsReport,
|
||||
stats => {
|
||||
return stats.type === 'track' &&
|
||||
stats.trackIdentifier === videoTrack.id;
|
||||
},
|
||||
'Expect video track stats to be found');
|
||||
|
||||
assert_equals(videoTrackStats.kind, 'video');
|
||||
|
||||
const mediaStreamStats = findStatsFromReport(statsReport,
|
||||
stats => {
|
||||
return stats.type === 'stream' &&
|
||||
stats.streamIdentifier === mediaStream.id;
|
||||
},
|
||||
'Expect media stream stats to be found');
|
||||
|
||||
assert_true(mediaStreamStats.trackIds.include(audioTrackStats.id));
|
||||
assert_true(mediaStreamStats.trackIds.include(videoTrackStats.id));
|
||||
}
|
||||
|
||||
const onConnected = t.step_func(() => {
|
||||
// Wait a while for the peer connections to collect stats
|
||||
t.step_timeout(() => {
|
||||
Promise.all([
|
||||
pc1.getStats()
|
||||
.then(statsReport => testStatsReport(pc1, statsReport)),
|
||||
|
||||
pc2.getStats()
|
||||
.then(statsReport => testStatsReport(pc2, statsReport))
|
||||
])
|
||||
.then(t.step_func_done())
|
||||
.catch(t.step_func(err => {
|
||||
assert_unreached(`test failed with error: ${err}`);
|
||||
}));
|
||||
}, 200)
|
||||
})
|
||||
|
||||
let onTrackCount = 0
|
||||
let onDataChannelCalled = false
|
||||
|
||||
pc2.addEventListener('track', t.step_func(() => {
|
||||
onTrackCount++;
|
||||
if (onTrackCount === 2 && onDataChannelCalled) {
|
||||
onConnected();
|
||||
}
|
||||
}));
|
||||
|
||||
pc2.addEventListener('datachannel', t.step_func(() => {
|
||||
onDataChannelCalled = true;
|
||||
if (onTrackCount === 2) {
|
||||
onConnected();
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
exchangeIceCandidates(pc1, pc2);
|
||||
doSignalingHandshake(pc1, pc2);
|
||||
}))
|
||||
.catch(t.step_func(err => {
|
||||
assert_unreached(`test failed with error: ${err}`);
|
||||
}));
|
||||
|
||||
}, `getStats() with connected peer connections having tracks and data channel should return all mandatory to implement stats`);
|
||||
|
||||
</script>
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset=utf-8>
|
||||
<title>IDL check of RTCPeerConnection</title>
|
||||
<link rel="author" title="Harald Alvestrand" href="mailto:hta@google.com"/>
|
||||
<link rel="help" href="http://w3c.github.io/webrtc-pc/#rtcpeerconnection-interface">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="instructions">Description</h1>
|
||||
<p class="instructions">This test verifies the availability of the RTCPeerConnection interface.</p>
|
||||
<div id='log'></div>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src=/resources/WebIDLParser.js></script>
|
||||
<script src=/resources/idlharness.js></script>
|
||||
|
||||
<!-- The IDL is copied from the 22 September 2015 editors' draft. -->
|
||||
<script type="text/plain">
|
||||
[Constructor()]
|
||||
interface EventTarget {
|
||||
// Only a dummy definition is needed here.
|
||||
};
|
||||
[ Constructor (optional RTCConfiguration configuration)]
|
||||
interface RTCPeerConnection : EventTarget {
|
||||
Promise<RTCSessionDescription> createOffer (optional RTCOfferOptions options);
|
||||
Promise<RTCSessionDescription> createAnswer (optional RTCAnswerOptions options);
|
||||
Promise<void> setLocalDescription (RTCSessionDescription description);
|
||||
readonly attribute RTCSessionDescription? localDescription;
|
||||
readonly attribute RTCSessionDescription? currentLocalDescription;
|
||||
readonly attribute RTCSessionDescription? pendingLocalDescription;
|
||||
Promise<void> setRemoteDescription (RTCSessionDescription description);
|
||||
readonly attribute RTCSessionDescription? remoteDescription;
|
||||
readonly attribute RTCSessionDescription? currentRemoteDescription;
|
||||
readonly attribute RTCSessionDescription? pendingRemoteDescription;
|
||||
Promise<void> addIceCandidate (RTCIceCandidate candidate);
|
||||
readonly attribute RTCSignalingState signalingState;
|
||||
readonly attribute RTCIceGatheringState iceGatheringState;
|
||||
readonly attribute RTCIceConnectionState iceConnectionState;
|
||||
readonly attribute boolean? canTrickleIceCandidates;
|
||||
RTCConfiguration getConfiguration ();
|
||||
void setConfiguration (RTCConfiguration configuration);
|
||||
void close ();
|
||||
attribute EventHandler onnegotiationneeded;
|
||||
attribute EventHandler onicecandidate;
|
||||
attribute EventHandler onsignalingstatechange;
|
||||
attribute EventHandler oniceconnectionstatechange;
|
||||
attribute EventHandler onicegatheringstatechange;
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
void createOffer (RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback, optional RTCOfferOptions options);
|
||||
void setLocalDescription (RTCSessionDescription description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
|
||||
void createAnswer (RTCSessionDescriptionCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);
|
||||
void setRemoteDescription (RTCSessionDescription description, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
|
||||
void addIceCandidate (RTCIceCandidate candidate, VoidFunction successCallback, RTCPeerConnectionErrorCallback failureCallback);
|
||||
void getStats (MediaStreamTrack? selector, RTCStatsCallback successCallback, RTCPeerConnectionErrorCallback failureCallback);
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
static Promise<RTCCertificate> generateCertificate (AlgorithmIdentifier keygenAlgorithm);
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
sequence<RTCRtpSender> getSenders ();
|
||||
sequence<RTCRtpReceiver> getReceivers ();
|
||||
RTCRtpSender addTrack (MediaStreamTrack track, MediaStream... streams);
|
||||
void removeTrack (RTCRtpSender sender);
|
||||
attribute EventHandler ontrack;
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
RTCDataChannel createDataChannel ([TreatNullAs=EmptyString] DOMString label, optional RTCDataChannelInit dataChannelDict);
|
||||
attribute EventHandler ondatachannel;
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
readonly attribute RTCDTMFSender? dtmf;
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
Promise<RTCStatsReport> getStats (optional MediaStreamTrack? selector);
|
||||
};
|
||||
|
||||
partial interface RTCPeerConnection {
|
||||
void setIdentityProvider (DOMString provider, optional DOMString protocol, optional DOMString usernameHint);
|
||||
Promise<DOMString> getIdentityAssertion ();
|
||||
readonly attribute Promise<RTCIdentityAssertion> peerIdentity;
|
||||
readonly attribute DOMString? idpLoginUrl;
|
||||
};
|
||||
|
||||
</script>
|
||||
<script>
|
||||
(function() {
|
||||
var idl_array = new IdlArray();
|
||||
[].forEach.call(document.querySelectorAll("script[type=text\\/plain]"),
|
||||
function(node) {
|
||||
idl_array.add_idls(node.textContent);
|
||||
});
|
||||
window.pc = new RTCPeerConnection(null);
|
||||
idl_array.add_objects({"RTCPeerConnection": ["pc"]});
|
||||
idl_array.test();
|
||||
done();
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -284,7 +284,7 @@
|
|||
pc2.setRemoteDescription(offer))
|
||||
.then(() =>
|
||||
assert_rtcerror_rejection('idp-execution-failure',
|
||||
peerIdentityPromise,
|
||||
peerIdentityPromise1,
|
||||
`Expect first peerIdentity promise to be rejected with RTCError('idp-execution-failure')`))
|
||||
.then(() => {
|
||||
const peerIdentityPromise2 = pc2.peerIdentity;
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let localTrack = tracks[0];
|
||||
const localTrack = tracks[0];
|
||||
caller.addTrack(localTrack);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
let remoteTrack = trackEvent.track;
|
||||
const remoteTrack = trackEvent.track;
|
||||
assert_equals(remoteTrack.id, localTrack.id,
|
||||
'Expected local and remote track IDs to match.');
|
||||
assert_equals(trackEvent.streams.length, 0,
|
||||
|
@ -47,15 +47,15 @@
|
|||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let localTrack = tracks[0];
|
||||
let localStream = streams[0];
|
||||
const localTrack = tracks[0];
|
||||
const localStream = streams[0];
|
||||
caller.addTrack(localTrack, localStream);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_equals(trackEvent.streams.length, 1,
|
||||
'Expected track event to fire with a single stream.');
|
||||
let remoteTrack = trackEvent.track;
|
||||
let remoteStream = trackEvent.streams[0];
|
||||
const remoteTrack = trackEvent.track;
|
||||
const remoteStream = trackEvent.streams[0];
|
||||
assert_equals(remoteTrack.id, localTrack.id,
|
||||
'Expected local and remote track IDs to match.');
|
||||
assert_equals(remoteStream.id, localStream.id,
|
||||
|
@ -71,22 +71,50 @@
|
|||
}));
|
||||
}, 'addTrack() with a track and a stream makes ontrack fire with a track and a stream.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
let eventSequence = '';
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const ontrackResolver = new Resolver();
|
||||
callee.ontrack = () => {
|
||||
eventSequence += 'ontrack;';
|
||||
ontrackResolver.resolve();
|
||||
}
|
||||
caller.addTrack(tracks[0]);
|
||||
return Promise.all([
|
||||
ontrackResolver.promise,
|
||||
performOffer(caller, callee).then(() => {
|
||||
eventSequence += 'setRemoteDescription;';
|
||||
})
|
||||
]);
|
||||
}))
|
||||
.then(t.step_func(() => {
|
||||
assert_equals(eventSequence, 'ontrack;setRemoteDescription;');
|
||||
t.done();
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'ontrack fires before setRemoteDescription resolves.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(2)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let localTrack1 = tracks[0];
|
||||
let localTrack2 = tracks[1];
|
||||
let localStream = streams[0];
|
||||
const localTrack1 = tracks[0];
|
||||
const localTrack2 = tracks[1];
|
||||
const localStream = streams[0];
|
||||
caller.addTrack(localTrack1, localStream);
|
||||
caller.addTrack(localTrack2, localStream);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_equals(trackEvent.streams.length, 1,
|
||||
'Expected track event to fire with a single stream.');
|
||||
let remoteTrack1 = trackEvent.track;
|
||||
let remoteStream = trackEvent.streams[0];
|
||||
const remoteTrack1 = trackEvent.track;
|
||||
const remoteStream = trackEvent.streams[0];
|
||||
assert_equals(remoteTrack1.id, localTrack1.id,
|
||||
'Expected first remote track ID to match first local track ID.');
|
||||
assert_equals(remoteStream.getTracks().length, 2,
|
||||
|
@ -94,7 +122,7 @@
|
|||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_equals(trackEvent.streams.length, 1,
|
||||
'Expected track event to fire with a single stream.');
|
||||
let remoteTrack2 = trackEvent.track;
|
||||
const remoteTrack2 = trackEvent.track;
|
||||
assert_equals(trackEvent.streams[0], remoteStream,
|
||||
'Expected both track events to fire with the same remote stream.');
|
||||
assert_equals(remoteTrack2.id, localTrack2.id,
|
||||
|
@ -151,17 +179,53 @@
|
|||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
let eventSequence = '';
|
||||
return getUserMediaTracksAndStreams(2)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let localTrack = tracks[0];
|
||||
let localStreams = streams;
|
||||
const localTracks = tracks;
|
||||
const localStream = streams[0];
|
||||
caller.addTrack(localTracks[0], localStream);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
callee.ontrack = null;
|
||||
const remoteStream = trackEvent.streams[0];
|
||||
const onaddtrackResolver = new Resolver();
|
||||
remoteStream.onaddtrack = () => {
|
||||
eventSequence += 'stream.onaddtrack;';
|
||||
onaddtrackResolver.resolve();
|
||||
}
|
||||
caller.addTrack(localTracks[1], localStream);
|
||||
Promise.all([
|
||||
onaddtrackResolver.promise,
|
||||
performOffer(caller, callee).then(() => {
|
||||
eventSequence += 'setRemoteDescription;';
|
||||
})
|
||||
]).then(t.step_func(() => {
|
||||
assert_equals(eventSequence, 'stream.onaddtrack;setRemoteDescription;');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
return offerPromise;
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'stream.onaddtrack fires before setRemoteDescription resolves.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(2)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const localTrack = tracks[0];
|
||||
const localStreams = streams;
|
||||
caller.addTrack(localTrack, localStreams[0], localStreams[1]);
|
||||
let performOffer = performOffer(caller, callee);
|
||||
const performOffer = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_equals(trackEvent.streams.length, 2,
|
||||
'Expected the track event to fire with two streams.');
|
||||
let remoteTrack = trackEvent.track;
|
||||
let remoteStreams = trackEvent.streams;
|
||||
const remoteTrack = trackEvent.track;
|
||||
const remoteStreams = trackEvent.streams;
|
||||
assert_equals(remoteTrack.id, localTrack.id,
|
||||
'Expected local and remote track IDs to match.');
|
||||
assert_equals(remoteStreams[0].id, localStreams[0].id,
|
||||
|
@ -184,38 +248,10 @@
|
|||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
let eventSequence = '';
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
caller.addTrack(tracks[0]);
|
||||
let ontrackResolver = new Resolver();
|
||||
callee.ontrack = () => {
|
||||
eventSequence += 'ontrack;';
|
||||
ontrackResolver.resolve();
|
||||
}
|
||||
return Promise.all([
|
||||
ontrackResolver.promise,
|
||||
performOffer(caller, callee).then(() => {
|
||||
eventSequence += 'setRemoteDescription;';
|
||||
})
|
||||
]);
|
||||
}))
|
||||
.then(t.step_func(() => {
|
||||
assert_equals(eventSequence, 'ontrack;setRemoteDescription;');
|
||||
t.done();
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'ontrack fires before setRemoteDescription resolves.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
caller.addTrack(tracks[0]);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_array_equals(callee.getReceivers(), [trackEvent.receiver]);
|
||||
t.done();
|
||||
|
@ -232,11 +268,11 @@
|
|||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let sender = caller.addTrack(tracks[0]);
|
||||
assert_true(sender != null);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const sender = caller.addTrack(tracks[0]);
|
||||
assert_not_equals(sender, null);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
let receivers = callee.getReceivers();
|
||||
const receivers = callee.getReceivers();
|
||||
assert_equals(receivers.length, 1,
|
||||
'Expected getReceivers() to be the track event\'s receiver.');
|
||||
caller.removeTrack(sender);
|
||||
|
@ -259,9 +295,9 @@
|
|||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let sender = caller.addTrack(tracks[0], streams[0]);
|
||||
assert_true(sender != null);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
assert_not_equals(sender, null);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_not_equals(trackEvent.track, null);
|
||||
assert_equals(trackEvent.streams.length, 1);
|
||||
|
@ -279,21 +315,55 @@
|
|||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'removeTrack() causes onremovetrack and the track to be removed from the stream.');
|
||||
}, 'removeTrack() makes stream.onremovetrack fire and the track to be removed from the stream.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
let eventSequence = '';
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
assert_not_equals(sender, null);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
const remoteStream = trackEvent.streams[0];
|
||||
const onremovetrackResolver = new Resolver();
|
||||
remoteStream.onremovetrack = t.step_func(removeEvent => {
|
||||
eventSequence += 'stream.onremovetrack;';
|
||||
onremovetrackResolver.resolve();
|
||||
});
|
||||
caller.removeTrack(sender);
|
||||
return Promise.all([
|
||||
onremovetrackResolver.promise,
|
||||
performOffer(caller, callee).then(() => {
|
||||
eventSequence += 'setRemoteDescription;';
|
||||
})
|
||||
]).then(t.step_func(() => {
|
||||
assert_equals(eventSequence, 'stream.onremovetrack;setRemoteDescription;');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
return offerPromise;
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'stream.onremovetrack fires before setRemoteDescription resolves.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
let sender = caller.addTrack(tracks[0]);
|
||||
assert_true(sender != null);
|
||||
let offerPromise = performOffer(caller, callee);
|
||||
const sender = caller.addTrack(tracks[0]);
|
||||
assert_not_equals(sender, null);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
assert_not_equals(trackEvent.track, null);
|
||||
const remoteTrack = trackEvent.track;
|
||||
caller.removeTrack(sender);
|
||||
performOffer(caller, callee);
|
||||
trackEvent.track.onmute = t.step_func(() => {
|
||||
remoteTrack.onmute = t.step_func(() => {
|
||||
assert_true(trackEvent.track.muted);
|
||||
t.done();
|
||||
});
|
||||
|
@ -303,6 +373,54 @@
|
|||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'removeTrack() causes onmute and the track to be muted.');
|
||||
}, 'removeTrack() makes track.onmute fire and the track to be muted.');
|
||||
|
||||
async_test(t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
const callee = new RTCPeerConnection();
|
||||
let eventSequence = '';
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const sender = caller.addTrack(tracks[0]);
|
||||
assert_not_equals(sender, null);
|
||||
const offerPromise = performOffer(caller, callee);
|
||||
callee.ontrack = t.step_func(trackEvent => {
|
||||
const remoteTrack = trackEvent.track;
|
||||
const onmuteResolver = new Resolver();
|
||||
remoteTrack.onmute = t.step_func(() => {
|
||||
eventSequence += 'track.onmute;';
|
||||
onmuteResolver.resolve();
|
||||
});
|
||||
caller.removeTrack(sender);
|
||||
return Promise.all([
|
||||
onmuteResolver.promise,
|
||||
performOffer(caller, callee).then(() => {
|
||||
eventSequence += 'setRemoteDescription;';
|
||||
})
|
||||
]).then(t.step_func(() => {
|
||||
assert_equals(eventSequence, 'track.onmute;setRemoteDescription;');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
return offerPromise;
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'track.onmute fires before setRemoteDescription resolves.');
|
||||
|
||||
async_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
return getUserMediaTracksAndStreams(1)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const sender = pc.addTrack(tracks[0]);
|
||||
assert_not_equals(sender, null);
|
||||
pc.removeTrack(sender);
|
||||
pc.removeTrack(sender);
|
||||
t.done();
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'removeTrack() twice is safe.');
|
||||
</script>
|
||||
|
|
|
@ -48,5 +48,5 @@ function validateCodecCapability(codec) {
|
|||
}
|
||||
|
||||
function validateHeaderExtensionCapability(headerExt) {
|
||||
assert_optional_string_field(uri);
|
||||
assert_optional_string_field(headerExt, 'uri');
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
'use strict';
|
||||
|
||||
// Test is based on the following editor draft:
|
||||
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
|
||||
// https://w3c.github.io/webrtc-stats/archives/20170614/webrtc-stats.html
|
||||
// webrtc-pc 20171130
|
||||
// webrtc-stats 20171122
|
||||
|
||||
// The following helper function is called from RTCStats-helper.js
|
||||
// validateStatsReport
|
||||
|
@ -18,11 +18,6 @@
|
|||
|
||||
/*
|
||||
5.2. RTCRtpSender Interface
|
||||
interface RTCRtpSender {
|
||||
Promise<RTCStatsReport> getStats();
|
||||
...
|
||||
};
|
||||
|
||||
getStats
|
||||
1. Let selector be the RTCRtpSender object on which the method was invoked.
|
||||
2. Let p be a new promise, and run the following steps in parallel:
|
||||
|
@ -49,6 +44,22 @@
|
|||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, ['outbound-rtp']);
|
||||
});
|
||||
}, 'sender.getStats() should return stats report containing outbound-rtp stats');
|
||||
}, 'sender.getStats() via addTransceiver should return stats report containing outbound-rtp stats');
|
||||
|
||||
promise_test(() => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
||||
return navigator.mediaDevices.getUserMedia({ audio: true })
|
||||
.then(mediaStream => {
|
||||
const [track] = mediaStream.getTracks();
|
||||
const sender = pc.addTrack(track, mediaStream);
|
||||
|
||||
return sender.getStats()
|
||||
.then(statsReport => {
|
||||
validateStatsReport(statsReport);
|
||||
assert_stats_report_has_stats(statsReport, ['outbound-rtp']);
|
||||
});
|
||||
})
|
||||
}, 'sender.getStats() via addTrack should return stats report containing outbound-rtp stats');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,181 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>RTCSctpTransport.prototype.maxMessageSize</title>
|
||||
<link rel="help" href="https://w3c.github.io/webrtc-pc/#rtcsctptransport-interface">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script src="RTCPeerConnection-helper.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
// This test has an assert_unreached() that requires that the variable
|
||||
// canSendSize (initiated below) is greater than 2, if non-zero. The reason
|
||||
// is that we need two non-zero values that are less that that value for
|
||||
// testing with predictable results. This is a bit unfortunate but shouldn't
|
||||
// have any practical impact.
|
||||
|
||||
// Helper class to read SDP attributes and generate SDPs with modified attribute values
|
||||
class SDPAttributeHelper {
|
||||
constructor(attrName, valueRegExpStr) {
|
||||
this.attrName = attrName;
|
||||
this.re = new RegExp(`^a=${attrName}:(${valueRegExpStr})\\r\\n`, 'm');
|
||||
}
|
||||
|
||||
getValue(sdp) {
|
||||
const matches = sdp.match(this.re);
|
||||
return matches ? matches[1] : null;
|
||||
}
|
||||
|
||||
sdpWithValue(sdp, value) {
|
||||
const matches = sdp.match(this.re);
|
||||
const sdpParts = sdp.split(matches[0]);
|
||||
const attributeLine = arguments.length > 1 ? `a=${this.attrName}:${value}\r\n` : '';
|
||||
return `${sdpParts[0]}${attributeLine}${sdpParts[1]}`;
|
||||
}
|
||||
|
||||
sdpWithoutAttribute(sdp) {
|
||||
return this.sdpWithValue(sdp);
|
||||
}
|
||||
}
|
||||
|
||||
const mmsAttributeHelper = new SDPAttributeHelper('max-message-size', '\\d+');
|
||||
let canSendSize;
|
||||
const remoteValue1 = 1;
|
||||
const remoteValue2 = 2;
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
assert_equals(pc.sctp, null);
|
||||
let maxMessageSize;
|
||||
|
||||
return generateOffer({ pc, data: true })
|
||||
.then((offer) => {
|
||||
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
|
||||
'SDP should have max-message-size attribute');
|
||||
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, 0) };
|
||||
return pc.setRemoteDescription(offer);
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
canSendSize = pc.sctp.maxMessageSize == Number.POSITIVE_INFINITY ? 0 : pc.sctp.maxMessageSize;
|
||||
if (canSendSize != 0 && canSendSize < remoteValue2) {
|
||||
assert_unreached('This test needs two values that are less than canSendSize (unless it is zero)');
|
||||
}
|
||||
});
|
||||
}, 'Determine the local side send limitation (canSendSize) by offering a max-message-size of 0');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
assert_equals(pc.sctp, null);
|
||||
|
||||
return generateOffer({ pc, data: true })
|
||||
.then((offer) => {
|
||||
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
|
||||
'SDP should have max-message-size attribute');
|
||||
|
||||
// Remove the max-message-size SDP attribute
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithoutAttribute(offer.sdp) };
|
||||
return pc.setRemoteDescription(offer)
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
// Test outcome depends on canSendSize value
|
||||
if (canSendSize) {
|
||||
assert_equals(pc.sctp.maxMessageSize, Math.min(65535, canSendSize),
|
||||
'Missing SDP attribute and a non-zero canSendSize should give an maxMessageSize of min(65535, canSendSize)');
|
||||
} else {
|
||||
assert_equals(pc.sctp.maxMessageSize, 65535,
|
||||
'Missing SDP attribute and a canSendSize of 0 should give an maxMessageSize of 65535');
|
||||
}
|
||||
});
|
||||
}, 'Remote offer SDP missing max-message-size attribute');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
assert_equals(pc.sctp, null);
|
||||
|
||||
return generateOffer({ pc, data: true })
|
||||
.then((offer) => {
|
||||
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
|
||||
'SDP should have max-message-size attribute');
|
||||
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
|
||||
return pc.setRemoteDescription(offer);
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
assert_equals(pc.sctp.maxMessageSize, remoteValue1,
|
||||
'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
|
||||
});
|
||||
}, 'max-message-size with a (non-zero) value provided by the remote peer');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
assert_equals(pc.sctp, null);
|
||||
|
||||
return generateOffer({ pc, data: true })
|
||||
.then((offer) => {
|
||||
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
|
||||
'SDP should have max-message-size attribute');
|
||||
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue1) };
|
||||
return pc.setRemoteDescription(offer)
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
assert_equals(pc.sctp.maxMessageSize, remoteValue1,
|
||||
'maxMessageSize should be the value provided by the remote peer (as long as it is less than canSendSize)');
|
||||
})
|
||||
.then(() => pc.createOffer()) // Start new O/A exchange that updates max-message-size
|
||||
.then((offer) => {
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, remoteValue2)};
|
||||
return pc.setRemoteDescription(offer)
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
assert_equals(pc.sctp.maxMessageSize, remoteValue2,
|
||||
'maxMessageSize should be the new value provided by the remote peer (as long as it is less than canSendSize)');
|
||||
})
|
||||
;
|
||||
}, 'Renegotiate max-message-size with a (non-zero) value provided by the remote peer');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
assert_equals(pc.sctp, null);
|
||||
const largerThanCanSendSize = canSendSize + 1;
|
||||
|
||||
return generateOffer({ pc, data: true })
|
||||
.then((offer) => {
|
||||
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
|
||||
'SDP should have max-message-size attribute');
|
||||
|
||||
offer = { type: 'offer', sdp: mmsAttributeHelper.sdpWithValue(offer.sdp, largerThanCanSendSize) };
|
||||
return pc.setRemoteDescription(offer)
|
||||
})
|
||||
.then(() => pc.createAnswer())
|
||||
.then((answer) => pc.setLocalDescription(answer))
|
||||
.then(() => {
|
||||
assert_not_equals(pc.sctp, null);
|
||||
// Test outcome depends on canSendSize value
|
||||
if (canSendSize) {
|
||||
assert_equals(pc.sctp.maxMessageSize, canSendSize,
|
||||
'A remote value larger than a non-zero canSendSize should limit maxMessageSize to canSendSize');
|
||||
} else {
|
||||
assert_equals(pc.sctp.maxMessageSize, 65535,
|
||||
'A canSendSize of zero should let the remote value set maxMessageSize');
|
||||
}
|
||||
});
|
||||
}, 'max-message-size with a (non-zero) value larger than canSendSize provided by the remote peer');
|
||||
|
||||
</script>
|
|
@ -1,18 +1,12 @@
|
|||
'use strict';
|
||||
|
||||
// Test is based on the following editor draft:
|
||||
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
|
||||
// https://w3c.github.io/webrtc-stats/archives/20170614/webrtc-stats.html
|
||||
|
||||
// webrtc-pc 20171130
|
||||
// webrtc-stats 20171122
|
||||
|
||||
// This file depends on dictionary-helper.js which should
|
||||
// be loaded from the main HTML file.
|
||||
|
||||
// To improve readability, the WebIDL definitions of the Stats
|
||||
// dictionaries are modified to annotate with required fields when
|
||||
// they are required by section 8.6 of webrtc-pc. ID fields are
|
||||
// also annotated with the stats type that they are linked to.
|
||||
|
||||
/*
|
||||
[webrtc-stats]
|
||||
6.1. RTCStatsType enum
|
||||
|
@ -82,6 +76,16 @@ function assert_stats_report_has_stats(statsReport, statsTypes) {
|
|||
}
|
||||
}
|
||||
|
||||
function findStatsFromReport(statsReport, predicate, message) {
|
||||
for (const stats of statsReport.values()) {
|
||||
if (predicate(stats)) {
|
||||
return stats;
|
||||
}
|
||||
}
|
||||
|
||||
assert_unreached(message || 'none of stats in statsReport satisfy given condition')
|
||||
}
|
||||
|
||||
// Get stats object of type that is expected to be
|
||||
// found in the statsReport
|
||||
function getRequiredStats(statsReport, type) {
|
||||
|
@ -132,7 +136,7 @@ function validateOptionalIdField(statsReport, stats, field, type) {
|
|||
};
|
||||
*/
|
||||
function validateRtcStats(statsReport, stats) {
|
||||
assert_number_field(stats, 'timeStamp');
|
||||
assert_number_field(stats, 'timestamp');
|
||||
assert_string_field(stats, 'type');
|
||||
assert_string_field(stats, 'id');
|
||||
}
|
||||
|
@ -141,35 +145,32 @@ function validateRtcStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.1. RTCRTPStreamStats dictionary
|
||||
dictionary RTCRTPStreamStats : RTCStats {
|
||||
required unsigned long ssrc;
|
||||
required DOMString mediaType;
|
||||
|
||||
[RTCMediaStreamTrackStats]
|
||||
required DOMString trackId;
|
||||
|
||||
[RTCTransportStats]
|
||||
required DOMString transportId;
|
||||
|
||||
[RTCCodecStats]
|
||||
required DOMString codecId;
|
||||
|
||||
unsigned long firCount;
|
||||
unsigned long pliCount;
|
||||
required unsigned long nackCount;
|
||||
unsigned long sliCount;
|
||||
unsigned long long qpSum;
|
||||
unsigned long ssrc;
|
||||
DOMString mediaType;
|
||||
DOMString trackId;
|
||||
DOMString transportId;
|
||||
DOMString codecId;
|
||||
unsigned long firCount;
|
||||
unsigned long pliCount;
|
||||
unsigned long nackCount;
|
||||
unsigned long sliCount;
|
||||
unsigned long long qpSum;
|
||||
};
|
||||
|
||||
mediaType of type DOMString
|
||||
Either "audio" or "video".
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCRTPStreamStats, with attributes ssrc, associateStatsId, isRemote, mediaType,
|
||||
mediaTrackId, transportId, codecId, nackCount
|
||||
- RTCRTPStreamStats, with attributes ssrc, mediaType, trackId,
|
||||
transportId, codecId, nackCount
|
||||
*/
|
||||
function validateRtpStreamStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
assert_unsigned_int_field(stats, 'ssrc');
|
||||
assert_string_field(stats, 'mediaType');
|
||||
assert_enum_field(stats, 'mediaType', ['audio', 'video'])
|
||||
|
||||
validateIdField(statsReport, stats, 'trackId', 'track');
|
||||
validateIdField(statsReport, stats, 'transportId', 'transport');
|
||||
|
@ -186,15 +187,12 @@ function validateRtpStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.2. RTCCodecStats dictionary
|
||||
dictionary RTCCodecStats : RTCStats {
|
||||
required unsigned long payloadType;
|
||||
required RTCCodecType codecType;
|
||||
|
||||
[RTCTransportStats]
|
||||
unsigned long payloadType;
|
||||
RTCCodecType codecType;
|
||||
DOMString transportId;
|
||||
|
||||
DOMString mimeType;
|
||||
required unsigned long clockRate;
|
||||
required unsigned long channels;
|
||||
unsigned long clockRate;
|
||||
unsigned long channels;
|
||||
DOMString sdpFmtpLine;
|
||||
DOMString implementation;
|
||||
};
|
||||
|
@ -206,7 +204,7 @@ function validateRtpStreamStats(statsReport, stats) {
|
|||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCCodecStats, with attributes payloadType, codec, clockRate, channels, parameters
|
||||
- RTCCodecStats, with attributes payloadType, codec, clockRate, channels, sdpFmtpLine
|
||||
*/
|
||||
|
||||
function validateCodecStats(statsReport, stats) {
|
||||
|
@ -221,7 +219,7 @@ function validateCodecStats(statsReport, stats) {
|
|||
assert_unsigned_int_field(stats, 'clockRate');
|
||||
assert_unsigned_int_field(stats, 'channels');
|
||||
|
||||
assert_optional_string_field(stats, 'sdpFmtpLine');
|
||||
assert_string_field(stats, 'sdpFmtpLine');
|
||||
assert_optional_string_field(stats, 'implementation');
|
||||
}
|
||||
|
||||
|
@ -229,34 +227,42 @@ function validateCodecStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.3. RTCReceivedRTPStreamStats dictionary
|
||||
dictionary RTCReceivedRTPStreamStats : RTCRTPStreamStats {
|
||||
unsigned long packetsReceived;
|
||||
unsigned long long bytesReceived;
|
||||
unsigned long packetsLost;
|
||||
double jitter;
|
||||
double fractionLost;
|
||||
unsigned long packetsDiscarded;
|
||||
unsigned long packetsRepaired;
|
||||
unsigned long burstPacketsLost;
|
||||
unsigned long burstPacketsDiscarded;
|
||||
unsigned long burstLossCount;
|
||||
unsigned long burstDiscardCount;
|
||||
double burstLossRate;
|
||||
double burstDiscardRate;
|
||||
double gapLossRate;
|
||||
double gapDiscardRate;
|
||||
unsigned long packetsReceived;
|
||||
unsigned long long bytesReceived;
|
||||
long packetsLost;
|
||||
double jitter;
|
||||
double fractionLost;
|
||||
unsigned long packetsDiscarded;
|
||||
unsigned long packetsFailedDecryption;
|
||||
unsigned long packetsRepaired;
|
||||
unsigned long burstPacketsLost;
|
||||
unsigned long burstPacketsDiscarded;
|
||||
unsigned long burstLossCount;
|
||||
unsigned long burstDiscardCount;
|
||||
double burstLossRate;
|
||||
double burstDiscardRate;
|
||||
double gapLossRate;
|
||||
double gapDiscardRate;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCReceivedRTPStreamStats, with all required attributes from its
|
||||
inherited dictionaries, and also attributes packetsReceived,
|
||||
bytesReceived, packetsLost, jitter, packetsDiscarded
|
||||
*/
|
||||
function validateReceivedRtpStreamStats(statsReport, stats) {
|
||||
validateRtpStreamStats(statsReport, stats);
|
||||
|
||||
assert_optional_unsigned_int_field(stats, 'packetsReceived');
|
||||
assert_optional_unsigned_int_field(stats, 'bytesReceived');
|
||||
assert_optional_unsigned_int_field(stats, 'packetsLost');
|
||||
assert_unsigned_int_field(stats, 'packetsReceived');
|
||||
assert_unsigned_int_field(stats, 'bytesReceived');
|
||||
assert_unsigned_int_field(stats, 'packetsLost');
|
||||
|
||||
assert_optional_number_field(stats, 'jitter');
|
||||
assert_number_field(stats, 'jitter');
|
||||
assert_optional_number_field(stats, 'fractionLost');
|
||||
|
||||
assert_optional_unsigned_int_field(stats, 'packetsDiscarded');
|
||||
assert_unsigned_int_field(stats, 'packetsDiscarded');
|
||||
assert_optional_unsigned_int_field(stats, 'packetsFailedDecryption');
|
||||
assert_optional_unsigned_int_field(stats, 'packetsRepaired');
|
||||
assert_optional_unsigned_int_field(stats, 'burstPacketsLost');
|
||||
assert_optional_unsigned_int_field(stats, 'burstPacketsDiscarded');
|
||||
|
@ -273,37 +279,21 @@ function validateReceivedRtpStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.4. RTCInboundRTPStreamStats dictionary
|
||||
dictionary RTCInboundRTPStreamStats : RTCReceivedRTPStreamStats {
|
||||
required unsigned long packetsReceived;
|
||||
required unsigned long long bytesReceived;
|
||||
required unsigned long packetsLost;
|
||||
required double jitter;
|
||||
required unsigned long packetsDiscarded;
|
||||
|
||||
[RTCRemoteOutboundRTPStreamStats]
|
||||
DOMString remoteId;
|
||||
|
||||
unsigned long framesDecoded;
|
||||
DOMHighResTimeStamp lastPacketReceivedTimestamp;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCInboundRTPStreamStats, with all required attributes from RTCRTPStreamStats,
|
||||
and also attributes packetsReceived, bytesReceived, packetsLost, jitter,
|
||||
packetsDiscarded
|
||||
- RTCInboundRTPStreamStats, with all required attributes from its inherited
|
||||
dictionaries, and also attributes remoteId, framesDecoded
|
||||
*/
|
||||
function validateInboundRtpStreamStats(statsReport, stats) {
|
||||
validateReceivedRtpStreamStats(statsReport, stats);
|
||||
|
||||
assert_unsigned_int_field(stats, 'packetsReceived');
|
||||
assert_unsigned_int_field(stats, 'bytesReceived');
|
||||
assert_unsigned_int_field(stats, 'packetsLost');
|
||||
assert_number_field(stats, 'jitter');
|
||||
assert_unsigned_int_field(stats, 'packetsDiscarded');
|
||||
|
||||
validateOptionalIdField(statsReport, stats, 'remoteId', 'remote-outbound-rtp');
|
||||
|
||||
assert_optional_unsigned_int_field(stats, 'framesDecoded');
|
||||
validateIdField(statsReport, stats, 'remoteId', 'remote-outbound-rtp');
|
||||
assert_unsigned_int_field(stats, 'framesDecoded');
|
||||
assert_optional_number_field(stats, 'lastPacketReceivedTimeStamp');
|
||||
}
|
||||
|
||||
|
@ -311,18 +301,20 @@ function validateInboundRtpStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.5. RTCRemoteInboundRTPStreamStats dictionary
|
||||
dictionary RTCRemoteInboundRTPStreamStats : RTCReceivedRTPStreamStats {
|
||||
[RTCOutboundRTPStreamStats]
|
||||
DOMString localId;
|
||||
|
||||
double roundTripTime;
|
||||
DOMString localId;
|
||||
double roundTripTime;
|
||||
};
|
||||
*/
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCRemoteInboundRTPStreamStats, with all required attributes from its
|
||||
inherited dictionaries, and also attributes localId, roundTripTime
|
||||
*/
|
||||
function validateRemoteInboundRtpStreamStats(statsReport, stats) {
|
||||
validateReceivedRtpStreamStats(statsReport, stats);
|
||||
|
||||
validateOptionalIdField(statsReport, stats, 'localId', 'outbound-rtp');
|
||||
assert_optional_number_field(stats, 'roundTripTime');
|
||||
validateIdField(statsReport, stats, 'localId', 'outbound-rtp');
|
||||
assert_number_field(stats, 'roundTripTime');
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -334,13 +326,18 @@ function validateRemoteInboundRtpStreamStats(statsReport, stats) {
|
|||
unsigned long long bytesSent;
|
||||
unsigned long long bytesDiscardedOnSend;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCSentRTPStreamStats, with all required attributes from its inherited
|
||||
dictionaries, and also attributes packetsSent, bytesSent
|
||||
*/
|
||||
function validateSentRtpStreamStats(statsReport, stats) {
|
||||
validateRtpStreamStats(statsReport, stats);
|
||||
|
||||
assert_optional_unsigned_int_field(stats, 'packetsSent');
|
||||
assert_unsigned_int_field(stats, 'packetsSent');
|
||||
assert_optional_unsigned_int_field(stats, 'packetsDiscardedOnSend');
|
||||
assert_optional_unsigned_int_field(stats, 'bytesSent');
|
||||
assert_unsigned_int_field(stats, 'bytesSent');
|
||||
assert_optional_unsigned_int_field(stats, 'bytesDiscardedOnSend');
|
||||
}
|
||||
|
||||
|
@ -348,12 +345,7 @@ function validateSentRtpStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.7. RTCOutboundRTPStreamStats dictionary
|
||||
dictionary RTCOutboundRTPStreamStats : RTCSentRTPStreamStats {
|
||||
required unsigned long packetsSent;
|
||||
required unsigned long long bytesSent;
|
||||
|
||||
[RTCRemoteInboundRTPStreamStats]
|
||||
DOMString remoteId;
|
||||
|
||||
DOMHighResTimeStamp lastPacketSentTimestamp;
|
||||
double targetBitrate;
|
||||
unsigned long framesEncoded;
|
||||
|
@ -361,20 +353,19 @@ function validateSentRtpStreamStats(statsReport, stats) {
|
|||
double averageRTCPInterval;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCOutboundRTPStreamStats, with all required attributes from RTCRTPStreamStats,
|
||||
and also attributes packetsSent, bytesSent, roundTripTime
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCOutboundRTPStreamStats, with all required attributes from its
|
||||
inherited dictionaries, and also attributes remoteId, framesEncoded
|
||||
*/
|
||||
function validateOutboundRtpStreamStats(statsReport, stats) {
|
||||
validateOptionalIdField(statsReport, stats, 'remoteId', 'remote-inbound-rtp');
|
||||
validateSentRtpStreamStats(statsReport, stats)
|
||||
|
||||
assert_unsigned_int_field(stats, 'packetsSent');
|
||||
assert_unsigned_int_field(stats, 'bytesSent');
|
||||
validateIdField(statsReport, stats, 'remoteId', 'remote-inbound-rtp');
|
||||
|
||||
assert_optional_number_field(stats, 'lastPacketSentTimestamp');
|
||||
assert_optional_number_field(stats, 'targetBitrate');
|
||||
assert_optional_unsigned_int_field(stats, 'framesEncoded');
|
||||
assert_unsigned_int_field(stats, 'framesEncoded');
|
||||
assert_optional_number_field(stats, 'totalEncodeTime');
|
||||
assert_optional_number_field(stats, 'averageRTCPInterval');
|
||||
}
|
||||
|
@ -383,17 +374,20 @@ function validateOutboundRtpStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.8. RTCRemoteOutboundRTPStreamStats dictionary
|
||||
dictionary RTCRemoteOutboundRTPStreamStats : RTCSentRTPStreamStats {
|
||||
[RTCInboundRTPStreamStats]
|
||||
DOMString localId;
|
||||
|
||||
DOMHighResTimeStamp remoteTimestamp;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCRemoteOutboundRTPStreamStats, with all required attributes from its
|
||||
inherited dictionaries, and also attributes localId, remoteTimestamp
|
||||
*/
|
||||
function validateRemoteOutboundRtpStreamStats(statsReport, stats) {
|
||||
validateSentRtpStreamStats(statsReport, stats);
|
||||
|
||||
validateOptionalIdField(statsReport, stats, 'localId', 'inbound-rtp');
|
||||
assert_optional_number_field(stats, 'remoteTimeStamp');
|
||||
validateIdField(statsReport, stats, 'localId', 'inbound-rtp');
|
||||
assert_number_field(stats, 'remoteTimeStamp');
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -401,10 +395,7 @@ function validateRemoteOutboundRtpStreamStats(statsReport, stats) {
|
|||
7.9. RTCRTPContributingSourceStats
|
||||
dictionary RTCRTPContributingSourceStats : RTCStats {
|
||||
unsigned long contributorSsrc;
|
||||
|
||||
[RTCInboundRTPStreamStats]
|
||||
DOMString inboundRtpStreamId;
|
||||
|
||||
unsigned long packetsContributedTo;
|
||||
double audioLevel;
|
||||
};
|
||||
|
@ -423,10 +414,10 @@ function validateContributingSourceStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.10. RTCPeerConnectionStats dictionary
|
||||
dictionary RTCPeerConnectionStats : RTCStats {
|
||||
required unsigned long dataChannelsOpened;
|
||||
required unsigned long dataChannelsClosed;
|
||||
unsigned long dataChannelsRequested;
|
||||
unsigned long dataChannelsAccepted;
|
||||
unsigned long dataChannelsOpened;
|
||||
unsigned long dataChannelsClosed;
|
||||
unsigned long dataChannelsRequested;
|
||||
unsigned long dataChannelsAccepted;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -446,10 +437,8 @@ function validatePeerConnectionStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.11. RTCMediaStreamStats dictionary
|
||||
dictionary RTCMediaStreamStats : RTCStats {
|
||||
required DOMString streamIdentifier;
|
||||
|
||||
[RTCMediaStreamTrackStats]
|
||||
required sequence<DOMString> trackIds;
|
||||
DOMString streamIdentifier;
|
||||
sequence<DOMString> trackIds;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -479,35 +468,37 @@ function validateMediaStreamStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.12. RTCMediaStreamTrackStats dictionary
|
||||
dictionary RTCMediaStreamTrackStats : RTCStats {
|
||||
required DOMString trackIdentifier;
|
||||
required boolean remoteSource;
|
||||
required boolean ended;
|
||||
required boolean detached;
|
||||
DOMString kind;
|
||||
DOMHighResTimeStamp estimatedPlayoutTimestamp;
|
||||
required unsigned long frameWidth;
|
||||
required unsigned long frameHeight;
|
||||
required double framesPerSecond;
|
||||
unsigned long framesCaptured;
|
||||
required unsigned long framesSent;
|
||||
required unsigned long framesReceived;
|
||||
required unsigned long framesDecoded;
|
||||
required unsigned long framesDropped;
|
||||
required unsigned long framesCorrupted;
|
||||
unsigned long partialFramesLost;
|
||||
unsigned long fullFramesLost;
|
||||
required double audioLevel;
|
||||
double totalAudioEnergy;
|
||||
boolean voiceActivityFlag;
|
||||
double echoReturnLoss;
|
||||
double echoReturnLossEnhancement;
|
||||
unsigned long long totalSamplesSent;
|
||||
unsigned long long totalSamplesReceived;
|
||||
double totalSamplesDuration;
|
||||
unsigned long long concealedSamples;
|
||||
unsigned long long concealmentEvents;
|
||||
double jitterBufferDelay;
|
||||
RTCPriorityType priority;
|
||||
DOMString trackIdentifier;
|
||||
boolean remoteSource;
|
||||
boolean ended;
|
||||
boolean detached;
|
||||
DOMString kind;
|
||||
DOMHighResTimeStamp estimatedPlayoutTimestamp;
|
||||
unsigned long frameWidth;
|
||||
unsigned long frameHeight;
|
||||
double framesPerSecond;
|
||||
unsigned long framesCaptured;
|
||||
unsigned long framesSent;
|
||||
unsigned long keyFramesSent;
|
||||
unsigned long framesReceived;
|
||||
unsigned long keyFramesReceived;
|
||||
unsigned long framesDecoded;
|
||||
unsigned long framesDropped;
|
||||
unsigned long framesCorrupted;
|
||||
unsigned long partialFramesLost;
|
||||
unsigned long fullFramesLost;
|
||||
double audioLevel;
|
||||
double totalAudioEnergy;
|
||||
boolean voiceActivityFlag;
|
||||
double echoReturnLoss;
|
||||
double echoReturnLossEnhancement;
|
||||
unsigned long long totalSamplesSent;
|
||||
unsigned long long totalSamplesReceived;
|
||||
double totalSamplesDuration;
|
||||
unsigned long long concealedSamples;
|
||||
unsigned long long concealmentEvents;
|
||||
double jitterBufferDelay;
|
||||
RTCPriorityType priority;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -520,48 +511,50 @@ function validateMediaStreamStats(statsReport, stats) {
|
|||
};
|
||||
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCMediaStreamTrackStats, with attributes trackIdentifier, remoteSource, ended,
|
||||
detached, ssrcIds, frameWidth, frameHeight, framesPerSecond, framesSent,
|
||||
- RTCMediaStreamTrackStats, with attributes trackIdentifier, remoteSource,
|
||||
ended, detached, frameWidth, frameHeight, framesPerSecond, framesSent,
|
||||
framesReceived, framesDecoded, framesDropped, framesCorrupted, audioLevel
|
||||
*/
|
||||
|
||||
function validateMediaStreamTrackStats(stats, stat) {
|
||||
function validateMediaStreamTrackStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
assert_string_field(stat, 'trackIdentifier');
|
||||
assert_boolean_field(stat, 'remoteSource');
|
||||
assert_boolean_field(stat, 'ended');
|
||||
assert_boolean_field(stat, 'detached');
|
||||
assert_string_field(stats, 'trackIdentifier');
|
||||
assert_boolean_field(stats, 'remoteSource');
|
||||
assert_boolean_field(stats, 'ended');
|
||||
assert_boolean_field(stats, 'detached');
|
||||
|
||||
assert_optional_string_field(stat, 'kind');
|
||||
assert_optional_number_field(stat, 'estimatedPlayoutTimestamp');
|
||||
assert_optional_enum_field(stats, 'kind', ['audio', 'video']);
|
||||
assert_optional_number_field(stats, 'estimatedPlayoutTimestamp');
|
||||
|
||||
assert_unsigned_int_field(stat, 'frameWidth');
|
||||
assert_unsigned_int_field(stat, 'frameHeight');
|
||||
assert_number_field(stat, 'framesPerSecond');
|
||||
assert_unsigned_int_field(stats, 'frameWidth');
|
||||
assert_unsigned_int_field(stats, 'frameHeight');
|
||||
assert_number_field(stats, 'framesPerSecond');
|
||||
|
||||
assert_optional_unsigned_int_field(stat, 'framesCaptured');
|
||||
assert_unsigned_int_field(stat, 'frameSent');
|
||||
assert_unsigned_int_field(stat, 'frameReceived');
|
||||
assert_unsigned_int_field(stat, 'frameDecoded');
|
||||
assert_unsigned_int_field(stat, 'frameDropped');
|
||||
assert_unsigned_int_field(stat, 'frameCorrupted');
|
||||
assert_optional_unsigned_int_field(stats, 'framesCaptured');
|
||||
assert_unsigned_int_field(stats, 'framesSent');
|
||||
assert_optional_unsigned_int_field(stats, 'keyFramesSent');
|
||||
assert_unsigned_int_field(stats, 'framesReceived');
|
||||
assert_optional_unsigned_int_field(stats, 'keyFramesReceived');
|
||||
assert_unsigned_int_field(stats, 'framesDecoded');
|
||||
assert_unsigned_int_field(stats, 'framesDropped');
|
||||
assert_unsigned_int_field(stats, 'framesCorrupted');
|
||||
|
||||
assert_optional_unsigned_int_field(stat, 'partialFramesLost');
|
||||
assert_optional_unsigned_int_field(stat, 'fullFramesLost');
|
||||
assert_optional_unsigned_int_field(stats, 'partialFramesLost');
|
||||
assert_optional_unsigned_int_field(stats, 'fullFramesLost');
|
||||
|
||||
assert_number_field(stat, 'audioLevel');
|
||||
assert_optional_number_field(stat, 'totalAudioEnergy');
|
||||
assert_optional_boolean_field(stat, 'voiceActivityFlag');
|
||||
assert_optional_number_field(stat, 'echoReturnLoss');
|
||||
assert_optional_number_field(stat, 'echoReturnLossEnhancement');
|
||||
assert_number_field(stats, 'audioLevel');
|
||||
assert_optional_number_field(stats, 'totalAudioEnergy');
|
||||
assert_optional_boolean_field(stats, 'voiceActivityFlag');
|
||||
assert_optional_number_field(stats, 'echoReturnLoss');
|
||||
assert_optional_number_field(stats, 'echoReturnLossEnhancement');
|
||||
|
||||
assert_optional_unsigned_int_field(stat, 'totalSamplesSent');
|
||||
assert_optional_unsigned_int_field(stat, 'totalSamplesReceived');
|
||||
assert_optional_number_field(stat, 'totalSamplesDuration');
|
||||
assert_optional_unsigned_int_field(stat, 'concealedSamples');
|
||||
assert_optional_unsigned_int_field(stat, 'concealmentEvents');
|
||||
assert_optional_number_field(stat, 'jitterBufferDelay');
|
||||
assert_optional_unsigned_int_field(stats, 'totalSamplesSent');
|
||||
assert_optional_unsigned_int_field(stats, 'totalSamplesReceived');
|
||||
assert_optional_number_field(stats, 'totalSamplesDuration');
|
||||
assert_optional_unsigned_int_field(stats, 'concealedSamples');
|
||||
assert_optional_unsigned_int_field(stats, 'concealmentEvents');
|
||||
assert_optional_number_field(stats, 'jitterBufferDelay');
|
||||
|
||||
assert_optional_enum_field(stats, 'priority',
|
||||
['very-low', 'low', 'medium', 'high']);
|
||||
|
@ -571,18 +564,15 @@ function validateMediaStreamTrackStats(stats, stat) {
|
|||
[webrtc-stats]
|
||||
7.13. RTCDataChannelStats dictionary
|
||||
dictionary RTCDataChannelStats : RTCStats {
|
||||
required DOMString label;
|
||||
required DOMString protocol;
|
||||
required long datachannelid;
|
||||
|
||||
[RTCTransportStats]
|
||||
DOMString transportId;
|
||||
|
||||
required RTCDataChannelState state;
|
||||
required unsigned long messagesSent;
|
||||
required unsigned long long bytesSent;
|
||||
required unsigned long messagesReceived;
|
||||
required unsigned long long bytesReceived;
|
||||
DOMString label;
|
||||
DOMString protocol;
|
||||
long dataChannelIdentifier;
|
||||
DOMString transportId;
|
||||
RTCDataChannelState state;
|
||||
unsigned long messagesSent;
|
||||
unsigned long long bytesSent;
|
||||
unsigned long messagesReceived;
|
||||
unsigned long long bytesReceived;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -598,22 +588,19 @@ function validateMediaStreamTrackStats(stats, stat) {
|
|||
- RTCDataChannelStats, with attributes label, protocol, datachannelId, state,
|
||||
messagesSent, bytesSent, messagesReceived, bytesReceived
|
||||
*/
|
||||
|
||||
function validateDataChannelStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
assert_string_field(stats, 'label');
|
||||
assert_string_field(stats, 'protocol');
|
||||
assert_int_field(stats, 'datachannelid');
|
||||
assert_int_field(stats, 'dataChannelIdentifier');
|
||||
|
||||
validateOptionalIdField(statsReport, stats, 'transportId', 'transport');
|
||||
|
||||
assert_enum_field(stats, 'state',
|
||||
['connecting', 'open', 'closing', 'closed']);
|
||||
|
||||
assert_unsigned_int_field(stats, 'messageSent');
|
||||
|
||||
assert_unsigned_int_field(stats, 'messageSent');
|
||||
assert_unsigned_int_field(stats, 'messagesSent');
|
||||
assert_unsigned_int_field(stats, 'bytesSent');
|
||||
assert_unsigned_int_field(stats, 'messagesReceived');
|
||||
assert_unsigned_int_field(stats, 'bytesReceived');
|
||||
|
@ -623,25 +610,16 @@ function validateDataChannelStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.14. RTCTransportStats dictionary
|
||||
dictionary RTCTransportStats : RTCStats {
|
||||
unsigned long packetsSent;
|
||||
unsigned long packetsReceived;
|
||||
required unsigned long long bytesSent;
|
||||
required unsigned long long bytesReceived;
|
||||
|
||||
[RTCTransportStats]
|
||||
required DOMString rtcpTransportStatsId;
|
||||
|
||||
RTCIceRole iceRole;
|
||||
RTCDtlsTransportState dtlsState;
|
||||
|
||||
[RTCIceCandidatePairStats]
|
||||
required DOMString selectedCandidatePairId;
|
||||
|
||||
[RTCCertificateStats]
|
||||
required DOMString localCertificateId;
|
||||
|
||||
[RTCCertificateStats]
|
||||
required DOMString remoteCertificateId;
|
||||
unsigned long packetsSent;
|
||||
unsigned long packetsReceived;
|
||||
unsigned long long bytesSent;
|
||||
unsigned long long bytesReceived;
|
||||
DOMString rtcpTransportStatsId;
|
||||
RTCIceRole iceRole;
|
||||
RTCDtlsTransportState dtlsState;
|
||||
DOMString selectedCandidatePairId;
|
||||
DOMString localCertificateId;
|
||||
DOMString remoteCertificateId;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -661,10 +639,10 @@ function validateDataChannelStats(statsReport, stats) {
|
|||
};
|
||||
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCTransportStats, with attributes bytesSent, bytesReceived, rtcpTransportStatsId,
|
||||
activeConnection, selectedCandidatePairId, localCertificateId, remoteCertificateId
|
||||
- RTCTransportStats, with attributes bytesSent, bytesReceived,
|
||||
rtcpTransportStatsId, selectedCandidatePairId, localCertificateId,
|
||||
remoteCertificateId
|
||||
*/
|
||||
|
||||
function validateTransportStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
|
@ -682,26 +660,35 @@ function validateTransportStats(statsReport, stats) {
|
|||
['new', 'connecting', 'connected', 'closed', 'failed']);
|
||||
|
||||
validateIdField(statsReport, stats, 'selectedCandidatePairId', 'candidate-pair');
|
||||
validateIdField(stateReport, stats, 'localCertificateId', 'certificate');
|
||||
validateIdField(stateReport, stats, 'remoteCertificateId', 'certificate');
|
||||
validateIdField(statsReport, stats, 'localCertificateId', 'certificate');
|
||||
validateIdField(statsReport, stats, 'remoteCertificateId', 'certificate');
|
||||
}
|
||||
|
||||
/*
|
||||
[webrtc-stats]
|
||||
7.15. RTCIceCandidateStats dictionary
|
||||
dictionary RTCIceCandidateStats : RTCStats {
|
||||
[RTCTransportStats]
|
||||
DOMString transportId;
|
||||
DOMString transportId;
|
||||
boolean isRemote;
|
||||
RTCNetworkType networkType;
|
||||
DOMString ip;
|
||||
long port;
|
||||
DOMString protocol;
|
||||
RTCIceCandidateType candidateType;
|
||||
long priority;
|
||||
DOMString url;
|
||||
DOMString relayProtocol;
|
||||
boolean deleted = false;
|
||||
};
|
||||
|
||||
boolean isRemote;
|
||||
required DOMString ip;
|
||||
required long port;
|
||||
required DOMString protocol;
|
||||
required RTCIceCandidateType candidateType;
|
||||
required long priority;
|
||||
required DOMString url;
|
||||
DOMString relayProtocol;
|
||||
boolean deleted = false;
|
||||
enum RTCNetworkType {
|
||||
"bluetooth",
|
||||
"cellular",
|
||||
"ethernet",
|
||||
"wifi",
|
||||
"wimax",
|
||||
"vpn",
|
||||
"unknown"
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -714,16 +701,18 @@ function validateTransportStats(statsReport, stats) {
|
|||
};
|
||||
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCIceCandidateStats, with attributes ip, port, protocol, candidateType, priority,
|
||||
url
|
||||
- RTCIceCandidateStats, with attributes ip, port, protocol, candidateType,
|
||||
priority, url
|
||||
*/
|
||||
|
||||
function validateIceCandidateStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
validateOptionalIdField(statsReport, stats, 'transportId', 'transport');
|
||||
assert_optional_boolean_field(stats, 'isRemote');
|
||||
|
||||
assert_optional_enum_field(stats, 'networkType',
|
||||
['bluetooth', 'cellular', 'ethernet', 'wifi', 'wimax', 'vpn', 'unknown'])
|
||||
|
||||
assert_string_field(stats, 'ip');
|
||||
assert_int_field(stats, 'port');
|
||||
assert_string_field(stats, 'protocol');
|
||||
|
@ -741,40 +730,34 @@ function validateIceCandidateStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.16. RTCIceCandidatePairStats dictionary
|
||||
dictionary RTCIceCandidatePairStats : RTCStats {
|
||||
[RTCTransportStats]
|
||||
required DOMString transportId;
|
||||
|
||||
[RTCIceCandidateStats]
|
||||
required DOMString localCandidateId;
|
||||
|
||||
[RTCIceCandidateStats]
|
||||
required DOMString remoteCandidateId;
|
||||
|
||||
required RTCStatsIceCandidatePairState state;
|
||||
required unsigned long long priority;
|
||||
required boolean nominated;
|
||||
unsigned long packetsSent;
|
||||
unsigned long packetsReceived;
|
||||
required unsigned long long bytesSent;
|
||||
required unsigned long long bytesReceived;
|
||||
DOMHighResTimeStamp lastPacketSentTimestamp;
|
||||
DOMHighResTimeStamp lastPacketReceivedTimestamp;
|
||||
DOMHighResTimeStamp firstRequestTimestamp;
|
||||
DOMHighResTimeStamp lastRequestTimestamp;
|
||||
DOMHighResTimeStamp lastResponseTimestamp;
|
||||
required double totalRoundTripTime;
|
||||
required double currentRoundTripTime;
|
||||
double availableOutgoingBitrate;
|
||||
double availableIncomingBitrate;
|
||||
unsigned long circuitBreakerTriggerCount;
|
||||
unsigned long long requestsReceived;
|
||||
unsigned long long requestsSent;
|
||||
unsigned long long responsesReceived;
|
||||
unsigned long long responsesSent;
|
||||
unsigned long long retransmissionsReceived;
|
||||
unsigned long long retransmissionsSent;
|
||||
unsigned long long consentRequestsSent;
|
||||
DOMHighResTimeStamp consentExpiredTimestamp;
|
||||
DOMString transportId;
|
||||
DOMString localCandidateId;
|
||||
DOMString remoteCandidateId;
|
||||
RTCStatsIceCandidatePairState state;
|
||||
unsigned long long priority;
|
||||
boolean nominated;
|
||||
unsigned long packetsSent;
|
||||
unsigned long packetsReceived;
|
||||
unsigned long long bytesSent;
|
||||
unsigned long long bytesReceived;
|
||||
DOMHighResTimeStamp lastPacketSentTimestamp;
|
||||
DOMHighResTimeStamp lastPacketReceivedTimestamp;
|
||||
DOMHighResTimeStamp firstRequestTimestamp;
|
||||
DOMHighResTimeStamp lastRequestTimestamp;
|
||||
DOMHighResTimeStamp lastResponseTimestamp;
|
||||
double totalRoundTripTime;
|
||||
double currentRoundTripTime;
|
||||
double availableOutgoingBitrate;
|
||||
double availableIncomingBitrate;
|
||||
unsigned long circuitBreakerTriggerCount;
|
||||
unsigned long long requestsReceived;
|
||||
unsigned long long requestsSent;
|
||||
unsigned long long responsesReceived;
|
||||
unsigned long long responsesSent;
|
||||
unsigned long long retransmissionsReceived;
|
||||
unsigned long long retransmissionsSent;
|
||||
unsigned long long consentRequestsSent;
|
||||
DOMHighResTimeStamp consentExpiredTimestamp;
|
||||
};
|
||||
|
||||
enum RTCStatsIceCandidatePairState {
|
||||
|
@ -788,8 +771,7 @@ function validateIceCandidateStats(statsReport, stats) {
|
|||
[webrtc-pc]
|
||||
8.6. Mandatory To Implement Stats
|
||||
- RTCIceCandidatePairStats, with attributes transportId, localCandidateId,
|
||||
remoteCandidateId, state, priority, nominated, writable, readable, bytesSent,
|
||||
bytesReceived, totalRtt, currentRtt
|
||||
remoteCandidateId, state, priority, nominated, bytesSent, bytesReceived, totalRoundTripTime, currentRoundTripTime
|
||||
*/
|
||||
function validateIceCandidatePairStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
@ -835,10 +817,10 @@ function validateIceCandidatePairStats(statsReport, stats) {
|
|||
[webrtc-stats]
|
||||
7.17. RTCCertificateStats dictionary
|
||||
dictionary RTCCertificateStats : RTCStats {
|
||||
required DOMString fingerprint;
|
||||
required DOMString fingerprintAlgorithm;
|
||||
required DOMString base64Certificate;
|
||||
required DOMString issuerCertificateId;
|
||||
DOMString fingerprint;
|
||||
DOMString fingerprintAlgorithm;
|
||||
DOMString base64Certificate;
|
||||
DOMString issuerCertificateId;
|
||||
};
|
||||
|
||||
[webrtc-pc]
|
||||
|
@ -846,7 +828,6 @@ function validateIceCandidatePairStats(statsReport, stats) {
|
|||
- RTCCertificateStats, with attributes fingerprint, fingerprintAlgorithm,
|
||||
base64Certificate, issuerCertificateId
|
||||
*/
|
||||
|
||||
function validateCertificateStats(statsReport, stats) {
|
||||
validateRtcStats(statsReport, stats);
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
assert_equals(trackEvent.receiver, receiver);
|
||||
assert_equals(trackEvent.track, track);
|
||||
assert_array_equals(trackEvent.streams, []);
|
||||
assert_equals(trackEvent.streams, trackEvent.streams); // [SameObject]
|
||||
assert_equals(trackEvent.transceiver, transceiver);
|
||||
|
||||
assert_equals(trackEvent.type, 'track');
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<!doctype html>
|
||||
<!--
|
||||
This test creates a data channel object and compares it with the WebIDL defined interface
|
||||
-->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>RTCPeerConnection Data Channel Empty String Test</title>
|
||||
<link rel="author" title="Dominique Hazael-Massieux" href="mailto:dom@w3.org"/>
|
||||
<link rel="help" href="http://w3c.github.io/webrtc-pc/#rtcdatachannel">
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<!-- These files are in place when executing on W3C. -->
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src=/resources/WebIDLParser.js></script>
|
||||
<script src=/resources/idlharness.js></script>
|
||||
<!-- The IDL is copied from https://w3c.github.io/webrtc-pc/archives/20161219/webrtc.html -->
|
||||
<script type="text/plain">
|
||||
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;
|
||||
readonly attribute unsigned long bufferedAmount;
|
||||
attribute unsigned long bufferedAmountLowThreshold;
|
||||
attribute EventHandler onopen;
|
||||
attribute EventHandler onbufferedamountlow;
|
||||
attribute EventHandler onerror;
|
||||
attribute EventHandler onclose;
|
||||
void close();
|
||||
attribute EventHandler onmessage;
|
||||
attribute DOMString binaryType;
|
||||
void send(USVString data);
|
||||
void send(Blob data);
|
||||
void send(ArrayBuffer data);
|
||||
void send(ArrayBufferView data);
|
||||
};
|
||||
enum RTCPriorityType {
|
||||
"very-low",
|
||||
"low",
|
||||
"medium",
|
||||
"high"
|
||||
};
|
||||
enum RTCDataChannelState {
|
||||
"connecting",
|
||||
"open",
|
||||
"closing",
|
||||
"closed"
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var idl_array = new IdlArray();
|
||||
[].forEach.call(document.querySelectorAll("script[type=text\\/plain]"),
|
||||
function(node) {
|
||||
idl_array.add_idls(node.textContent);
|
||||
});
|
||||
pc = new RTCPeerConnection(null);
|
||||
window.channel = pc.createDataChannel("test");
|
||||
idl_array.add_objects({"RTCDataChannel": ["channel"]});
|
||||
idl_array.test();
|
||||
done();
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
156
tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js
Normal file
156
tests/wpt/web-platform-tests/webrtc/tools/.eslintrc.js
Normal file
|
@ -0,0 +1,156 @@
|
|||
module.exports = {
|
||||
rules: {
|
||||
'no-undef': 1,
|
||||
'no-unused-vars': 0
|
||||
},
|
||||
plugins: [
|
||||
'html'
|
||||
],
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true
|
||||
},
|
||||
globals: {
|
||||
// testharness globals
|
||||
test: true,
|
||||
async_test: true,
|
||||
promise_test: true,
|
||||
promise_rejects: true,
|
||||
IdlArray: true,
|
||||
assert_true: true,
|
||||
assert_false: true,
|
||||
assert_equals: true,
|
||||
assert_not_equals: true,
|
||||
assert_array_equals: true,
|
||||
assert_in_array: true,
|
||||
assert_unreached: true,
|
||||
assert_throws: true,
|
||||
assert_idl_attribute: true,
|
||||
assert_exists: true,
|
||||
assert_greater_than: true,
|
||||
assert_less_than: true,
|
||||
assert_greater_than_equal: true,
|
||||
assert_less_than_equal: true,
|
||||
assert_approx_equals: true,
|
||||
|
||||
|
||||
// WebRTC globals
|
||||
RTCPeerConnection: true,
|
||||
RTCRtpSender: true,
|
||||
RTCRtpReceiver: true,
|
||||
RTCRtpTransceiver: true,
|
||||
RTCIceTransport: true,
|
||||
RTCDtlsTransport: true,
|
||||
RTCSctpTransport: true,
|
||||
RTCDataChannel: true,
|
||||
RTCCertificate: true,
|
||||
RTCDTMFSender: true,
|
||||
RTCError: true,
|
||||
RTCTrackEvent: true,
|
||||
RTCPeerConnectionIceEvent: true,
|
||||
RTCDTMFToneChangeEvent: true,
|
||||
RTCDataChannelEvent: true,
|
||||
RTCRtpContributingSource: true,
|
||||
RTCRtpSynchronizationSource: true,
|
||||
|
||||
// dictionary-helper.js
|
||||
assert_unsigned_int_field: true,
|
||||
assert_int_field: true,
|
||||
assert_string_field: true,
|
||||
assert_number_field: true,
|
||||
assert_boolean_field: true,
|
||||
assert_array_field: true,
|
||||
assert_dict_field: true,
|
||||
assert_enum_field: true,
|
||||
|
||||
assert_optional_unsigned_int_field: true,
|
||||
assert_optional_int_field: true,
|
||||
assert_optional_string_field: true,
|
||||
assert_optional_number_field: true,
|
||||
assert_optional_boolean_field: true,
|
||||
assert_optional_array_field: true,
|
||||
assert_optional_dict_field: true,
|
||||
assert_optional_enum_field: true,
|
||||
|
||||
// identity-helper.js
|
||||
parseAssertionResult: true,
|
||||
getIdpDomains: true,
|
||||
assert_rtcerror_rejection: true,
|
||||
hostString: true,
|
||||
|
||||
// RTCConfiguration-helper.js
|
||||
config_test: true,
|
||||
|
||||
// RTCDTMFSender-helper.js
|
||||
createDtmfSender: true,
|
||||
test_tone_change_events: true,
|
||||
getTransceiver: true,
|
||||
|
||||
// RTCPeerConnection-helper.js
|
||||
countLine: true,
|
||||
countAudioLine: true,
|
||||
countVideoLine: true,
|
||||
countApplicationLine: true,
|
||||
similarMediaDescriptions: true,
|
||||
assert_is_session_description: true,
|
||||
isSimilarSessionDescription: true,
|
||||
assert_session_desc_equals: true,
|
||||
assert_session_desc_not_equals: true,
|
||||
generateOffer: true,
|
||||
generateAnswer: true,
|
||||
test_state_change_event: true,
|
||||
test_never_resolve: true,
|
||||
exchangeIceCandidates: true,
|
||||
doSignalingHandshake: true,
|
||||
createDataChannelPair: true,
|
||||
awaitMessage: true,
|
||||
blobToArrayBuffer: true,
|
||||
assert_equals_array_buffer: true,
|
||||
generateMediaStreamTrack: true,
|
||||
getTrackFromUserMedia: true,
|
||||
getUserMediaTracksAndStreams: true,
|
||||
performOffer: true,
|
||||
Resolver: true,
|
||||
|
||||
// RTCRtpCapabilities-helper.js
|
||||
validateRtpCapabilities: true,
|
||||
validateCodecCapability: true,
|
||||
validateHeaderExtensionCapability: true,
|
||||
|
||||
// RTCRtpParameters-helper.js
|
||||
validateSenderRtpParameters: true,
|
||||
validateReceiverRtpParameters: true,
|
||||
validateRtpParameters: true,
|
||||
validateEncodingParameters: true,
|
||||
validateRtcpParameters: true,
|
||||
validateHeaderExtensionParameters: true,
|
||||
validateCodecParameters: true,
|
||||
|
||||
// RTCStats-helper.js
|
||||
validateStatsReport: true,
|
||||
assert_stats_report_has_stats: true,
|
||||
findStatsFromReport: true,
|
||||
getRequiredStats: true,
|
||||
getStatsById: true,
|
||||
validateIdField: true,
|
||||
validateOptionalIdField: true,
|
||||
validateRtcStats: true,
|
||||
validateRtpStreamStats: true,
|
||||
validateCodecStats: true,
|
||||
validateReceivedRtpStreamStats: true,
|
||||
validateInboundRtpStreamStats: true,
|
||||
validateRemoteInboundRtpStreamStats: true,
|
||||
validateSentRtpStreamStats: true,
|
||||
validateOutboundRtpStreamStats: true,
|
||||
validateRemoteOutboundRtpStreamStats: true,
|
||||
validateContributingSourceStats: true,
|
||||
validatePeerConnectionStats: true,
|
||||
validateMediaStreamStats: true,
|
||||
validateMediaStreamTrackStats: true,
|
||||
validateDataChannelStats: true,
|
||||
validateTransportStats: true,
|
||||
validateIceCandidateStats: true,
|
||||
validateIceCandidatePairStats: true,
|
||||
validateCertificateStats: true,
|
||||
}
|
||||
}
|
14
tests/wpt/web-platform-tests/webrtc/tools/README.md
Normal file
14
tests/wpt/web-platform-tests/webrtc/tools/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
WebRTC Tools
|
||||
============
|
||||
|
||||
This directory contains a simple Node.js project to aid the development of
|
||||
WebRTC tests.
|
||||
|
||||
## Lint
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
Does basic linting of the JavaScript code. Mainly for catching usage of
|
||||
undefined variables.
|
1213
tests/wpt/web-platform-tests/webrtc/tools/package-lock.json
generated
Normal file
1213
tests/wpt/web-platform-tests/webrtc/tools/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
14
tests/wpt/web-platform-tests/webrtc/tools/package.json
Normal file
14
tests/wpt/web-platform-tests/webrtc/tools/package.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "webrtc-testing-tools",
|
||||
"version": "1.0.0",
|
||||
"description": "Tools for WebRTC testing",
|
||||
"scripts": {
|
||||
"lint": "eslint -c .eslintrc.js ../*.html ../*.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^4.11.0",
|
||||
"eslint-plugin-html": "^4.0.0"
|
||||
},
|
||||
"license": "BSD",
|
||||
"private": true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue