Auto merge of #27317 - servo-wpt-sync:wpt_update_18-07-2020, r=servo-wpt-sync

Sync WPT with upstream (18-07-2020)

Automated downstream sync of changes from upstream as of 18-07-2020.
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2020-07-18 06:41:39 -04:00 committed by GitHub
commit ccff00742f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 656 additions and 278 deletions

View file

@ -4,7 +4,7 @@
expected: TIMEOUT
[Opening a blob URL in a new window immediately before revoking it works.]
expected: FAIL
expected: TIMEOUT
[Fetching a blob URL immediately before revoking it works in an iframe.]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -2,6 +2,3 @@
[listeners are called when <iframe> is resized]
expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -17,3 +17,6 @@
[test the top of layer]
expected: FAIL
[test some point of the element: top left corner]
expected: FAIL

View file

@ -312,24 +312,21 @@
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
expected: NOTRUN
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL

View file

@ -53,3 +53,6 @@
[combined text/javascript ]
expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -0,0 +1,19 @@
[javascript-url-return-value-handling-dynamic.html]
[Test javascript URL string return values in direct and indirect (target) frame contexts. 7]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 6]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 5]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 4]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 9]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 8]
expected: FAIL

View file

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

View file

@ -14,6 +14,3 @@
[Host element with delegatesFocus should support autofocus]
expected: FAIL
[Non-HTMLElement should not support autofocus]
expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html]
expected: CRASH
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html]
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[module-static-import-delayed.html]
[document.write in an imported module]
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

@ -0,0 +1,5 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,2 +0,0 @@
[Worker-constructor.html]
expected: ERROR

View file

@ -7,7 +7,7 @@
expected: FAIL
[Opening a blob URL in a new window immediately before revoking it works.]
expected: FAIL
expected: TIMEOUT
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
expected: TIMEOUT

View file

@ -161005,6 +161005,71 @@
{}
]
],
"position-relative-001.html": [
"7ec9e4f767b4548e52e92b358b59e51376dea389",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-relative-002.html": [
"7e176be987e7d6cb52bfa79ef58ec1ee93634375",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-relative-003.html": [
"7a0040c40b534da6367fcc0d0a94ac3f7650bc50",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-relative-004.html": [
"aac4520f728bb833b2ecaaf5c1a03e904e333040",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-relative-005.html": [
"f1ad0846741704285603dff9d719790676f9e9fe",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"position-relative-table-tbody-left-absolute-child.html": [
"98e759a8c0a83817b3d691503e807ed5ed549936",
[
@ -324728,7 +324793,7 @@
],
"resources": {
"cache.py": [
"10122f6439615c840e33d52314bdc14bfb443420",
"ca0bd644b4f798c4fa64d1041b628a3740bc0bac",
[]
],
"hello.txt": [
@ -324743,7 +324808,7 @@
},
"resources": {
"authentication.py": [
"b65047d765703b8e4400396a306b026316fc6d09",
"8b6b00b0873b38e57e579f3d7f2651fb97917b81",
[]
],
"bad-chunk-encoding.py": [
@ -324755,11 +324820,11 @@
[]
],
"cache.py": [
"899638716a100a66c06cebbf92c31de7c705498b",
"4de751e30bfc6a5f6a8b02cd3ed47aa666d193e6",
[]
],
"clean-stash.py": [
"3ae731052692e048a07d65a6e015fe5a76362098",
"ee8c69ac446ea979f63c0f82afd3061610b4b523",
[]
],
"cors-top.txt": [
@ -324787,7 +324852,7 @@
[]
],
"inspect-headers.py": [
"10a12eb883a17c701d909cde650799f21ec898c1",
"9ed566e607b0e07d70ac6a183c0a9a025bcade5f",
[]
],
"keepalive-iframe.html": [
@ -324795,11 +324860,11 @@
[]
],
"method.py": [
"795ad1ff11d085d82cb010b969753b94cbe06b53",
"c1a111b4cdf98dc6d8db702b0cc20d43825779bd",
[]
],
"preflight.py": [
"a2552c2565ad9be6d17dea1cb6a90ff9eb211190",
"f983ef952272a75a6706d3cdfabb08aced7efc7b",
[]
],
"redirect-empty-location.py": [
@ -324839,7 +324904,7 @@
[]
],
"trickle.py": [
"9b3aa37b25c9c99fe1fc6a988cd79ea6c793c287",
"5091a2b3fddce7e9a44cf6ef94e922f79d913693",
[]
],
"utils.js": [
@ -324873,7 +324938,7 @@
"content-encoding": {
"resources": {
"bad-gzip-body.py": [
"b2f8cfefd7e491260648e33adfe9fbd3f8f72fe6",
"a79b94ed041d0e0852e71bdd5cdba57897a1f198",
[]
]
}
@ -325274,7 +325339,7 @@
},
"redirect-navigate": {
"302-found-post-handler.py": [
"23bf4b2c522b7c00ab6bd0fc3eb99f0737d512ec",
"40a224f6565bae3e2c4b32f77e2bf4fd5d5451ee",
[]
],
"resources": {
@ -329293,7 +329358,7 @@
"46ad58d83bf6e98913ca4c564b7acb8f19fa0093",
[]
],
"reporting-popup-unafe-none-report-to.https.html.sub.headers": [
"reporting-popup-unsafe-none-report-to.https.html.sub.headers": [
"a0d12c549fac7d4e7b06d2741085b4ef712bae13",
[]
]
@ -334614,7 +334679,7 @@
}
},
"pitch-detector.js": [
"595bde3120c7307244c1f4b70eeca3adceac1dd7",
"78f22ccd85760255056f1114cfb9ba1c25fcc60e",
[]
],
"track": {
@ -338829,7 +338894,7 @@
[]
],
"appmanifest.idl": [
"0d24849b9f7657aed65b8d1dd147cf7001e26599",
"926a4fc2022e71c28aa4a2ae3d1adc12104ee1ab",
[]
],
"audio-output.idl": [
@ -339305,7 +339370,7 @@
[]
],
"service-workers.idl": [
"c01fcab7f2d92491899907bc3c0505e8a4d4ba63",
"3d5e63a81204baa3099a2415be3a73d369aa31e3",
[]
],
"shape-detection-api.idl": [
@ -339337,7 +339402,7 @@
[]
],
"trusted-types.tentative.idl": [
"f2318d685676291a5ec85a1a0c3c408fa1a7f079",
"4e469c19b823bf3d452f480e086474e49741964a",
[]
],
"ua-client-hints.idl": [
@ -344725,7 +344790,7 @@
]
},
"idlharness.js": [
"25c193b55e5b76fff6dc180268357a11a27abc08",
"9a23e3a1da203309150e80ac820aa3df294ae3c3",
[]
],
"idlharness.js.headers": [
@ -359563,7 +359628,7 @@
[]
],
"RTCPeerConnection-helper.js": [
"07626bd0ccc39e93034beaf1f745bbc49a9438c1",
"cf31d2f0008c95ac1566f3c7e21fbeda0992d7e3",
[]
],
"RTCRtpCapabilities-helper.js": [
@ -390574,6 +390639,13 @@
{}
]
],
"contain-flexbox-outline.html": [
"39cf81688e0a294d542cf18a72ec1e808d7bc546",
[
null,
{}
]
],
"contain-size-grid-003.html": [
"44b736b1d6b62ec5c4fc0e6fb3314095df6a27f4",
[
@ -408443,7 +408515,7 @@
]
},
"appearance-cssom-001.html": [
"49769b359a53cf54bf232e42d567f88513abf853",
"2f0644093ea7b7d99581f2fae13d2203b961adf0",
[
null,
{}
@ -436498,6 +436570,13 @@
{}
]
],
"javascript-url-return-value-handling-dynamic.html": [
"0441d174cee07f278ef6df8d616c4d9ec212a857",
[
null,
{}
]
],
"javascript-url-return-value-handling.html": [
"621a8cbaecc787f4549cb54a7ac223cf79eb0b74",
[
@ -456645,7 +456724,7 @@
}
]
],
"reporting-popup-unafe-none-report-to.https.html": [
"reporting-popup-unsafe-none-report-to.https.html": [
"7ad6ec9ce7ab26b5f1bcca6ee6bbe6d6ad3a20f0",
[
null,
@ -461252,7 +461331,7 @@
]
],
"preserves-pitch.html": [
"9a86cbc210b296a131d60f26cb7288b870cf096b",
"1cf6c7639036edbc53c70ee71dc99edc6e224d58",
[
null,
{
@ -478255,7 +478334,7 @@
]
],
"MediaStreamTrack-getCapabilities.html": [
"c569283c34ef09541977938825abd1f01f6b386b",
"4e0c933bc1ceae2e98ec702c4044cdde056790e4",
[
null,
{
@ -478278,7 +478357,7 @@
]
],
"MediaStreamTrack-getSettings.html": [
"8fc2c82319517e4b9f60daa2866584505040ad2f",
"747eff8937d923b25c72e2ecd3c18967905f71a1",
[
null,
{
@ -511887,6 +511966,13 @@
{}
]
],
"TrustedTypePolicyFactory-blocking.html": [
"6ae71b69880a0313a549b586a04fa38b4be466e2",
[
null,
{}
]
],
"TrustedTypePolicyFactory-constants.tentative.html": [
"551084ca4b6e001ce49213a3d12491a4aedaf8f4",
[
@ -523521,7 +523607,7 @@
]
],
"RTCPeerConnection-setRemoteDescription-offer.html": [
"b4702446613255daec7db5325f64089a917fdee9",
"a50e969637294aec8eeafe682da5d258e2a90de5",
[
null,
{}
@ -523905,7 +523991,7 @@
]
],
"candidate-exchange.https.html": [
"532bc4d0d13d72170f9e521cbeda7d2e656e317f",
"82178953b6bbe3faccfd949817cf59e8d1dfa1ab",
[
null,
{

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -2,6 +2,3 @@
[listeners are called when <iframe> is resized]
expected: FAIL
[listeners are called correct number of times]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -21,3 +21,6 @@
[test the top of layer]
expected: FAIL
[test some point of the element: top left corner]
expected: FAIL

View file

@ -312,24 +312,21 @@
[fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN
[<iframe>: separate response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/html */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL

View file

@ -53,3 +53,6 @@
[combined text/javascript ]
expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -0,0 +1,19 @@
[javascript-url-return-value-handling-dynamic.html]
[Test javascript URL string return values in direct and indirect (target) frame contexts. 7]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 6]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 5]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 4]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 9]
expected: FAIL
[Test javascript URL string return values in direct and indirect (target) frame contexts. 8]
expected: FAIL

View file

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

View file

@ -14,6 +14,3 @@
[Host element with delegatesFocus should support autofocus]
expected: FAIL
[Non-HTMLElement should not support autofocus]
expected: FAIL

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html]
expected: CRASH
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_nonescaping-2.html]
type: testharness
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[module-static-import-delayed.html]
[document.write in an imported module]
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

@ -0,0 +1,5 @@
[017.html]
expected: TIMEOUT
[origin of the script that invoked the method, about:blank]
expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,2 +0,0 @@
[Worker-constructor.html]
expected: ERROR

View file

@ -0,0 +1,24 @@
<!doctype html>
<title>Test `contain: strict` to Flexbox does not crash</title>
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#contain-property">
<link rel="author" href="mailto:kojii@chromium.org">
<style>
body {
contain: strict;
display: flex;
}
html {
outline: 1px auto;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="target"></div>
<div id="log"></div>
<script>
test(() => {
document.body.offsetTop;
target.style.width = '100px';
document.body.offsetTop;
}, "Pass if no crash");
</script>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1058690">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="A percent inset resolves against the available size.">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; height: 100px; background: red;">
<span style="position: relative; top: 100%; left: 100%;">
<div style="width: 100px; height: 100px; background: green; position: relative; top: -100px; left: -100px;"></div>
</span>
</div>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1058690">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="A percent inset resolves against the available size.">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; height: 100px; background: red;">
<span style="position: relative; top: 100px; left: 100px;">
<div style="width: 100px; height: 100px; background: green; position: relative; top: -100%; left: -100%;"></div>
</span>
</div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1058690">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="A percent inset resolves against the available size.">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; height: 100px; background: red;">
<span style="position: relative; top: 100%; left: 100%;">
<span style="position: relative; top: -100px; left: -100px;">
<div style="width: 100px; height: 100px; background: green; position: fixed;"></div>
</span>
</span>
</div>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1058690">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="A percent inset resolves against the available size when it dynamically changes.">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="target" style="contain: paint; width: 100px; background: red; line-height: 0;">
<span style="position: relative; top: -100%;">
<span style="position: relative; top: 100px;">
<div style="position: fixed; width: 100px; height: 100px; background: green;"></div>
</span>
</span>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.height = '100px';
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="help" href="https://crbug.com/1058690">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="A percent inset resolves against the available size when it dynamically changes.">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div id="target" style="width: 100px; background: red; line-height: 0;">
<span style="position: relative; top: -100%;">
<span style="position: relative; top: 100px;">
<div style="position: absolute; width: 100px; height: 100px; background: green;"></div>
</span>
</span>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.height = '100px';
</script>

View file

@ -24,6 +24,7 @@
"textarea",
"textfield",
];
const initial_appearance = getComputedStyle(button).appearance;
function assert_style_for_prop(style, prop, value) {
if (prop === '-webkit-appearance') {
assert_equals(style.WebkitAppearance, value, 'style.WebkitAppearance (uppercase W)');
@ -198,7 +199,7 @@
button.style.setProperty(prop, invalidValue);
assert_style_for_prop(button.style, prop, "");
const style = getComputedStyle(button);
assert_style_for_prop(style, prop, "button");
assert_style_for_prop(style, prop, initial_appearance);
}, `${prop}: ${invalidValue} (invalid)`);
}
}

View file

@ -1,24 +1,26 @@
from wptserve.utils import isomorphic_decode
def main(request, response):
token = request.GET.first("token", None)
if "querystate" in request.GET:
token = request.GET.first(b"token", None)
if b"querystate" in request.GET:
from json import JSONEncoder
response.headers.set("Content-Type", "text/plain")
response.headers.set(b"Content-Type", b"text/plain")
return JSONEncoder().encode(request.server.stash.take(token))
content = request.GET.first("content", None)
tag = request.GET.first("tag", None)
date = request.GET.first("date", None)
expires = request.GET.first("expires", None)
vary = request.GET.first("vary", None)
cc = request.GET.first("cache_control", None)
redirect = request.GET.first("redirect", None)
inm = request.headers.get("If-None-Match", None)
ims = request.headers.get("If-Modified-Since", None)
pragma = request.headers.get("Pragma", None)
cache_control = request.headers.get("Cache-Control", None)
ignore = "ignore" in request.GET
content = request.GET.first(b"content", None)
tag = request.GET.first(b"tag", None)
date = request.GET.first(b"date", None)
expires = request.GET.first(b"expires", None)
vary = request.GET.first(b"vary", None)
cc = request.GET.first(b"cache_control", None)
redirect = request.GET.first(b"redirect", None)
inm = request.headers.get(b"If-None-Match", None)
ims = request.headers.get(b"If-Modified-Since", None)
pragma = request.headers.get(b"Pragma", None)
cache_control = request.headers.get(b"Cache-Control", None)
ignore = b"ignore" in request.GET
if tag:
tag = '"%s"' % tag
tag = b'"%s"' % tag
server_state = request.server.stash.take(token)
if not server_state:
@ -26,40 +28,40 @@ def main(request, response):
state = dict()
if not ignore:
if inm:
state["If-None-Match"] = inm
state[u"If-None-Match"] = isomorphic_decode(inm)
if ims:
state["If-Modified-Since"] = ims
state[u"If-Modified-Since"] = isomorphic_decode(ims)
if pragma:
state["Pragma"] = pragma
state[u"Pragma"] = isomorphic_decode(pragma)
if cache_control:
state["Cache-Control"] = cache_control
state[u"Cache-Control"] = isomorphic_decode(cache_control)
server_state.append(state)
request.server.stash.put(token, server_state)
if tag:
response.headers.set("ETag", '%s' % tag)
response.headers.set(b"ETag", b'%s' % tag)
elif date:
response.headers.set("Last-Modified", date)
response.headers.set(b"Last-Modified", date)
if expires:
response.headers.set("Expires", expires)
response.headers.set(b"Expires", expires)
if vary:
response.headers.set("Vary", vary)
response.headers.set(b"Vary", vary)
if cc:
response.headers.set("Cache-Control", cc)
response.headers.set(b"Cache-Control", cc)
# The only-if-cached redirect tests wants CORS to be okay, the other tests
# are all same-origin anyways and don't care.
response.headers.set("Access-Control-Allow-Origin", "*")
response.headers.set(b"Access-Control-Allow-Origin", b"*")
if redirect:
response.headers.set("Location", redirect)
response.status = (302, "Redirect")
return ""
response.headers.set(b"Location", redirect)
response.status = (302, b"Redirect")
return b""
elif ((inm is not None and inm == tag) or
(ims is not None and ims == date)):
response.status = (304, "Not Modified")
return ""
response.status = (304, b"Not Modified")
return b""
else:
response.status = (200, "OK")
response.headers.set("Content-Type", "text/plain")
response.status = (200, b"OK")
response.headers.set(b"Content-Type", b"text/plain")
return content

View file

@ -2,13 +2,13 @@ def main(request, response):
user = request.auth.username
password = request.auth.password
if user == "user" and password == "password":
return "Authentication done"
if user == b"user" and password == b"password":
return b"Authentication done"
realm = "test"
if "realm" in request.GET:
realm = request.GET.first("realm")
realm = b"test"
if b"realm" in request.GET:
realm = request.GET.first(b"realm")
return ((401, "Unauthorized"),
[("WWW-Authenticate", 'Basic realm="' + realm + '"')],
"Please login with credentials 'user' and 'password'")
return ((401, b"Unauthorized"),
[(b"WWW-Authenticate", b'Basic realm="' + realm + b'"')],
b"Please login with credentials 'user' and 'password'")

View file

@ -1,18 +1,18 @@
ETAG = '"123abc"'
CONTENT_TYPE = "text/plain"
CONTENT = "lorem ipsum dolor sit amet"
ETAG = b'"123abc"'
CONTENT_TYPE = b"text/plain"
CONTENT = b"lorem ipsum dolor sit amet"
def main(request, response):
# let caching kick in if possible (conditional GET)
etag = request.headers.get("If-None-Match", None)
etag = request.headers.get(b"If-None-Match", None)
if etag == ETAG:
response.headers.set("X-HTTP-STATUS", 304)
response.status = (304, "Not Modified")
return ""
response.headers.set(b"X-HTTP-STATUS", 304)
response.status = (304, b"Not Modified")
return b""
# cache miss, so respond with the actual content
response.status = (200, "OK")
response.headers.set("ETag", ETAG)
response.headers.set("Content-Type", CONTENT_TYPE)
response.status = (200, b"OK")
response.headers.set(b"ETag", ETAG)
response.headers.set(b"Content-Type", CONTENT_TYPE)
return CONTENT

View file

@ -1,6 +1,6 @@
def main(request, response):
token = request.GET.first("token")
token = request.GET.first(b"token")
if request.server.stash.take(token) is not None:
return "1"
return b"1"
else:
return "0"
return b"0"

View file

@ -1,24 +1,24 @@
def main(request, response):
headers = []
if "headers" in request.GET:
checked_headers = request.GET.first("headers").split("|")
if b"headers" in request.GET:
checked_headers = request.GET.first(b"headers").split(b"|")
for header in checked_headers:
if header in request.headers:
headers.append(("x-request-" + header, request.headers.get(header, "")))
headers.append((b"x-request-" + header, request.headers.get(header, b"")))
if "cors" in request.GET:
if "Origin" in request.headers:
headers.append(("Access-Control-Allow-Origin", request.headers.get("Origin", "")))
if b"cors" in request.GET:
if b"Origin" in request.headers:
headers.append((b"Access-Control-Allow-Origin", request.headers.get(b"Origin", b"")))
else:
headers.append(("Access-Control-Allow-Origin", "*"))
headers.append(("Access-Control-Allow-Credentials", "true"))
headers.append(("Access-Control-Allow-Methods", "GET, POST, HEAD"))
exposed_headers = ["x-request-" + header for header in checked_headers]
headers.append(("Access-Control-Expose-Headers", ", ".join(exposed_headers)))
if "allow_headers" in request.GET:
headers.append(("Access-Control-Allow-Headers", request.GET['allow_headers']))
headers.append((b"Access-Control-Allow-Origin", b"*"))
headers.append((b"Access-Control-Allow-Credentials", b"true"))
headers.append((b"Access-Control-Allow-Methods", b"GET, POST, HEAD"))
exposed_headers = [b"x-request-" + header for header in checked_headers]
headers.append((b"Access-Control-Expose-Headers", b", ".join(exposed_headers)))
if b"allow_headers" in request.GET:
headers.append((b"Access-Control-Allow-Headers", request.GET[b'allow_headers']))
else:
headers.append(("Access-Control-Allow-Headers", ", ".join(request.headers)))
headers.append((b"Access-Control-Allow-Headers", b", ".join(request.headers)))
headers.append(("content-type", "text/plain"))
return headers, ""
headers.append((b"content-type", b"text/plain"))
return headers, b""

View file

@ -1,16 +1,18 @@
from wptserve.utils import isomorphic_encode
def main(request, response):
headers = []
if "cors" in request.GET:
headers.append(("Access-Control-Allow-Origin", "*"))
headers.append(("Access-Control-Allow-Credentials", "true"))
headers.append(("Access-Control-Allow-Methods", "GET, POST, PUT, FOO"))
headers.append(("Access-Control-Allow-Headers", "x-test, x-foo"))
headers.append(("Access-Control-Expose-Headers", "x-request-method"))
if b"cors" in request.GET:
headers.append((b"Access-Control-Allow-Origin", b"*"))
headers.append((b"Access-Control-Allow-Credentials", b"true"))
headers.append((b"Access-Control-Allow-Methods", b"GET, POST, PUT, FOO"))
headers.append((b"Access-Control-Allow-Headers", b"x-test, x-foo"))
headers.append((b"Access-Control-Expose-Headers", b"x-request-method"))
headers.append(("x-request-method", request.method))
headers.append(("x-request-content-type", request.headers.get("Content-Type", "NO")))
headers.append(("x-request-content-length", request.headers.get("Content-Length", "NO")))
headers.append(("x-request-content-encoding", request.headers.get("Content-Encoding", "NO")))
headers.append(("x-request-content-language", request.headers.get("Content-Language", "NO")))
headers.append(("x-request-content-location", request.headers.get("Content-Location", "NO")))
headers.append((b"x-request-method", isomorphic_encode(request.method)))
headers.append((b"x-request-content-type", request.headers.get(b"Content-Type", b"NO")))
headers.append((b"x-request-content-length", request.headers.get(b"Content-Length", b"NO")))
headers.append((b"x-request-content-encoding", request.headers.get(b"Content-Encoding", b"NO")))
headers.append((b"x-request-content-language", request.headers.get(b"Content-Language", b"NO")))
headers.append((b"x-request-content-location", request.headers.get(b"Content-Location", b"NO")))
return headers, request.body

View file

@ -1,58 +1,58 @@
def main(request, response):
headers = [("Content-Type", "text/plain")]
stashed_data = {'control_request_headers': "", 'preflight': "0", 'preflight_referrer': ""}
headers = [(b"Content-Type", b"text/plain")]
stashed_data = {b'control_request_headers': b"", b'preflight': b"0", b'preflight_referrer': b""}
token = None
if "token" in request.GET:
token = request.GET.first("token")
if b"token" in request.GET:
token = request.GET.first(b"token")
if "origin" in request.GET:
for origin in request.GET['origin'].split(", "):
headers.append(("Access-Control-Allow-Origin", origin))
if b"origin" in request.GET:
for origin in request.GET[b'origin'].split(b", "):
headers.append((b"Access-Control-Allow-Origin", origin))
else:
headers.append(("Access-Control-Allow-Origin", "*"))
headers.append((b"Access-Control-Allow-Origin", b"*"))
if "clear-stash" in request.GET:
if b"clear-stash" in request.GET:
if request.server.stash.take(token) is not None:
return headers, "1"
return headers, b"1"
else:
return headers, "0"
return headers, b"0"
if "credentials" in request.GET:
headers.append(("Access-Control-Allow-Credentials", "true"))
if b"credentials" in request.GET:
headers.append((b"Access-Control-Allow-Credentials", b"true"))
if request.method == "OPTIONS":
if not "Access-Control-Request-Method" in request.headers:
response.set_error(400, "No Access-Control-Request-Method header")
return "ERROR: No access-control-request-method in preflight!"
if request.method == u"OPTIONS":
if not b"Access-Control-Request-Method" in request.headers:
response.set_error(400, u"No Access-Control-Request-Method header")
return b"ERROR: No access-control-request-method in preflight!"
if request.headers.get("Accept", "") != "*/*":
response.set_error(400, "Request does not have 'Accept: */*' header")
return "ERROR: Invalid access in preflight!"
if request.headers.get(b"Accept", b"") != b"*/*":
response.set_error(400, u"Request does not have 'Accept: */*' header")
return b"ERROR: Invalid access in preflight!"
if "control_request_headers" in request.GET:
stashed_data['control_request_headers'] = request.headers.get("Access-Control-Request-Headers", None)
if b"control_request_headers" in request.GET:
stashed_data[b'control_request_headers'] = request.headers.get(b"Access-Control-Request-Headers", None)
if "max_age" in request.GET:
headers.append(("Access-Control-Max-Age", request.GET['max_age']))
if b"max_age" in request.GET:
headers.append((b"Access-Control-Max-Age", request.GET[b'max_age']))
if "allow_headers" in request.GET:
headers.append(("Access-Control-Allow-Headers", request.GET['allow_headers']))
if b"allow_headers" in request.GET:
headers.append((b"Access-Control-Allow-Headers", request.GET[b'allow_headers']))
if "allow_methods" in request.GET:
headers.append(("Access-Control-Allow-Methods", request.GET['allow_methods']))
if b"allow_methods" in request.GET:
headers.append((b"Access-Control-Allow-Methods", request.GET[b'allow_methods']))
preflight_status = 200
if "preflight_status" in request.GET:
preflight_status = int(request.GET.first("preflight_status"))
if b"preflight_status" in request.GET:
preflight_status = int(request.GET.first(b"preflight_status"))
stashed_data['preflight'] = "1"
stashed_data['preflight_referrer'] = request.headers.get("Referer", "")
stashed_data['preflight_user_agent'] = request.headers.get("User-Agent", "")
stashed_data[b'preflight'] = b"1"
stashed_data[b'preflight_referrer'] = request.headers.get(b"Referer", b"")
stashed_data[b'preflight_user_agent'] = request.headers.get(b"User-Agent", b"")
if token:
request.server.stash.put(token, stashed_data)
return preflight_status, headers, ""
return preflight_status, headers, b""
if token:
@ -60,19 +60,19 @@ def main(request, response):
if data:
stashed_data = data
if "checkUserAgentHeaderInPreflight" in request.GET and request.headers.get("User-Agent") != stashed_data['preflight_user_agent']:
return 400, headers, "ERROR: No user-agent header in preflight"
if b"checkUserAgentHeaderInPreflight" in request.GET and request.headers.get(b"User-Agent") != stashed_data[b'preflight_user_agent']:
return 400, headers, b"ERROR: No user-agent header in preflight"
#use x-* headers for returning value to bodyless responses
headers.append(("Access-Control-Expose-Headers", "x-did-preflight, x-control-request-headers, x-referrer, x-preflight-referrer, x-origin"))
headers.append(("x-did-preflight", stashed_data['preflight']))
if stashed_data['control_request_headers'] != None:
headers.append(("x-control-request-headers", stashed_data['control_request_headers']))
headers.append(("x-preflight-referrer", stashed_data['preflight_referrer']))
headers.append(("x-referrer", request.headers.get("Referer", "")))
headers.append(("x-origin", request.headers.get("Origin", "")))
headers.append((b"Access-Control-Expose-Headers", b"x-did-preflight, x-control-request-headers, x-referrer, x-preflight-referrer, x-origin"))
headers.append((b"x-did-preflight", stashed_data[b'preflight']))
if stashed_data[b'control_request_headers'] != None:
headers.append((b"x-control-request-headers", stashed_data[b'control_request_headers']))
headers.append((b"x-preflight-referrer", stashed_data[b'preflight_referrer']))
headers.append((b"x-referrer", request.headers.get(b"Referer", b"")))
headers.append((b"x-origin", request.headers.get(b"Origin", b"")))
if token:
request.server.stash.put(token, stashed_data)
return headers, ""
return headers, b""

View file

@ -12,5 +12,5 @@ def main(request, response):
response.write_status_headers()
time.sleep(delay)
for i in xrange(count):
response.writer.write_content(u"TEST_TRICKLE\n")
response.writer.write_content(b"TEST_TRICKLE\n")
time.sleep(delay)

View file

@ -1,3 +1,3 @@
def main(request, response):
headers = [("Content-Encoding", "gzip")]
return headers, "not actually gzip"
headers = [(b"Content-Encoding", b"gzip")]
return headers, b"not actually gzip"

View file

@ -1,13 +1,15 @@
from wptserve.utils import isomorphic_encode
def main(request, response):
if request.method == "POST":
if request.method == u"POST":
response.add_required_headers = False
response.writer.write_status(302)
response.writer.write_header("Location", request.url)
response.writer.write_header(b"Location", isomorphic_encode(request.url))
response.writer.end_headers()
response.writer.write("")
elif request.method == "GET":
return ([("Content-Type", "text/plain")],
"OK")
response.writer.write(b"")
elif request.method == u"GET":
return ([(b"Content-Type", b"text/plain")],
b"OK")
else:
return ([("Content-Type", "text/plain")],
"FAIL")
return ([(b"Content-Type", b"text/plain")],
b"FAIL")

View file

@ -0,0 +1,51 @@
<!doctype html>
<meta charset=UTF-8>
<title>Test javascript URL string return values in direct and indirect (target) frame contexts.</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
const testInputs = [
[0x41],
[0x80,0xFF],
[0x80,0xFF,0x100],
[0xD83D,0xDE0D],
[0xDE0D,0x41]
];
testInputs.forEach(input => {
const javascriptURL = "javascript:[" + input + "].map(b => String.fromCharCode(b)).join('')",
output = input.map(b => String.fromCharCode(b)).join("");
async_test(t => {
const frame = document.createElement("iframe");
t.add_cleanup(() => frame.remove());
frame.src = javascriptURL;
t.step_timeout(() => {
assert_equals(frame.contentDocument.body.textContent, output);
assert_equals(frame.contentDocument.charset, document.charset);
t.done();
}, 200);
document.body.appendChild(frame);
});
});
testInputs.forEach(input => {
const javascriptURL = "javascript:[" + input + "].map(b => String.fromCharCode(b)).join('')",
output = input.map(b => String.fromCharCode(b)).join("");
async_test(t => {
const frame = document.createElement("iframe"),
href = document.createElement("a");
t.add_cleanup(() => { frame.remove(); href.remove(); });
frame.name = "hi" + input;
href.target = "hi" + input;
href.href = javascriptURL;
t.step_timeout(() => {
assert_equals(frame.contentDocument.body.textContent, output);
assert_equals(frame.contentDocument.charset, document.charset);
t.done();
}, 200)
document.body.appendChild(frame);
document.body.appendChild(href);
href.click();
});
});
</script>

View file

@ -4,11 +4,14 @@ window.AudioContext = window.AudioContext || window.webkitAudioContext;
var FFT_SIZE = 2048;
function getPitchDetector(media, t) {
var audioContext = new AudioContext();
t.add_cleanup(() => audioContext.close());
var audioContext;
var sourceNode;
var sourceNode = audioContext.createMediaElementSource(media);
function getPitchDetector(media) {
if(!audioContext) {
audioContext = new AudioContext();
sourceNode = audioContext.createMediaElementSource(media);
}
var analyser = audioContext.createAnalyser();
analyser.fftSize = FFT_SIZE;
@ -16,13 +19,20 @@ function getPitchDetector(media, t) {
sourceNode.connect(analyser);
analyser.connect(audioContext.destination);
return () => getPitch(analyser);
return {
ensureStart() { return audioContext.resume(); },
detect() { return getPitch(analyser); },
cleanup() {
sourceNode.disconnect();
analyser.disconnect();
},
};
}
function getPitch(analyser) {
// Returns the frequency value for the nth FFT bin.
var binConverter = (bin) =>
(analyser.context.sampleRate/2)*((bin)/(analyser.frequencyBinCount-1));
(audioContext.sampleRate/2)*((bin)/(analyser.frequencyBinCount-1));
var buf = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(buf);

View file

@ -15,8 +15,8 @@ function getPreservesPitch(audio) {
if ("mozPreservesPitch" in HTMLAudioElement.prototype) {
return audio.mozPreservesPitch;
}
if ("wekbitPreservesPitch" in HTMLAudioElement.prototype) {
return audio.wekbitPreservesPitch;
if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
return audio.webkitPreservesPitch;
}
return undefined;
}
@ -27,8 +27,8 @@ function setPreservesPitch(audio, value) {
audio.preservesPitch = value;
} else if ("mozPreservesPitch" in HTMLAudioElement.prototype) {
audio.mozPreservesPitch = value;
} else if ("wekbitPreservesPitch" in HTMLAudioElement.prototype) {
audio.wekbitPreservesPitch = value;
} else if ("webkitPreservesPitch" in HTMLAudioElement.prototype) {
audio.webkitPreservesPitch = value;
}
}
@ -37,21 +37,28 @@ test(function(t) {
}, "Test that preservesPitch is present and unprefixed.");
test(function(t) {
let audio = document.createElement('audio');
assert_true(getPreservesPitch(audio));
let defaultAudio = document.createElement('audio');
assert_true(getPreservesPitch(defaultAudio));
setPreservesPitch(audio, false);
assert_false(getPreservesPitch(audio));
}, "Test that presevesPitch is on by default");
setPreservesPitch(defaultAudio, false);
assert_false(getPreservesPitch(defaultAudio));
}, "Test that preservesPitch is on by default");
var audio;
function addTestCleanups(t, detector) {
t.add_cleanup(() => {
audio.pause();
audio.currentTime = 0;
});
t.add_cleanup(() => detector.cleanup());
}
function testPreservesPitch(preservesPitch, playbackRate, expectedPitch, description) {
promise_test(async t => {
let audio = document.createElement('audio');
var detector = getPitchDetector(audio, t);
// This file contains 5 seconds of a 440hz sine wave.
audio.src = "/media/sine440.mp3";
let detector = getPitchDetector(audio);
addTestCleanups(t, detector);
audio.playbackRate = playbackRate;
setPreservesPitch(audio, preservesPitch);
@ -66,13 +73,12 @@ function testPreservesPitch(preservesPitch, playbackRate, expectedPitch, descrip
});
}
await test_driver.bless("Play audio element", () => audio.play() )
// Wait until we have played some audio. Otherwise, the detector
// might return a pitch of 0Hz.
audio.play();
await waitUntil(0.25);
// Wait until we have at least played some audio. Otherwise, the
// detector might return a pitch of 0Hz.
await waitUntil(0.5);
var pitch = detector();
var pitch = detector.detect();
// 25Hz is larger than the margin we get from 48kHz and 44.1kHz
// audio being analyzed by a FFT of size 2048. If we get something
@ -89,6 +95,24 @@ function testPreservesPitch(preservesPitch, playbackRate, expectedPitch, descrip
var REFERENCE_PITCH = 440;
promise_test(async t => {
// Create the audio element only once, in order to lower the chances of
// tests timing out.
audio = document.createElement('audio');
// This file contains 5 seconds of a 440hz sine wave.
audio.src = "/media/sine440.mp3";
let detector = getPitchDetector(audio);
addTestCleanups(t, detector);
// The first time we run the test, we need to interact with the
// AudioContext and Audio element via user gestures.
await test_driver.bless("Play audio element", () => {
return Promise.all([audio.play(), detector.ensureStart()]);
});
}, "Setup Audio element and AudioContext")
testPreservesPitch(true, 1.0, REFERENCE_PITCH,
"The default playbackRate should not affect pitch")

View file

@ -8,7 +8,11 @@ dictionary WebAppManifest {
DOMString lang;
USVString name;
USVString short_name;
USVString description;
sequence<ManifestImageResource> icons;
sequence<ManifestImageResource> screenshots;
sequence<USVString> categories;
DOMString iarc_rating_id;
USVString start_url;
DisplayModeType display = "browser";
OrientationLockType orientation;

View file

@ -173,6 +173,7 @@ interface FetchEvent : ExtendableEvent {
readonly attribute DOMString clientId;
readonly attribute DOMString resultingClientId;
readonly attribute DOMString replacesClientId;
readonly attribute Promise<void> handled;
void respondWith(Promise<Response> r);
};
@ -183,6 +184,7 @@ dictionary FetchEventInit : ExtendableEventInit {
DOMString clientId = "";
DOMString resultingClientId = "";
DOMString replacesClientId = "";
Promise<void> handled;
};
[Exposed=ServiceWorker]

View file

@ -28,7 +28,7 @@ typedef [StringContext=TrustedScriptURL] USVString ScriptURLString;
[
Exposed=(Window, Worker),
SecureContext
] interface TrustedTypePolicyFactory {
] interface TrustedTypePolicyFactory : EventTarget {
TrustedTypePolicy createPolicy(DOMString policyName, optional TrustedTypePolicyOptions policyOptions = {});
// All the policy object names that have been created
};

View file

@ -159,14 +159,16 @@ function makeImageCaptureTest(hasPanTiltZoomPermissionGranted) {
assert_equals(capabilities.tilt.max, mockCapabilities.tilt.max);
assert_equals(capabilities.tilt.min, mockCapabilities.tilt.min);
assert_equals(capabilities.tilt.step, mockCapabilities.tilt.step);
} else if (ptzPermission === 'denied') {
assert_false('pan' in capabilities);
assert_false('tilt' in capabilities);
}
assert_true(capabilities.zoom instanceof MediaSettingsRange);
assert_equals(capabilities.zoom.max, mockCapabilities.zoom.max);
assert_equals(capabilities.zoom.min, mockCapabilities.zoom.min);
assert_equals(capabilities.zoom.step, mockCapabilities.zoom.step);
} else if (ptzPermission === 'denied') {
assert_false('pan' in capabilities);
assert_false('tilt' in capabilities);
assert_false('zoom' in capabilities);
}
assert_equals(capabilities.torch, mockCapabilities.supportsTorch,
'torch');

View file

@ -73,11 +73,12 @@ function makeImageCaptureTest(hasPanTiltZoomPermissionGranted) {
if (ptzPermission === 'granted') {
assert_equals(settings.pan, mockSettings.pan.current);
assert_equals(settings.tilt, mockSettings.tilt.current);
assert_equals(settings.zoom, mockSettings.zoom.current);
} else if (ptzPermission === 'denied') {
assert_false('pan' in settings);
assert_false('tilt' in settings);
assert_false('zoom' in settings);
}
assert_equals(settings.zoom, mockSettings.zoom.current);
assert_equals(settings.torch, mockSettings.torch, 'torch');
});

View file

@ -2534,6 +2534,10 @@ IdlInterface.prototype.do_member_operation_asserts = function(memberHolderObject
memberHolderObject[member.name].length,
minOverloadLength(ctors),
"property has wrong .length");
assert_equals(
memberHolderObject[member.name].name,
member.name,
"property has wrong .name");
// Make some suitable arguments
var args = member.arguments.map(function(arg) {

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="support/helper.sub.js"></script>
<meta http-equiv="Content-Security-Policy" content="trusted-types *">
<body>
<script>
test(t => {
event_listener = (e) => {
assert_equals(e.policyName, "default");
e.preventDefault(); // don't let this policy be created.
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
assert_throws_dom("NotAllowedError", () => trustedTypes.createPolicy("default", {}));
}, 'Block Trusted Type policy creation by event listener.');
test(t => {
let flag = false;
event_listener = (e) => {
assert_equals(e.policyName, "myPolicy");
flag = true;
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
trustedTypes.createPolicy("myPolicy", {});
assert_equals(flag, true);
}, 'Trusted Type policy creation.');
test(t => {
event_listener = (e) => {
if (e.policyName === "default")
e.preventDefault();
};
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
assert_throws_dom("NotAllowedError", () => trustedTypes.createPolicy("default", {}));
trustedTypes.createPolicy("newPolicy", {});
}, 'Block only default Trusted Type policy creation.');
test(t => {
event_listener = (e) => {
assert_unreached();
};
trustedTypes.createPolicy("test", {});
trustedTypes.addEventListener('beforecreatepolicy', event_listener, {once:true});
}, 'Policy creation called before addEventListener function will not reached the listener.');
</script>

View file

@ -232,6 +232,12 @@ async function waitForConnectionStateChange(pc, wantedStates) {
}
}
async function waitForIceGatheringState(pc, wantedStates) {
while (!wantedStates.includes(pc.iceGatheringState)) {
await waitUntilEvent(pc, 'icegatheringstatechange');
}
}
// Resolves when RTP packets have been received.
async function listenForSSRCs(t, receiver) {
while (true) {

View file

@ -325,4 +325,16 @@
await pc1.setRemoteDescription(answer);
}, 'repeated sRD(offer) works');
promise_test(async t => {
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
pc1.addTransceiver('video');
await exchangeOfferAnswer(pc1, pc2);
await waitForIceGatheringState(pc1, ['complete']);
await exchangeOfferAnswer(pc1, pc2);
await waitForIceStateChange(pc2, ['connected', 'completed']);
}, 'sRD(reoffer) with candidates and without trickle works');
</script>

View file

@ -10,23 +10,6 @@
<body>
<script>
function iceGatheringCompleteWaiter(pc) {
const waiter = new Promise((resolve) => {
const eventHandler = () => {
if (pc.iceGatheringState == 'complete') {
pc.removeEventListener('icegatheringstatechange', eventHandler, false);
resolve();
}
};
if (pc.iceGatheringState == 'complete') {
resolve();
} else {
pc.addEventListener('icegatheringstatechange', eventHandler, false);
}
});
return waiter;
}
class StateLogger {
constructor(source, eventname, field) {
source.addEventListener(eventname, event => {
@ -74,7 +57,7 @@ promise_test(async t => {
// Candidates from PC2 are not delivered to pc1, so pc1 will use
// peer-reflexive candidates.
await exchangeOfferAnswer(pc1, pc2);
const waiter = iceGatheringCompleteWaiter(pc1);
const waiter = waitForIceGatheringState(pc1, ['complete']);
await waiter;
for (const candidate of candidates) {
if (candidate) {
@ -105,7 +88,7 @@ promise_test(async t => {
// Candidates from pc1 are not delivered to pc2. so pc2 will use
// peer-reflexive candidates.
await exchangeOfferAnswer(pc1, pc2);
const waiter = iceGatheringCompleteWaiter(pc2);
const waiter = waitForIceGatheringState(pc2, ['complete']);
await waiter;
for (const candidate of candidates) {
if (candidate) {
@ -174,7 +157,7 @@ promise_test(async t => {
await Promise.all([pc1.setLocalDescription(offer),
pc2.setRemoteDescription(offer)]);
const answer = await pc2.createAnswer();
await iceGatheringCompleteWaiter(pc1);
await waitForIceGatheringState(pc1, ['complete']);
await pc2.setLocalDescription(answer).then(() => {
for (const candidate of pc1ToPc2Candidates) {
if (candidate) {
@ -182,7 +165,7 @@ promise_test(async t => {
}
}
});
await iceGatheringCompleteWaiter(pc2);
await waitForIceGatheringState(pc2, ['complete']);
pc1.setRemoteDescription(answer).then(async () => {
for (const candidate of pc2ToPc1Candidates) {
if (candidate) {