mirror of
https://github.com/servo/servo.git
synced 2025-08-11 16:35:33 +01:00
Update web-platform-tests to revision 2d42384cf21efd71843295d319c1bab85b3acf4a
This commit is contained in:
parent
f2b224d610
commit
e851ef0cd2
1014 changed files with 5653 additions and 1590 deletions
|
@ -1,79 +1,111 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<!-- This file contains two tests that wait for 10 seconds each. -->
|
||||
<meta name="timeout" content="long">
|
||||
<title>RTCRtpReceiver.prototype.getSynchronizationSources</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="RTCPeerConnection-helper.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
// Test is based on the following editor draft:
|
||||
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
|
||||
async function initiateSingleTrackCallAndReturnReceiver(t, kind) {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
/*
|
||||
5.3. RTCRtpReceiver Interface
|
||||
interface RTCRtpReceiver {
|
||||
...
|
||||
sequence<RTCRtpSynchronizationSource> getSynchronizationSources();
|
||||
};
|
||||
const stream = await navigator.mediaDevices.getUserMedia({[kind]:true});
|
||||
const [track] = stream.getTracks();
|
||||
t.add_cleanup(() => track.stop());
|
||||
pc1.addTrack(track, stream);
|
||||
|
||||
interface RTCRtpSynchronizationSource {
|
||||
readonly attribute DOMHighResTimeStamp timestamp;
|
||||
readonly attribute unsigned long source;
|
||||
readonly attribute byte audioLevel;
|
||||
readonly attribute boolean? voiceActivityFlag;
|
||||
};
|
||||
*/
|
||||
exchangeIceCandidates(pc1, pc2);
|
||||
const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2);
|
||||
await exchangeAnswer(pc1, pc2);
|
||||
return trackEvent.receiver;
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
const pc2 = new RTCPeerConnection();
|
||||
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
const ontrackPromise = new Promise(resolve => {
|
||||
pc2.addEventListener('track', trackEvent => {
|
||||
const { receiver } = trackEvent;
|
||||
assert_true(receiver instanceof RTCRtpReceiver,
|
||||
'Expect trackEvent.receiver to be instance of RTCRtpReceiver');
|
||||
|
||||
resolve(receiver);
|
||||
});
|
||||
});
|
||||
|
||||
return getTrackFromUserMedia('audio')
|
||||
.then(([track, mediaStream]) => {
|
||||
pc1.addTrack(track, mediaStream);
|
||||
exchangeIceCandidates(pc1, pc2);
|
||||
return doSignalingHandshake(pc1, pc2);
|
||||
})
|
||||
.then(() => ontrackPromise)
|
||||
.then(receiver => {
|
||||
const syncSources = receiver.getSynchronizationSources();
|
||||
assert_greater_than(syncSources.length, 0,
|
||||
'Expect SSRCs to be available after RTP connection is established');
|
||||
|
||||
for(const ssrc of syncSources) {
|
||||
assert_true(ssrc instanceof RTCRtpSynchronizationSource,
|
||||
'Expect synchronizationSources elements to be instance of RTCSynchronizationSource');
|
||||
|
||||
assert_equals(typeof ssrc.timestamp, 'number',
|
||||
'Expect ssrc.timestamp attribute to be DOMHighResTimeStamp');
|
||||
|
||||
assert_true(Number.isInteger(ssrc.source) && ssrc.source > 0,
|
||||
'Expect SSRC identifier to be unsigned long');
|
||||
|
||||
assert_true(Number.isInteger(ssrc.audioLevel) &&
|
||||
ssrc.audioLevel >= 0 && ssrc.audioLevel <= 127,
|
||||
'Expect ssrc.audioLevel to be byte value from 0-127.');
|
||||
|
||||
if(ssrc.voiceActivityFlag !== null) {
|
||||
assert_equals(typeof ssrc.voiceActivityFlag, 'boolean',
|
||||
'Expect ssrc.voiceActivity to be either null or boolean');
|
||||
}
|
||||
function listenForSSRCs(t, receiver) {
|
||||
return new Promise((resolve) => {
|
||||
function listen() {
|
||||
const ssrcs = receiver.getSynchronizationSources();
|
||||
assert_true(ssrcs != undefined);
|
||||
if (ssrcs.length > 0) {
|
||||
resolve(ssrcs);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}, `getContributingSources() should return list of CSRC after connection is established`);
|
||||
t.step_timeout(listen, 0);
|
||||
};
|
||||
listen();
|
||||
});
|
||||
}
|
||||
|
||||
for (const kind of ['audio', 'video']) {
|
||||
promise_test(async t => {
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
|
||||
await listenForSSRCs(t, receiver);
|
||||
}, '[' + kind + '] getSynchronizationSources() eventually returns a ' +
|
||||
'non-empty list');
|
||||
|
||||
promise_test(async t => {
|
||||
const startTime = performance.now();
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
|
||||
const [ssrc] = await listenForSSRCs(t, receiver);
|
||||
assert_equals(typeof ssrc.timestamp, 'number');
|
||||
assert_true(ssrc.timestamp >= startTime);
|
||||
}, '[' + kind + '] RTCRtpSynchronizationSource.timestamp is a number');
|
||||
|
||||
promise_test(async t => {
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
|
||||
// Wait for packets to start flowing.
|
||||
await listenForSSRCs(t, receiver);
|
||||
// Wait for 10 seconds.
|
||||
await new Promise(resolve => t.step_timeout(resolve, 10000));
|
||||
let earliestTimestamp = undefined;
|
||||
let latestTimestamp = undefined;
|
||||
for (const ssrc of await listenForSSRCs(t, receiver)) {
|
||||
if (earliestTimestamp == undefined || earliestTimestamp > ssrc.timestamp)
|
||||
earliestTimestamp = ssrc.timestamp;
|
||||
if (latestTimestamp == undefined || latestTimestamp < ssrc.timestamp)
|
||||
latestTimestamp = ssrc.timestamp;
|
||||
}
|
||||
assert_true(latestTimestamp - earliestTimestamp <= 10000);
|
||||
}, '[' + kind + '] getSynchronizationSources() does not contain SSRCs ' +
|
||||
'older than 10 seconds');
|
||||
|
||||
promise_test(async t => {
|
||||
const startTime = performance.timeOrigin + performance.now();
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
|
||||
const [ssrc] = await listenForSSRCs(t, receiver);
|
||||
const endTime = performance.timeOrigin + performance.now();
|
||||
assert_true(startTime <= ssrc.timestamp && ssrc.timestamp <= endTime);
|
||||
}, '[' + kind + '] RTCRtpSynchronizationSource.timestamp is comparable to ' +
|
||||
'performance.timeOrigin + performance.now()');
|
||||
|
||||
promise_test(async t => {
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
|
||||
const [ssrc] = await listenForSSRCs(t, receiver);
|
||||
assert_equals(typeof ssrc.source, 'number');
|
||||
}, '[' + kind + '] RTCRtpSynchronizationSource.source is a number');
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, 'audio');
|
||||
const [ssrc] = await listenForSSRCs(t, receiver);
|
||||
assert_equals(typeof ssrc.audioLevel, 'number');
|
||||
assert_greater_than_equal(ssrc.audioLevel, 0);
|
||||
assert_less_than_equal(ssrc.audioLevel, 1);
|
||||
}, '[audio-only] RTCRtpSynchronizationSource.audioLevel is a number [0, 1]');
|
||||
|
||||
// This test only passes if the implementation is sending the RFC 6464 extension
|
||||
// header and the "vad" extension attribute is not "off", otherwise
|
||||
// voiceActivityFlag is absent. TODO: Consider moving this test to an
|
||||
// optional-to-implement subfolder?
|
||||
promise_test(async t => {
|
||||
const receiver = await initiateSingleTrackCallAndReturnReceiver(t, 'audio');
|
||||
const [ssrc] = await listenForSSRCs(t, receiver);
|
||||
assert_equals(typeof ssrc.voiceActivityFlag, 'boolean');
|
||||
}, '[audio-only] RTCRtpSynchronizationSource.voiceActivityFlag is a boolean');
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue