Update web-platform-tests to revision 064f51c50eab34723ef435e80188bde08f718c2c

This commit is contained in:
WPT Sync Bot 2018-11-04 20:45:21 -05:00
parent 348f5520ee
commit 3c4e5d8f18
44 changed files with 769 additions and 789 deletions

View file

@ -317494,6 +317494,11 @@
{}
]
],
"webrtc/legacy/README.txt": [
[
{}
]
],
"webrtc/protocol/README.txt": [
[
{}
@ -339351,6 +339356,12 @@
{}
]
],
"css/css-position/inheritance.html": [
[
"/css/css-position/inheritance.html",
{}
]
],
"css/css-position/position-sticky-bottom.html": [
[
"/css/css-position/position-sticky-bottom.html",
@ -376505,6 +376516,12 @@
{}
]
],
"mediacapture-record/MediaRecorder-error.html": [
[
"/mediacapture-record/MediaRecorder-error.html",
{}
]
],
"mediacapture-record/MediaRecorder-stop.html": [
[
"/mediacapture-record/MediaRecorder-stop.html",
@ -408711,6 +408728,12 @@
{}
]
],
"webrtc-identity/RTCPeerConnection-constructor.html": [
[
"/webrtc-identity/RTCPeerConnection-constructor.html",
{}
]
],
"webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html": [
[
"/webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html",
@ -408893,12 +408916,6 @@
{}
]
],
"webrtc/RTCPeerConnection-createOffer-offerToReceive.html": [
[
"/webrtc/RTCPeerConnection-createOffer-offerToReceive.html",
{}
]
],
"webrtc/RTCPeerConnection-createOffer.html": [
[
"/webrtc/RTCPeerConnection-createOffer.html",
@ -409229,6 +409246,24 @@
{}
]
],
"webrtc/legacy/RTCPeerConnection-createOffer-offerToReceive.html": [
[
"/webrtc/legacy/RTCPeerConnection-createOffer-offerToReceive.html",
{}
]
],
"webrtc/legacy/RTCRtpTransceiver-with-OfferToReceive-options.https.html": [
[
"/webrtc/legacy/RTCRtpTransceiver-with-OfferToReceive-options.https.html",
{}
]
],
"webrtc/legacy/onaddstream.https.html": [
[
"/webrtc/legacy/onaddstream.https.html",
{}
]
],
"webrtc/no-media-call.html": [
[
"/webrtc/no-media-call.html",
@ -409241,6 +409276,12 @@
{}
]
],
"webrtc/protocol/jsep-initial-offer.https.html": [
[
"/webrtc/protocol/jsep-initial-offer.https.html",
{}
]
],
"webrtc/protocol/video-codecs.https.html": [
[
"/webrtc/protocol/video-codecs.https.html",
@ -556512,6 +556553,10 @@
"9ccb822f107f429651c7949995412c9f2a80feea",
"reftest"
],
"css/css-position/inheritance.html": [
"d75b28c1e0aa2698fe0c73965f4e7d1f06b16547",
"testharness"
],
"css/css-position/position-relative-table-left-ref.html": [
"7c1193b80007d8e7f89b35400a6d2ea2266cb3ac",
"support"
@ -627392,6 +627437,10 @@
"1710d238b6e31d285766f25f4625d206d1d8a1fc",
"testharness"
],
"mediacapture-record/MediaRecorder-error.html": [
"2459449acf931cd38301fca11e7b15326afac040",
"testharness"
],
"mediacapture-record/MediaRecorder-stop.html": [
"8e05fc5491d8da7aaddefea20fae36d705c75bce",
"testharness"
@ -669212,6 +669261,10 @@
"900769b9d4334bb38d6413beea6a28235d8c927c",
"support"
],
"webrtc-identity/RTCPeerConnection-constructor.html": [
"8498e6b35c9ff820c86773dd874930c5b012229e",
"testharness"
],
"webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html": [
"2bd860d901ded78c9635da65413ac63e7dbf4460",
"testharness"
@ -669333,7 +669386,7 @@
"testharness"
],
"webrtc/RTCPeerConnection-addTrack.https.html": [
"2ec9a1f7d60d84fce6e5a8b240b0fadc3b1d910f",
"1550fc4f7943b79cc331d5c93ca6d5643793dead",
"testharness"
],
"webrtc/RTCPeerConnection-addTransceiver.https.html": [
@ -669349,23 +669402,19 @@
"testharness"
],
"webrtc/RTCPeerConnection-constructor.html": [
"e00d98709087eea37599e5c7d520b04cbb6e1e8f",
"abea2eb6761b779ba527b75660d0c2258c805ba1",
"testharness"
],
"webrtc/RTCPeerConnection-createAnswer.html": [
"abff1eb7329cceda286216b90531f997040ed474",
"030ced8c98f4c926c5af870bf16097f4f56a7d1e",
"testharness"
],
"webrtc/RTCPeerConnection-createDataChannel.html": [
"450a25002ed2212e7f1dd5cb97ff985e3f957aa1",
"testharness"
],
"webrtc/RTCPeerConnection-createOffer-offerToReceive.html": [
"dd1827a1c8d60abe67cad72a9ef3280003c792c0",
"testharness"
],
"webrtc/RTCPeerConnection-createOffer.html": [
"2fa3a05f60a1a53668e9978009958a19c57e4fc1",
"c56d45280ef6317bc0ef77b8ad71e9273c809863",
"testharness"
],
"webrtc/RTCPeerConnection-generateCertificate.html": [
@ -669385,7 +669434,7 @@
"testharness"
],
"webrtc/RTCPeerConnection-helper.js": [
"330ce1992d97a5d3fc825f882fcdaa3f1f4a95bf",
"8529fb4ef3cdf509a519608fbb4a5919c44f3e37",
"support"
],
"webrtc/RTCPeerConnection-iceConnectionState.html": [
@ -669421,15 +669470,15 @@
"testharness"
],
"webrtc/RTCPeerConnection-setLocalDescription-answer.html": [
"4a50456f21613a39946c54774377aef176c04486",
"b783d854738a926cfdf0ecc7ecd7897b5b86b200",
"testharness"
],
"webrtc/RTCPeerConnection-setLocalDescription-offer.html": [
"9502f283f55081300f80a0f06650f28eb46ce506",
"49eb522881a9abb914566b42a5e7aae7063fdb8b",
"testharness"
],
"webrtc/RTCPeerConnection-setLocalDescription-pranswer.html": [
"a145f95afa3521d6ec8446e12da41d19d338b9a7",
"1fbb30923f3d1e9abef6940a931a6d426ed01915",
"testharness"
],
"webrtc/RTCPeerConnection-setLocalDescription-rollback.html": [
@ -669437,11 +669486,11 @@
"testharness"
],
"webrtc/RTCPeerConnection-setLocalDescription.html": [
"0ab2db1d56d4163aa088776c51d652cedece15a7",
"1030f494f2469c2fceaa618e2992397b5a4bbb8f",
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-answer.html": [
"ff554478af833a2a9b56a7a863d37a0255bca7b6",
"cc5bd1e0807b71e0e96c368fe18ab6bd0c6d142d",
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-offer.html": [
@ -669449,7 +669498,7 @@
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html": [
"9197a359671bd1d8f28098b2a8db1b93ee181cee",
"c27ee20855bea03e4aa8a2ca80b90653f5e9d5b5",
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-replaceTrack.https.html": [
@ -669457,7 +669506,7 @@
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-rollback.html": [
"01969dce310c78561d97f22a0cc6da9390bf0c27",
"ec90e561cbcf76559356dcd46c77547fb8262dcb",
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription-tracks.https.html": [
@ -669465,7 +669514,7 @@
"testharness"
],
"webrtc/RTCPeerConnection-setRemoteDescription.html": [
"ad9cdff5fb0a4cf90e977fd0cdde7d3d685e9f4d",
"182abea403ed7bee6568aac402cbb6a8caac6159",
"testharness"
],
"webrtc/RTCPeerConnection-track-stats.https.html": [
@ -669533,11 +669582,11 @@
"testharness"
],
"webrtc/RTCRtpReceiver-getParameters.html": [
"97e5d10d1e53b18d3c9deca969d2046881418569",
"453844d5f0e63cf6690ca8eb5fe3335073d34921",
"testharness"
],
"webrtc/RTCRtpReceiver-getStats.https.html": [
"4a2e6a0bd8b0ac9528ed4eeb0b47fea83b26c54f",
"05ca9f3c90b652a4c46a0395bf2ad1a6eb44e15f",
"testharness"
],
"webrtc/RTCRtpReceiver-getSynchronizationSources.https.html": [
@ -669549,7 +669598,7 @@
"testharness"
],
"webrtc/RTCRtpSender-getStats.https.html": [
"18ab82555447194dbacfb07aa5715953c0f17dde",
"1af8285f4c325f38b322d26aa582f3bed7f70585",
"testharness"
],
"webrtc/RTCRtpSender-replaceTrack.https.html": [
@ -669569,15 +669618,15 @@
"testharness"
],
"webrtc/RTCRtpTransceiver.https.html": [
"860f5de2d2aca4b3cbcc6e201c8dc774f154346f",
"2de9fb9f6ee4dbc555bf30ba46f21df30385dd5c",
"testharness"
],
"webrtc/RTCSctpTransport-constructor.html": [
"c415c3fe180b6718fa11c20b1bc9a1ecd88a4547",
"7d3df051d876e490c926639499c13ba0dcf8d30a",
"testharness"
],
"webrtc/RTCSctpTransport-maxMessageSize.html": [
"28d17eeaccf3f26aaca93c9e1f1eab9edc643aaa",
"9163a66af151e3e2f13ab7c4a40e56e3f162c97f",
"testharness"
],
"webrtc/RTCStats-helper.js": [
@ -669609,7 +669658,7 @@
"support"
],
"webrtc/getstats.html": [
"937f54b74ec8266f890d60a4c67e75c3d6714826",
"053d9092ceb6f1ca6900d164ee10965c001f2a0c",
"testharness"
],
"webrtc/historical.html": [
@ -669620,8 +669669,24 @@
"3c57a022cabfbedcf4a015024ac88ecd3080faf6",
"testharness"
],
"webrtc/legacy/README.txt": [
"8adbf6aa173949718a90bd54cc95361e1a8801ba",
"support"
],
"webrtc/legacy/RTCPeerConnection-createOffer-offerToReceive.html": [
"f710498e75f1be587c66d1d0dfe215cb136cc747",
"testharness"
],
"webrtc/legacy/RTCRtpTransceiver-with-OfferToReceive-options.https.html": [
"8c2975214c4dce28a41336de128e0c54c0800828",
"testharness"
],
"webrtc/legacy/onaddstream.https.html": [
"5aa16b36a24e1bce3c286cc5aec249a891bf76f0",
"testharness"
],
"webrtc/no-media-call.html": [
"8f4f5962d4af9de8fd25b9a64aedb49c7b0a0824",
"0f2e2a33e62b47292085c14ad36a253d800c5982",
"testharness"
],
"webrtc/promises-call.html": [
@ -669632,8 +669697,12 @@
"062db8540f43278b7a49a94c3fa25647f038ef8f",
"support"
],
"webrtc/protocol/jsep-initial-offer.https.html": [
"88bdfcfc2867335ca53c30f5637b38b3d12c64ca",
"testharness"
],
"webrtc/protocol/video-codecs.https.html": [
"547856f2a271b5c349b529ec7f1fe1acb5a48ef0",
"e728effbeb94de865df9f8860cd45c8de1f601c1",
"testharness"
],
"webrtc/resources/RTCCertificate-postMessage-iframe.html": [

View file

@ -0,0 +1,2 @@
[mix-blend-mode-animation.html]
expected: FAIL

View file

@ -74,3 +74,9 @@
[opacity end]
expected: FAIL
[border-top-width end]
expected: FAIL
[border-right-width end]
expected: FAIL

View file

@ -1,4 +0,0 @@
[006.html]
[Link with onclick form submit and href navigation ]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_1.html]
[Multiple history traversals from the same task]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_5.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -18,18 +18,6 @@
[Set data URL frame location.protocol to http+x]
expected: FAIL
[Set HTTP URL frame location.protocol to data]
expected: FAIL
[Set HTTP URL frame location.protocol to gopher]
expected: FAIL
[Set HTTP URL frame location.protocol to http+x]
expected: FAIL
[Set HTTP URL frame location.protocol to ftp]
expected: FAIL
[Set HTTP URL frame location.protocol to x]
expected: FAIL

View file

@ -1,10 +0,0 @@
[non-active-document.html]
[DOMParser]
expected: FAIL
[createHTMLDocument]
expected: FAIL
[<template>]
expected: FAIL

View file

@ -0,0 +1,7 @@
[toggleEvent.html]
[Calling open twice on 'details' fires only one toggle event]
expected: FAIL
[Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element]
expected: FAIL

View file

@ -12,6 +12,3 @@
[Verifies the resolution of entry.startTime is at least 5 microseconds.]
expected: TIMEOUT
[Verifies the resolution of performance.now() is at least 5 microseconds.]
expected: FAIL

View file

@ -1,283 +0,0 @@
[no-quirks.html]
[top: -\\31 .5]
expected: FAIL
[bottom: -1A]
expected: FAIL
[bottom: -1a]
expected: FAIL
[top: @1]
expected: FAIL
[top: "1a"]
expected: FAIL
[top: @a]
expected: FAIL
[bottom: "1"]
expected: FAIL
[bottom: -/**/1]
expected: FAIL
[top: +/**/1]
expected: FAIL
[bottom: @1a]
expected: FAIL
[top: 1\\31 ]
expected: FAIL
[top: url('1')]
expected: FAIL
[bottom: -\\31 ]
expected: FAIL
[top: calc(1)]
expected: FAIL
[top: \\31 ]
expected: FAIL
[bottom: +1\\31 ]
expected: FAIL
[bottom: 1\\31 .5]
expected: FAIL
[bottom: #0001]
expected: FAIL
[top: calc(2 * 2px)]
expected: FAIL
[bottom: 1a]
expected: FAIL
[bottom: A]
expected: FAIL
[bottom: #01]
expected: FAIL
[top: +\\31 .5]
expected: FAIL
[bottom: #1]
expected: FAIL
[top: -/**/1]
expected: FAIL
[bottom: +\\31 .5]
expected: FAIL
[bottom: \\31 ]
expected: FAIL
[bottom: calc(1)]
expected: FAIL
[top: #001]
expected: FAIL
[top: +\\31 ]
expected: FAIL
[bottom: +\\31 ]
expected: FAIL
[top: +1.5]
expected: FAIL
[top: +1\\31 ]
expected: FAIL
[bottom: @a]
expected: FAIL
[bottom: @1]
expected: FAIL
[top: #1]
expected: FAIL
[top: 1a]
expected: FAIL
[bottom: +1a]
expected: FAIL
[bottom: +1A]
expected: FAIL
[bottom: "a"]
expected: FAIL
[top: #00001]
expected: FAIL
[bottom: -1\\31 .5]
expected: FAIL
[top: "1"]
expected: FAIL
[bottom: 1.5]
expected: FAIL
[bottom: -\\31 .5]
expected: FAIL
[bottom: url('1')]
expected: FAIL
[bottom: -1.5]
expected: FAIL
[top: \\31 .5]
expected: FAIL
[bottom: "1a"]
expected: FAIL
[bottom: calc(2 * 2px)]
expected: FAIL
[bottom: +1\\31 .5]
expected: FAIL
[bottom: 1\\31 ]
expected: FAIL
[bottom: +/**/1]
expected: FAIL
[bottom: #00001]
expected: FAIL
[top: url(1)]
expected: FAIL
[bottom: #001]
expected: FAIL
[top: +1\\31 .5]
expected: FAIL
[top: -1a]
expected: FAIL
[top: -1A]
expected: FAIL
[bottom: url(1)]
expected: FAIL
[top: a]
expected: FAIL
[top: A]
expected: FAIL
[top: #000001]
expected: FAIL
[top: 1]
expected: FAIL
[top: 1\\31 .5]
expected: FAIL
[bottom: a]
expected: FAIL
[bottom: 1]
expected: FAIL
[bottom: +1]
expected: FAIL
[bottom: #000001]
expected: FAIL
[bottom: +a]
expected: FAIL
[bottom: +A]
expected: FAIL
[top: 1.5]
expected: FAIL
[top: +A]
expected: FAIL
[top: +a]
expected: FAIL
[top: +1]
expected: FAIL
[top: -1.5]
expected: FAIL
[top: -1\\31 .5]
expected: FAIL
[top: +1a]
expected: FAIL
[top: +1A]
expected: FAIL
[top: @1a]
expected: FAIL
[bottom: \\31 .5]
expected: FAIL
[top: "a"]
expected: FAIL
[top: #01]
expected: FAIL
[bottom: +1.5]
expected: FAIL
[bottom: -A]
expected: FAIL
[bottom: -a]
expected: FAIL
[bottom: -1\\31 ]
expected: FAIL
[top: #0001]
expected: FAIL
[bottom: -1]
expected: FAIL
[top: -\\31 ]
expected: FAIL
[top: -A]
expected: FAIL
[top: -a]
expected: FAIL
[top: -1]
expected: FAIL
[top: -1\\31 ]
expected: FAIL

View file

@ -8,35 +8,20 @@
[response.formData() with input: a&b&c]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a=b&c=d]
expected: FAIL
[urlencoded-parser.any.worker.html]
[request.formData() with input: a&b&c]
expected: FAIL
[request.formData() with input: a=b&c=d&]
expected: FAIL
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a&b&c]
expected: FAIL
[response.formData() with input: a=b&c=d&]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x]
[response.formData() with input: a=b&c=d]
expected: FAIL

View file

@ -1,4 +1,5 @@
[realtimeanalyser-fft-scaling.html]
expected: TIMEOUT
[X 2048-point FFT peak position is not equal to 64. Got 0.]
expected: FAIL

View file

@ -1,4 +0,0 @@
[paint_timing.html]
[Performance entries observer]
expected: FAIL

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Inheritance of CSS Positioned Layout properties</title>
<link rel="help" href="https://drafts.csswg.org/css-position/#property-index">
<meta name="assert" content="Properties inherit or not according to the spec.">
<meta name="assert" content="Properties have initial values according to the spec.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/inheritance-testcommon.js"></script>
</head>
<body>
<div id="container">
<div id="target"></div>
</div>
<style>
#container, #target {
position: sticky;
}
</style>
<script>
assert_not_inherited('position', 'static', 'absolute');
assert_not_inherited('top', 'auto', '10px');
assert_not_inherited('right', 'auto', '10px');
assert_not_inherited('bottom', 'auto', '10px');
assert_not_inherited('left', 'auto', '10px');
assert_not_inherited('inset-before', 'auto', '10px');
assert_not_inherited('inset-after', 'auto', '10px');
assert_not_inherited('inset-start', 'auto', '10px');
assert_not_inherited('inset-end', 'auto', '10px');
assert_not_inherited('z-index', 'auto', '123');
</script>
</body>
</html>

View file

@ -0,0 +1,75 @@
<!doctype html>
<html>
<head>
<title>MediaRecorder Error</title>
<link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html#mediarecorder">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<canvas id="canvas" width="320" height="320">
</canvas>
<script>
function createAudioStream() {
let ac = new AudioContext();
let osc = ac.createOscillator();
let dest = ac.createMediaStreamDestination();
osc.connect(dest);
return dest.stream;
}
function createVideoStream() {
let canvas = document.getElementById("canvas");
canvas.getContext('2d').lineTo(10, 10);
return canvas.captureStream();
}
async_test(t => {
let video = createVideoStream();
let audio = createAudioStream();
let recorder = new MediaRecorder(video);
recorder.onerror = t.step_func(mediaRecorderErrorEvent => {
assert_true(mediaRecorderErrorEvent instanceof MediaRecorderErrorEvent, 'the type of event should be MediaRecorderErrorEvent');
assert_equals(mediaRecorderErrorEvent.error.name, 'UnknownError', 'the type of error should be UnknownError when track has been added or removed');
assert_true(mediaRecorderErrorEvent.isTrusted, 'isTrusted should be true when the event is created by C++');
assert_equals(recorder.state, "inactive", "MediaRecorder has been stopped after adding a track to stream");
t.done();
});
recorder.start();
assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully");
video.addTrack(audio.getAudioTracks()[0]);
t.step_timeout(() => {
assert_unreached("error event is not fired after 2 seconds");
}, 2000);
}, "MediaRecorder will stop recording when any of track is added and error event will be fired");
async_test(t => {
let video = createVideoStream();
let recorder = new MediaRecorder(video);
recorder.onerror = t.step_func(mediaRecorderErrorEvent => {
assert_true(mediaRecorderErrorEvent instanceof MediaRecorderErrorEvent, 'the type of event should be MediaRecorderErrorEvent');
assert_equals(mediaRecorderErrorEvent.error.name, 'UnknownError', 'the type of error should be UnknownError when track has been added or removed');
assert_true(mediaRecorderErrorEvent.isTrusted, 'isTrusted should be true when the event is created by C++');
assert_equals(recorder.state, "inactive", "MediaRecorder has been stopped after removing a track from stream");
t.done();
});
recorder.start();
assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully");
video.removeTrack(video.getVideoTracks()[0]);
t.step_timeout(() => {
assert_unreached("error event is not fired after 2 seconds");
}, 2000);
}, "MediaRecorder will stop recording when any of track is removed and error event will be fired");
test(t => {
let video = createVideoStream();
let recorder = new MediaRecorder(video);
recorder.start();
assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully");
assert_throws("InvalidStateError", function() {
recorder.start();
});
}, "MediaRecorder cannot start recording when MediaRecorder' state is not inactive and an InvalidStateError should be thrown");
</script>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection constructor</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
test(() => {
const toStringThrows = { toString: function() { throw new Error; } };
assert_throws(new Error, () => new RTCPeerConnection({ peerIdentity: toStringThrows }));
}, "RTCPeerConnection constructor throws if the given peerIdentity getter throws");
</script>

View file

@ -276,19 +276,6 @@
createAnswer to mark the corresponding media description as sendrecv
or sendonly and add the MSID of the track added, as defined in [JSEP]
(section 5.2.2. and section 5.3.2.).
9. A track could have contents that are inaccessible to the application.
This can be due to being marked with a peerIdentity option or anything
that would make a track CORS cross-origin. These tracks can be supplied
to the addTrack method, and have an RTCRtpSender created for them, but
content must not be transmitted, unless they are also marked with
peerIdentity and they meet the requirements for sending (see isolated
streams and RTCPeerConnection).
All other tracks that are not accessible to the application must not be
sent to the peer, with silence (audio), black frames (video) or
equivalently absent content being sent in place of track content.
Note that this property can change over time.
Non-Testable
5.1. addTrack

View file

@ -23,9 +23,6 @@ const testArgs = {
'undefined': false,
'{}': false,
// peerIdentity
'{ peerIdentity: toStringThrows }': new Error,
// certificates
'{ certificates: null }': new TypeError,
'{ certificates: undefined }': false,

View file

@ -11,8 +11,7 @@
// https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer()
// generateAnswer()
// generateDataChannelOffer()
/*
* 4.3.2. createAnswer()
@ -39,7 +38,7 @@
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer => pc.setRemoteDescription(offer))
.then(() => pc.createAnswer())
.then(answer => {
@ -56,7 +55,7 @@
t.add_cleanup(() => pc.close());
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then(offer => pc.setRemoteDescription(offer))
.then(() => {
pc.close();

View file

@ -11,8 +11,6 @@
// https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer()
// generateAnswer()
// countAudioLine()
// countVideoLine()
// assert_session_desc_similar()
@ -49,7 +47,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveAudio: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => {
@ -113,93 +111,4 @@
* 5. If this inspection failed for any reason, reject p with a newly created
* OperationError and abort these steps.
*/
/*
* 4.3.3.2 Configuration data extensions
* partial dictionary RTCOfferOptions
*/
/*
* offerToReceiveAudio of type boolean
* When this is given a non-false value, no outgoing track of type
* "audio" is attached to the PeerConnection, and the existing
* localDescription (if any) doesn't contain any sendrecv or recv
* audio media sections, createOffer() will behave as if
* addTransceiver("audio") had been called once prior to the createOffer() call.
*/
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveAudio: true })
.then(offer1 => {
assert_equals(countAudioLine(offer1.sdp), 1,
'Expect created offer to have audio line');
// The first createOffer implicitly calls addTransceiver('audio'),
// so all following offers will also have audio media section
// in their SDP.
return pc.createOffer({ offerToReceiveAudio: false })
.then(offer2 => {
assert_equals(countAudioLine(offer2.sdp), 1,
'Expect audio line to remain in created offer');
})
});
}, 'createOffer() with offerToReceiveAudio should add audio line to all subsequent created offers');
/*
* offerToReceiveVideo of type boolean
* When this is given a non-false value, and no outgoing track
* of type "video" is attached to the PeerConnection, and the
* existing localDescription (if any) doesn't contain any sendecv
* or recv video media sections, createOffer() will behave as if
* addTransceiver("video") had been called prior to the createOffer() call.
*/
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveVideo: true })
.then(offer1 => {
assert_equals(countVideoLine(offer1.sdp), 1,
'Expect created offer to have video line');
return pc.createOffer({ offerToReceiveVideo: false })
.then(offer2 => {
assert_equals(countVideoLine(offer2.sdp), 1,
'Expect video line to remain in created offer');
})
});
}, 'createOffer() with offerToReceiveVideo should add video line to all subsequent created offers');
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: false
}).then(offer1 => {
assert_equals(countAudioLine(offer1.sdp), 1,
'Expect audio line to be found in created offer');
assert_equals(countVideoLine(offer1.sdp), 0,
'Expect video line to not found in create offer');
return pc.createOffer({
offerToReceiveAudio: false,
offerToReceiveVideo: true
}).then(offer2 => {
assert_equals(countAudioLine(offer2.sdp), 1,
'Expect audio line to remain in created offer');
assert_equals(countVideoLine(offer2.sdp), 1,
'Expect video line to be found in create offer');
})
});
}, 'createOffer() with offerToReceiveAudio:true then offerToReceiveVideo:true should have result offer with both audio and video line');
</script>

View file

@ -103,73 +103,41 @@ function assert_session_desc_not_similar(sessionDesc1, sessionDesc2) {
'Expect both session descriptions to have different count of media lines');
}
// Helper function to generate offer using a freshly created RTCPeerConnection
// object with any audio, video, data media lines present
function generateOffer(options={}) {
const {
audio = false,
video = false,
data = false,
pc,
} = options;
if (data) {
async function generateDataChannelOffer(pc) {
pc.createDataChannel('test');
}
const setup = {};
if (audio) {
setup.offerToReceiveAudio = true;
}
if (video) {
setup.offerToReceiveVideo = true;
}
return pc.createOffer(setup).then(offer => {
// Guard here to ensure that the generated offer really
// contain the number of media lines we want
const { sdp } = offer;
if(audio) {
assert_equals(countAudioLine(sdp), 1,
'Expect m=audio line to be present in generated SDP');
} else {
assert_equals(countAudioLine(sdp), 0,
'Expect m=audio line to be present in generated SDP');
}
if(video) {
assert_equals(countVideoLine(sdp), 1,
'Expect m=video line to be present in generated SDP');
} else {
assert_equals(countVideoLine(sdp), 0,
'Expect m=video line to not present in generated SDP');
}
if(data) {
assert_equals(countApplicationLine(sdp), 1,
'Expect m=application line to be present in generated SDP');
} else {
assert_equals(countApplicationLine(sdp), 0,
'Expect m=application line to not present in generated SDP');
}
const offer = await pc.createOffer();
assert_equals(countApplicationLine(offer.sdp), 1, 'Expect m=application line to be present in generated SDP');
return offer;
});
}
async function generateAudioReceiveOnlyOffer(pc)
{
try {
pc.addTransceiver('audio', { direction: 'recvonly' });
return pc.createOffer();
} catch(e) {
return pc.createOffer({ offerToReceiveAudio: true });
}
}
async function generateVideoReceiveOnlyOffer(pc)
{
try {
pc.addTransceiver('video', { direction: 'recvonly' });
return pc.createOffer();
} catch(e) {
return pc.createOffer({ offerToReceiveVideo: true });
}
}
// Helper function to generate answer based on given offer using a freshly
// created RTCPeerConnection object
function generateAnswer(offer) {
async function generateAnswer(offer) {
const pc = new RTCPeerConnection();
return pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())
.then((answer) => {
await pc.setRemoteDescription(offer);
const answer = await pc.createAnswer();
pc.close();
return answer;
});
}
// Run a test function that return a promise that should

View file

@ -11,7 +11,6 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateAnswer
// assert_session_desc_similar
@ -65,7 +64,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())
@ -97,7 +96,7 @@
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())
@ -128,7 +127,7 @@
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => generateAnswer(offer))

View file

@ -11,7 +11,7 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateDataChannelOffer
// assert_session_desc_not_similar
// assert_session_desc_similar
@ -62,7 +62,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveAudio: true })
return generateAudioReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => {
@ -84,7 +84,7 @@
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveAudio: true })
return generateAudioReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription({ type: 'offer' })
.then(() => {
@ -109,7 +109,7 @@
t.add_cleanup(() => pc2.close());
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then(offer =>
promise_rejects(t, 'InvalidModificationError',
pc2.setLocalDescription(offer)));
@ -122,9 +122,9 @@
// with the first offer
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveAudio: true })
return generateAudioReceiveOnlyOffer(pc)
.then(offer1 =>
pc.createOffer({ offerToReceiveVideo: true })
generateVideoReceiveOnlyOffer(pc)
.then(offer2 => {
assert_session_desc_not_similar(offer1, offer2);
return promise_rejects(t, 'InvalidModificationError',
@ -139,11 +139,11 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveAudio: true })
return generateAudioReceiveOnlyOffer(pc)
.then(offer1 =>
pc.setLocalDescription(offer1)
.then(() =>
pc.createOffer({ offerToReceiveVideo: true })
generateVideoReceiveOnlyOffer(pc)
.then(offer2 =>
pc.setLocalDescription(offer2)
.then(offer2 => {

View file

@ -11,8 +11,6 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateAnswer
// assert_session_desc_similar
/*
@ -86,7 +84,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())
@ -119,7 +117,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())
@ -141,7 +139,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setRemoteDescription(offer)
.then(() => pc.createAnswer())

View file

@ -11,7 +11,7 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateDataChannelOffer
// assert_session_desc_not_similar
// assert_session_desc_similar
@ -50,14 +50,14 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveAudio: true })
return generateAudioReceiveOnlyOffer(pc)
.then(offer1 =>
pc.setLocalDescription(offer1)
.then(() => generateAnswer(offer1))
.then(answer => pc.setRemoteDescription(answer))
.then(() => {
pc.createDataChannel('test');
return pc.createOffer({ offerToReceiveVideo: true });
return generateVideoReceiveOnlyOffer(pc);
})
.then(offer2 =>
pc.setLocalDescription(offer2)
@ -79,12 +79,12 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then(offer => pc.setRemoteDescription(offer))
.then(() => pc.createAnswer())
.then(answer =>
pc.setLocalDescription(answer)
.then(() => pc.createOffer({ offerToReceiveVideo: true }))
.then(() => generateVideoReceiveOnlyOffer(pc))
.then(offer =>
pc.setLocalDescription(offer)
.then(() => {

View file

@ -11,7 +11,6 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer()
// generateAnswer()
// assert_session_desc_similar()
@ -64,7 +63,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => generateAnswer(offer))

View file

@ -11,7 +11,6 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateAnswer
// assert_session_desc_similar
@ -86,7 +85,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => generateAnswer(offer))
@ -117,7 +116,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => generateAnswer(offer))
@ -139,7 +138,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return pc.createOffer({ offerToReceiveVideo: true })
return generateVideoReceiveOnlyOffer(pc)
.then(offer =>
pc.setLocalDescription(offer)
.then(() => generateAnswer(offer))

View file

@ -11,7 +11,7 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer
// generateDataChannelOffer
// assert_session_desc_similar
/*
@ -63,7 +63,7 @@
const states = [];
pc.addEventListener('signalingstatechange', () => states.push(pc.signalingState));
return generateOffer({ data: true })
return generateDataChannelOffer(pc)
.then(offer => pc.setRemoteDescription(offer))
.then(() => {
assert_equals(pc.signalingState, 'have-remote-offer');

View file

@ -91,7 +91,7 @@
assert_equals(state, states[eventCount]);
};
const offer = await pc.createOffer({ offerToReceiveAudio: true });
const offer = await generateAudioReceiveOnlyOffer(pc);
assert_state('stable');
await pc.setLocalDescription(offer);
assert_state('have-local-offer');
@ -111,10 +111,10 @@
t.add_cleanup(() => pc.close());
t.add_cleanup(() => pc2.close());
const offer1 = await pc2.createOffer({ offerToReceiveAudio: true });
const offer1 = await generateAudioReceiveOnlyOffer(pc2);
await pc.setRemoteDescription(offer1);
await pc.setLocalDescription(await pc.createAnswer());
const offer2 = await pc2.createOffer({ offerToReceiveVideo: true });
const offer2 = await generateVideoReceiveOnlyOffer(pc2);
await pc.setRemoteDescription(offer2);
assert_session_desc_not_similar(offer1, offer2);
assert_session_desc_similar(pc.remoteDescription, offer2);
@ -128,7 +128,7 @@
t.add_cleanup(() => pc.close());
t.add_cleanup(() => pc2.close());
const offer = await pc.createOffer({ offerToReceiveAudio: true });
const offer = await generateAudioReceiveOnlyOffer(pc);
await pc.setLocalDescription(offer);
await pc2.setRemoteDescription(offer);
const answer = await pc2.createAnswer();

View file

@ -36,7 +36,7 @@
test(t => {
const pc = new RTCPeerConnection();
const { receiver } = pc.addTransceiver('audio');
const param = pc.getParameters();
const param = receiver.getParameters();
validateReceiverRtpParameters(param);
});
</script>

View file

@ -49,6 +49,12 @@
t.add_cleanup(() => caller.close());
const callee = new RTCPeerConnection();
t.add_cleanup(() => callee.close());
const stream = await getNoiseStream({audio:true});
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
const [track] = stream.getTracks();
callee.addTrack(track);
const { receiver } = caller.addTransceiver('audio');
await doSignalingHandshake(caller, callee);

View file

@ -44,7 +44,11 @@
t.add_cleanup(() => caller.close());
const callee = new RTCPeerConnection();
t.add_cleanup(() => callee.close());
const { sender } = caller.addTransceiver('audio');
const stream = await getNoiseStream({audio:true});
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
const [track] = stream.getTracks();
const { sender } = caller.addTransceiver(track);
await doSignalingHandshake(caller, callee);
const statsReport = await sender.getStats();

View file

@ -305,125 +305,6 @@
]);
};
const checkAddTransceiverWithStream = async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const audioStream = await navigator.mediaDevices.getUserMedia({audio: true});
const videoStream = await navigator.mediaDevices.getUserMedia({video: true});
t.add_cleanup(() => stopTracks(audioStream, videoStream));
const audio = audioStream.getAudioTracks()[0];
const video = videoStream.getVideoTracks()[0];
pc.addTransceiver(audio, {streams: [audioStream]});
pc.addTransceiver(video, {streams: [videoStream]});
hasProps(pc.getTransceivers(),
[
{
receiver: {track: {kind: "audio"}},
sender: {track: audio},
direction: "sendrecv",
mid: null,
currentDirection: null,
stopped: false
},
{
receiver: {track: {kind: "video"}},
sender: {track: video},
direction: "sendrecv",
mid: null,
currentDirection: null,
stopped: false
}
]);
const offer = await pc.createOffer();
assert_true(offer.sdp.includes("a=msid:" + audioStream.id + " " + audio.id),
"offer contains the expected audio msid");
assert_true(offer.sdp.includes("a=msid:" + videoStream.id + " " + video.id),
"offer contains the expected video msid");
};
const checkAddTransceiverWithOfferToReceive = async (t, kinds) => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const propsToSet = kinds.map(kind => {
if (kind == "audio") {
return "offerToReceiveAudio";
} else if (kind == "video") {
return "offerToReceiveVideo";
}
});
const options = {};
for (const prop of propsToSet) {
options[prop] = true;
}
let offer = await pc.createOffer(options);
const expected = [];
if (options.offerToReceiveAudio) {
expected.push(
{
receiver: {track: {kind: "audio"}},
sender: {track: null},
direction: "recvonly",
mid: null,
currentDirection: null,
stopped: false
});
}
if (options.offerToReceiveVideo) {
expected.push(
{
receiver: {track: {kind: "video"}},
sender: {track: null},
direction: "recvonly",
mid: null,
currentDirection: null,
stopped: false
});
}
hasProps(pc.getTransceivers(), expected);
// Test offerToReceive: false
for (const prop of propsToSet) {
options[prop] = false;
}
// Check that sendrecv goes to sendonly
for (const transceiver of pc.getTransceivers()) {
transceiver.direction = "sendrecv";
}
for (const transceiverCheck of expected) {
transceiverCheck.direction = "sendonly";
}
offer = await pc.createOffer(options);
hasProps(pc.getTransceivers(), expected);
// Check that recvonly goes to inactive
for (const transceiver of pc.getTransceivers()) {
transceiver.direction = "recvonly";
}
for (const transceiverCheck of expected) {
transceiverCheck.direction = "inactive";
}
offer = await pc.createOffer(options);
hasProps(pc.getTransceivers(), expected);
};
const checkAddTransceiverWithSetRemoteOfferSending = async t => {
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
@ -1248,70 +1129,6 @@
assert_equals(2, countUnmuteVideo2.count, "Got 2 unmute events for pc2's video track");
};
const checkOnAddStream = async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const stream1 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
t.add_cleanup(() => stopTracks(stream1));
const audio1 = stream1.getAudioTracks()[0];
pc1.addTrack(audio1, stream1);
const video1 = stream1.getVideoTracks()[0];
pc1.addTrack(video1, stream1);
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
const stream2 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
t.add_cleanup(() => stopTracks(stream2));
const audio2 = stream2.getAudioTracks()[0];
pc2.addTrack(audio2, stream2);
const video2 = stream2.getVideoTracks()[0];
pc2.addTrack(video2, stream2);
const offer = await pc1.createOffer();
let trackEventCollector = collectTrackEvents(pc2);
let addstreamEventCollector = collectEvents(pc2, "addstream", e => {
hasProps(e, {stream: {id: stream1.id}});
assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
});
await pc2.setRemoteDescription(offer);
let addstreamEvents = addstreamEventCollector.finish();
assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");
let trackEvents = trackEventCollector.finish();
hasProps(trackEvents,
[
{streams: [addstreamEvents[0].stream]},
{streams: [addstreamEvents[0].stream]}
]);
await pc1.setLocalDescription(offer);
const answer = await pc2.createAnswer();
trackEventCollector = collectTrackEvents(pc1);
addstreamEventCollector = collectEvents(pc1, "addstream", e => {
hasProps(e, {stream: {id: stream2.id}});
assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
});
await pc1.setRemoteDescription(answer);
addstreamEvents = addstreamEventCollector.finish();
assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");
trackEvents = trackEventCollector.finish();
hasProps(trackEvents,
[
{streams: [addstreamEvents[0].stream]},
{streams: [addstreamEvents[0].stream]}
]);
};
const checkStop = async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
@ -2312,16 +2129,6 @@ const tests = [
checkAddTransceiverWithTrack,
checkAddTransceiverWithAddTrack,
checkAddTransceiverWithDirection,
checkAddTransceiverWithStream,
function checkAddTransceiverWithOfferToReceiveAudio(t) {
return checkAddTransceiverWithOfferToReceive(t, ["audio"]);
},
function checkAddTransceiverWithOfferToReceiveVideo(t) {
return checkAddTransceiverWithOfferToReceive(t, ["video"]);
},
function checkAddTransceiverWithOfferToReceiveBoth(t) {
return checkAddTransceiverWithOfferToReceive(t, ["audio", "video"]);
},
checkAddTransceiverWithSetRemoteOfferSending,
checkAddTransceiverWithSetRemoteOfferNoSend,
checkAddTransceiverBadKind,
@ -2340,7 +2147,6 @@ const tests = [
checkAddTrackExistingTransceiverThenRemove,
checkRemoveTrackNegotiation,
checkMute,
checkOnAddStream,
checkStop,
checkStopAfterCreateOffer,
checkStopAfterSetLocalOffer,

View file

@ -11,7 +11,7 @@
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
// The following helper functions are called from RTCPeerConnection-helper.js:
// generateOffer()
// generateDataChannelOffer()
// generateAnswer()
/*
@ -69,7 +69,7 @@
t.add_cleanup(() => pc.close());
assert_equals(pc.sctp, null);
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then(offer => pc.setRemoteDescription(offer))
.then(() => pc.createAnswer())
.then(answer => pc.setLocalDescription(answer))

View file

@ -49,7 +49,7 @@ promise_test(t => {
assert_equals(pc.sctp, null);
let maxMessageSize;
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then((offer) => {
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
'SDP should have max-message-size attribute');
@ -73,7 +73,7 @@ promise_test(t => {
t.add_cleanup(() => pc.close());
assert_equals(pc.sctp, null);
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then((offer) => {
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
'SDP should have max-message-size attribute');
@ -102,7 +102,7 @@ promise_test(t => {
t.add_cleanup(() => pc.close());
assert_equals(pc.sctp, null);
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then((offer) => {
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
'SDP should have max-message-size attribute');
@ -124,7 +124,7 @@ promise_test(t => {
t.add_cleanup(() => pc.close());
assert_equals(pc.sctp, null);
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then((offer) => {
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
'SDP should have max-message-size attribute');
@ -160,7 +160,7 @@ promise_test(t => {
assert_equals(pc.sctp, null);
const largerThanCanSendSize = canSendSize + 1;
return generateOffer({ pc, data: true })
return generateDataChannelOffer(pc)
.then((offer) => {
assert_not_equals(mmsAttributeHelper.getValue(offer.sdp), null,
'SDP should have max-message-size attribute');

View file

@ -38,10 +38,6 @@ This test uses data only, and thus does not require fake media devices.
}
});
var onRemoteStream = test.step_func(function(event) {
assert_unreached('WebRTC received a stream when there was none');
});
var getStatsRecordByType = function(stats, type) {
for (let stat of stats.values()) {
if (stat.type == type) {
@ -91,7 +87,6 @@ This test uses data only, and thus does not require fake media devices.
gSecondConnection = new RTCPeerConnection(null);
gSecondConnection.onicecandidate = onIceCandidateToSecond;
gSecondConnection.onaddstream = onRemoteStream;
// The createDataChannel is necessary and sufficient to make
// sure the ICE connection be attempted.

View file

@ -0,0 +1,2 @@
This directory contains files that test for behavior relevant to webrtc,
particularly defined in https://w3c.github.io/webrtc-pc/#legacy-interface-extensions

View file

@ -4,10 +4,99 @@
<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 src="../RTCPeerConnection-helper.js"></script>
<script>
'use strict';
/*
* 4.3.3.2 Configuration data extensions
* partial dictionary RTCOfferOptions
*/
/*
* offerToReceiveAudio of type boolean
* When this is given a non-false value, no outgoing track of type
* "audio" is attached to the PeerConnection, and the existing
* localDescription (if any) doesn't contain any sendrecv or recv
* audio media sections, createOffer() will behave as if
* addTransceiver("audio") had been called once prior to the createOffer() call.
*/
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveAudio: true })
.then(offer1 => {
assert_equals(countAudioLine(offer1.sdp), 1,
'Expect created offer to have audio line');
// The first createOffer implicitly calls addTransceiver('audio'),
// so all following offers will also have audio media section
// in their SDP.
return pc.createOffer({ offerToReceiveAudio: false })
.then(offer2 => {
assert_equals(countAudioLine(offer2.sdp), 1,
'Expect audio line to remain in created offer');
})
});
}, 'createOffer() with offerToReceiveAudio should add audio line to all subsequent created offers');
/*
* offerToReceiveVideo of type boolean
* When this is given a non-false value, and no outgoing track
* of type "video" is attached to the PeerConnection, and the
* existing localDescription (if any) doesn't contain any sendecv
* or recv video media sections, createOffer() will behave as if
* addTransceiver("video") had been called prior to the createOffer() call.
*/
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({ offerToReceiveVideo: true })
.then(offer1 => {
assert_equals(countVideoLine(offer1.sdp), 1,
'Expect created offer to have video line');
return pc.createOffer({ offerToReceiveVideo: false })
.then(offer2 => {
assert_equals(countVideoLine(offer2.sdp), 1,
'Expect video line to remain in created offer');
})
});
}, 'createOffer() with offerToReceiveVideo should add video line to all subsequent created offers');
promise_test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
return pc.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: false
}).then(offer1 => {
assert_equals(countAudioLine(offer1.sdp), 1,
'Expect audio line to be found in created offer');
assert_equals(countVideoLine(offer1.sdp), 0,
'Expect video line to not be found in create offer');
return pc.createOffer({
offerToReceiveAudio: false,
offerToReceiveVideo: true
}).then(offer2 => {
assert_equals(countAudioLine(offer2.sdp), 1,
'Expect audio line to remain in created offer');
assert_equals(countVideoLine(offer2.sdp), 1,
'Expect video line to be found in create offer');
})
});
}, 'createOffer() with offerToReceiveAudio:true, then with offerToReceiveVideo:true, should have result offer with both audio and video line');
// Run some tests for both audio and video kinds
['audio', 'video'].forEach((kind) => {
const capsKind = kind[0].toUpperCase() + kind.slice(1);

View file

@ -0,0 +1,169 @@
<!doctype html>
<meta charset=utf-8>
<title>RTCRtpTransceiver with OfferToReceive legacy options</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../RTCPeerConnection-helper.js"></script>
<script>
'use strict';
const stopTracks = (...streams) => {
streams.forEach(stream => stream.getTracks().forEach(track => track.stop()));
};
// comparable() - produces copy of object that is JSON comparable.
// o = original object (required)
// t = template of what to examine. Useful if o is non-enumerable (optional)
const comparable = (o, t = o) => {
if (typeof o != 'object' || !o) {
return o;
}
if (Array.isArray(t) && Array.isArray(o)) {
return o.map((n, i) => comparable(n, t[i]));
}
return Object.keys(t).sort()
.reduce((r, key) => (r[key] = comparable(o[key], t[key]), r), {});
};
const stripKeyQuotes = s => s.replace(/"(\w+)":/g, "$1:");
const hasProps = (observed, expected) => {
const observable = comparable(observed, expected);
assert_equals(stripKeyQuotes(JSON.stringify(observable)),
stripKeyQuotes(JSON.stringify(comparable(expected))));
};
const checkAddTransceiverWithStream = async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const audioStream = await navigator.mediaDevices.getUserMedia({audio: true});
const videoStream = await navigator.mediaDevices.getUserMedia({video: true});
t.add_cleanup(() => stopTracks(audioStream, videoStream));
const audio = audioStream.getAudioTracks()[0];
const video = videoStream.getVideoTracks()[0];
pc.addTransceiver(audio, {streams: [audioStream]});
pc.addTransceiver(video, {streams: [videoStream]});
hasProps(pc.getTransceivers(),
[
{
receiver: {track: {kind: "audio"}},
sender: {track: audio},
direction: "sendrecv",
mid: null,
currentDirection: null,
stopped: false
},
{
receiver: {track: {kind: "video"}},
sender: {track: video},
direction: "sendrecv",
mid: null,
currentDirection: null,
stopped: false
}
]);
const offer = await pc.createOffer();
assert_true(offer.sdp.includes("a=msid:" + audioStream.id + " " + audio.id),
"offer contains the expected audio msid");
assert_true(offer.sdp.includes("a=msid:" + videoStream.id + " " + video.id),
"offer contains the expected video msid");
};
const checkAddTransceiverWithOfferToReceive = async (t, kinds) => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const propsToSet = kinds.map(kind => {
if (kind == "audio") {
return "offerToReceiveAudio";
} else if (kind == "video") {
return "offerToReceiveVideo";
}
});
const options = {};
for (const prop of propsToSet) {
options[prop] = true;
}
let offer = await pc.createOffer(options);
const expected = [];
if (options.offerToReceiveAudio) {
expected.push(
{
receiver: {track: {kind: "audio"}},
sender: {track: null},
direction: "recvonly",
mid: null,
currentDirection: null,
stopped: false
});
}
if (options.offerToReceiveVideo) {
expected.push(
{
receiver: {track: {kind: "video"}},
sender: {track: null},
direction: "recvonly",
mid: null,
currentDirection: null,
stopped: false
});
}
hasProps(pc.getTransceivers(), expected);
// Test offerToReceive: false
for (const prop of propsToSet) {
options[prop] = false;
}
// Check that sendrecv goes to sendonly
for (const transceiver of pc.getTransceivers()) {
transceiver.direction = "sendrecv";
}
for (const transceiverCheck of expected) {
transceiverCheck.direction = "sendonly";
}
offer = await pc.createOffer(options);
hasProps(pc.getTransceivers(), expected);
// Check that recvonly goes to inactive
for (const transceiver of pc.getTransceivers()) {
transceiver.direction = "recvonly";
}
for (const transceiverCheck of expected) {
transceiverCheck.direction = "inactive";
}
offer = await pc.createOffer(options);
hasProps(pc.getTransceivers(), expected);
};
const tests = [
checkAddTransceiverWithStream,
function checkAddTransceiverWithOfferToReceiveAudio(t) {
return checkAddTransceiverWithOfferToReceive(t, ["audio"]);
},
function checkAddTransceiverWithOfferToReceiveVideo(t) {
return checkAddTransceiverWithOfferToReceive(t, ["video"]);
},
function checkAddTransceiverWithOfferToReceiveBoth(t) {
return checkAddTransceiverWithOfferToReceive(t, ["audio", "video"]);
}
].forEach(test => promise_test(test, test.name));
</script>

View file

@ -0,0 +1,153 @@
<!doctype html>
<meta charset=utf-8>
<title>onaddstream tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
const stopTracks = (...streams) => {
streams.forEach(stream => stream.getTracks().forEach(track => track.stop()));
};
const collectEvents = (target, name, check) => {
const events = [];
const handler = e => {
check(e);
events.push(e);
};
target.addEventListener(name, handler);
const finishCollecting = () => {
target.removeEventListener(name, handler);
return events;
};
return {finish: finishCollecting};
};
const collectAddTrackEvents = stream => {
const checkEvent = e => {
assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
assert_true(stream.getTracks().includes(e.track),
"track in addtrack event is in the stream");
};
return collectEvents(stream, "addtrack", checkEvent);
};
const collectRemoveTrackEvents = stream => {
const checkEvent = e => {
assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
assert_true(!stream.getTracks().includes(e.track),
"track in removetrack event is not in the stream");
};
return collectEvents(stream, "removetrack", checkEvent);
};
const collectTrackEvents = pc => {
const checkEvent = e => {
assert_true(e.track instanceof MediaStreamTrack, "Track is set on event");
assert_true(e.receiver instanceof RTCRtpReceiver, "Receiver is set on event");
assert_true(e.transceiver instanceof RTCRtpTransceiver, "Transceiver is set on event");
assert_true(Array.isArray(e.streams), "Streams is set on event");
e.streams.forEach(stream => {
assert_true(stream.getTracks().includes(e.track),
"Each stream in event contains the track");
});
assert_equals(e.receiver, e.transceiver.receiver,
"Receiver belongs to transceiver");
assert_equals(e.track, e.receiver.track,
"Track belongs to receiver");
};
return collectEvents(pc, "track", checkEvent);
};
// comparable() - produces copy of object that is JSON comparable.
// o = original object (required)
// t = template of what to examine. Useful if o is non-enumerable (optional)
const comparable = (o, t = o) => {
if (typeof o != 'object' || !o) {
return o;
}
if (Array.isArray(t) && Array.isArray(o)) {
return o.map((n, i) => comparable(n, t[i]));
}
return Object.keys(t).sort()
.reduce((r, key) => (r[key] = comparable(o[key], t[key]), r), {});
};
const stripKeyQuotes = s => s.replace(/"(\w+)":/g, "$1:");
const hasProps = (observed, expected) => {
const observable = comparable(observed, expected);
assert_equals(stripKeyQuotes(JSON.stringify(observable)),
stripKeyQuotes(JSON.stringify(comparable(expected))));
};
promise_test(async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const stream1 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
t.add_cleanup(() => stopTracks(stream1));
const audio1 = stream1.getAudioTracks()[0];
pc1.addTrack(audio1, stream1);
const video1 = stream1.getVideoTracks()[0];
pc1.addTrack(video1, stream1);
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
const stream2 = await navigator.mediaDevices.getUserMedia({audio: true, video: true});
t.add_cleanup(() => stopTracks(stream2));
const audio2 = stream2.getAudioTracks()[0];
pc2.addTrack(audio2, stream2);
const video2 = stream2.getVideoTracks()[0];
pc2.addTrack(video2, stream2);
const offer = await pc1.createOffer();
let trackEventCollector = collectTrackEvents(pc2);
let addstreamEventCollector = collectEvents(pc2, "addstream", e => {
hasProps(e, {stream: {id: stream1.id}});
assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
});
await pc2.setRemoteDescription(offer);
let addstreamEvents = addstreamEventCollector.finish();
assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");
let trackEvents = trackEventCollector.finish();
hasProps(trackEvents,
[
{streams: [addstreamEvents[0].stream]},
{streams: [addstreamEvents[0].stream]}
]);
await pc1.setLocalDescription(offer);
const answer = await pc2.createAnswer();
trackEventCollector = collectTrackEvents(pc1);
addstreamEventCollector = collectEvents(pc1, "addstream", e => {
hasProps(e, {stream: {id: stream2.id}});
assert_equals(e.stream.getAudioTracks().length, 1, "One audio track");
assert_equals(e.stream.getVideoTracks().length, 1, "One video track");
});
await pc1.setRemoteDescription(answer);
addstreamEvents = addstreamEventCollector.finish();
assert_equals(addstreamEvents.length, 1, "Should have 1 addstream event");
trackEvents = trackEventCollector.finish();
hasProps(trackEvents,
[
{streams: [addstreamEvents[0].stream]},
{streams: [addstreamEvents[0].stream]}
]);
},"Check onaddstream");
</script>

View file

@ -17,6 +17,7 @@ This test uses the legacy callback API with no media, and thus does not require
<!-- These files are in place when executing on W3C. -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webrtc/RTCPeerConnection-helper.js"></script>
<script type="text/javascript">
var test = async_test('Can set up a basic WebRTC call with no data.');
@ -123,9 +124,7 @@ This test uses the legacy callback API with no media, and thus does not require
gSecondConnection.onicecandidate = onIceCandidateToSecond;
gSecondConnection.oniceconnectionstatechange = onIceConnectionStateChange;
// The offerToReceiveVideo is necessary and sufficient to make
// an actual connection.
gFirstConnection.createOffer({offerToReceiveVideo: true})
generateVideoReceiveOnlyOffer(gFirstConnection)
.then(onOfferCreated, failed('createOffer'));
});
</script>

View file

@ -0,0 +1,35 @@
<!doctype html>
<meta charset=utf-8>
<title>RTCPeerConnection.prototype.createOffer</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../RTCPeerConnection-helper.js"></script>
<script>
'use strict';
// Tests for the construction of initial offers according to
// draft-ietf-rtcweb-jsep-24 section 5.2.1
promise_test(async t => {
const pc = new RTCPeerConnection();
const offer = await generateVideoReceiveOnlyOffer(pc);
let offer_lines = offer.sdp.split('\r\n');
// The first 3 lines are dictated by JSEP.
assert_equals(offer_lines[0], "v=0");
assert_equals(offer_lines[1].slice(0, 2), "o=");
// JSEP says that the address part SHOULD be a meaningless address
// "such as" IN IP4 127.0.0.1. We do strict matching here in order
// to detect if anyone ever uses something different.
assert_regexp_match(offer_lines[1], /^o=- \d+ \d+ IN IP4 127.0.0.1$/);
const fields = RegExp(/^o=- (\d+) (\d+)/).exec(offer_lines[1]);
// Per RFC 3264, the sess-id should be representable in an uint64
// Note: JSEP -24 has this wrong - see bug:
// https://github.com/rtcweb-wg/jsep/issues/855
assert_less_than(Number(fields[1]), 2**64);
// Per RFC 3264, the version should be less than 2^62 to avoid overflow
assert_less_than(Number(fields[2]), 2**62);
// Note: using - in s=- is a SHOULD in JSEP, not a MUST.
assert_equals(offer_lines[2], "s=-");
// After this, the order is not dictated by JSEP.
// TODO: Check lines subsequent to the s= line.
}, 'Offer conforms to basic SDP requirements');
</script>

View file

@ -21,7 +21,7 @@
// Section 5: Browsers MUST implement VP8 and H.264 Constrained Baseline
promise_test(async t => {
const pc = new RTCPeerConnection();
const offer = await pc.createOffer({offerToReceiveVideo: true});
const offer = await generateVideoReceiveOnlyOffer(pc);
let video_section_found = false;
for (let section of offer.sdp.split(/\r\nm=/)) {
if (section.search('video') != 0) {