Update web-platform-tests to revision 6e9693d2690e0648fb9a1bd902af7cc078f28515

This commit is contained in:
WPT Sync Bot 2018-11-03 21:29:40 -04:00
parent 4ec7dedce1
commit 612038c4d6
56 changed files with 1374 additions and 477 deletions

View file

@ -251424,6 +251424,16 @@
{} {}
] ]
], ],
"css/css-easing/META.yml": [
[
{}
]
],
"css/css-easing/testcommon.js": [
[
{}
]
],
"css/css-env/META.yml": [ "css/css-env/META.yml": [
[ [
{} {}
@ -268389,16 +268399,6 @@
{} {}
] ]
], ],
"css/css-timing/META.yml": [
[
{}
]
],
"css/css-timing/testcommon.js": [
[
{}
]
],
"css/css-transforms/META.yml": [ "css/css-transforms/META.yml": [
[ [
{} {}
@ -317409,6 +317409,16 @@
{} {}
] ]
], ],
"webrtc-identity/META.yml": [
[
{}
]
],
"webrtc-identity/identity-helper.sub.js": [
[
{}
]
],
"webrtc-stats/META.yml": [ "webrtc-stats/META.yml": [
[ [
{} {}
@ -317484,12 +317494,12 @@
{} {}
] ]
], ],
"webrtc/identity-helper.sub.js": [ "webrtc/protocol/README.txt": [
[ [
{} {}
] ]
], ],
"webrtc/protocol/README.txt": [ "webrtc/resources/RTCCertificate-postMessage-iframe.html": [
[ [
{} {}
] ]
@ -335033,6 +335043,54 @@
{} {}
] ]
], ],
"css/CSS2/normal-flow/containing-block-percent-margin-bottom.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-margin-bottom.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-margin-left.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-margin-left.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-margin-right.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-margin-right.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-margin-top.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-margin-top.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-padding-bottom.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-padding-bottom.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-padding-left.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-padding-left.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-padding-right.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-padding-right.html",
{}
]
],
"css/CSS2/normal-flow/containing-block-percent-padding-top.html": [
[
"/css/CSS2/normal-flow/containing-block-percent-padding-top.html",
{}
]
],
"css/CSS2/normal-flow/unresolvable-max-height.html": [ "css/CSS2/normal-flow/unresolvable-max-height.html": [
[ [
"/css/CSS2/normal-flow/unresolvable-max-height.html", "/css/CSS2/normal-flow/unresolvable-max-height.html",
@ -336405,6 +336463,24 @@
{} {}
] ]
], ],
"css/css-easing/cubic-bezier-timing-functions-output.html": [
[
"/css/css-easing/cubic-bezier-timing-functions-output.html",
{}
]
],
"css/css-easing/step-timing-functions-output.html": [
[
"/css/css-easing/step-timing-functions-output.html",
{}
]
],
"css/css-easing/step-timing-functions-syntax.html": [
[
"/css/css-easing/step-timing-functions-syntax.html",
{}
]
],
"css/css-env/at-supports.tentative.html": [ "css/css-env/at-supports.tentative.html": [
[ [
"/css/css-env/at-supports.tentative.html", "/css/css-env/at-supports.tentative.html",
@ -342041,12 +342117,6 @@
{} {}
] ]
], ],
"css/css-timing/cubic-bezier-timing-functions-output.html": [
[
"/css/css-timing/cubic-bezier-timing-functions-output.html",
{}
]
],
"css/css-timing/frames-timing-functions-output.html": [ "css/css-timing/frames-timing-functions-output.html": [
[ [
"/css/css-timing/frames-timing-functions-output.html", "/css/css-timing/frames-timing-functions-output.html",
@ -342059,12 +342129,6 @@
{} {}
] ]
], ],
"css/css-timing/step-timing-functions-output.html": [
[
"/css/css-timing/step-timing-functions-output.html",
{}
]
],
"css/css-transforms/2d-rotate-js.html": [ "css/css-transforms/2d-rotate-js.html": [
[ [
"/css/css-transforms/2d-rotate-js.html", "/css/css-transforms/2d-rotate-js.html",
@ -408647,12 +408711,30 @@
{} {}
] ]
], ],
"webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html": [
[
"/webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html",
{}
]
],
"webrtc-identity/RTCPeerConnection-peerIdentity.html": [
[
"/webrtc-identity/RTCPeerConnection-peerIdentity.html",
{}
]
],
"webrtc-stats/idlharness.window.js": [ "webrtc-stats/idlharness.window.js": [
[ [
"/webrtc-stats/idlharness.window.html", "/webrtc-stats/idlharness.window.html",
{} {}
] ]
], ],
"webrtc/RTCCertificate-postMessage.html": [
[
"/webrtc/RTCCertificate-postMessage.html",
{}
]
],
"webrtc/RTCCertificate.html": [ "webrtc/RTCCertificate.html": [
[ [
"/webrtc/RTCCertificate.html", "/webrtc/RTCCertificate.html",
@ -408835,12 +408917,6 @@
{} {}
] ]
], ],
"webrtc/RTCPeerConnection-getIdentityAssertion.sub.html": [
[
"/webrtc/RTCPeerConnection-getIdentityAssertion.sub.html",
{}
]
],
"webrtc/RTCPeerConnection-getStats.https.html": [ "webrtc/RTCPeerConnection-getStats.https.html": [
[ [
"/webrtc/RTCPeerConnection-getStats.https.html", "/webrtc/RTCPeerConnection-getStats.https.html",
@ -408883,12 +408959,6 @@
{} {}
] ]
], ],
"webrtc/RTCPeerConnection-peerIdentity.html": [
[
"/webrtc/RTCPeerConnection-peerIdentity.html",
{}
]
],
"webrtc/RTCPeerConnection-remote-track-mute.https.html": [ "webrtc/RTCPeerConnection-remote-track-mute.https.html": [
[ [
"/webrtc/RTCPeerConnection-remote-track-mute.https.html", "/webrtc/RTCPeerConnection-remote-track-mute.https.html",
@ -409177,6 +409247,12 @@
{} {}
] ]
], ],
"webrtc/simplecall-no-ssrcs.https.html": [
[
"/webrtc/simplecall-no-ssrcs.https.html",
{}
]
],
"webrtc/simplecall.https.html": [ "webrtc/simplecall.https.html": [
[ [
"/webrtc/simplecall.https.html", "/webrtc/simplecall.https.html",
@ -441457,7 +441533,7 @@
"testharness" "testharness"
], ],
"IndexedDB/get-databases.any.js": [ "IndexedDB/get-databases.any.js": [
"f054e0fec2f0543eae7978303ae2a24858bdf245", "823cfce284b2beed49821825f2794849edda5753",
"testharness" "testharness"
], ],
"IndexedDB/globalscope-indexedDB-SameObject.html": [ "IndexedDB/globalscope-indexedDB-SameObject.html": [
@ -501892,6 +501968,38 @@
"b3a7420c630ad4c84e5593ad48f48f3072a88b98", "b3a7420c630ad4c84e5593ad48f48f3072a88b98",
"visual" "visual"
], ],
"css/CSS2/normal-flow/containing-block-percent-margin-bottom.html": [
"9dfc1963ac8a3bbccdd317e2b21613d08db21452",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-margin-left.html": [
"aa077d9ea83656debaca6009e86f0321b8c2872c",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-margin-right.html": [
"9ae84bd16ca2829ce0606cf69c17cbc76f22355e",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-margin-top.html": [
"7698f27240ebe2b8f6a98e8c5bfb495ec6b12461",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-padding-bottom.html": [
"5eea503005da0a38840fc4a708ea37870772feb6",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-padding-left.html": [
"0f793e715d67c20719b28b64ccf031acb5fe831a",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-padding-right.html": [
"28fd9590cdf5d30d5dce298ca52e331f64d836ff",
"testharness"
],
"css/CSS2/normal-flow/containing-block-percent-padding-top.html": [
"f30ace92e9def67f70bc1b6b6b4ad6e43f1561bd",
"testharness"
],
"css/CSS2/normal-flow/float-percentage-resolution-quirks-mode.html": [ "css/CSS2/normal-flow/float-percentage-resolution-quirks-mode.html": [
"a3794579f0ea242f9e7faaffcc16de5a3a69cf7c", "a3794579f0ea242f9e7faaffcc16de5a3a69cf7c",
"reftest" "reftest"
@ -531281,7 +531389,7 @@
"testharness" "testharness"
], ],
"css/css-animations/parsing/animation-timing-function-valid.html": [ "css/css-animations/parsing/animation-timing-function-valid.html": [
"63e2805485bfb1f8db9dfe3ad70979ade7e11cd4", "7ab823ea1da1535606ac4aad30fb21f423ba6703",
"testharness" "testharness"
], ],
"css/css-animations/pending-style-changes-001.html": [ "css/css-animations/pending-style-changes-001.html": [
@ -538852,6 +538960,26 @@
"08024b52d5fd82e18fc482888164cbe127239329", "08024b52d5fd82e18fc482888164cbe127239329",
"support" "support"
], ],
"css/css-easing/META.yml": [
"2c412b40f0f1b6059099682bc5c787310e8d2991",
"support"
],
"css/css-easing/cubic-bezier-timing-functions-output.html": [
"168f4cd907ec93d84bafcd11b00a7c78878569c8",
"testharness"
],
"css/css-easing/step-timing-functions-output.html": [
"978ac25df696dff029614733920a5155d8d96ecf",
"testharness"
],
"css/css-easing/step-timing-functions-syntax.html": [
"4e8b21e4413f8000ae584396355ed7df1c44a447",
"testharness"
],
"css/css-easing/testcommon.js": [
"9fd25b86507258b900911df892540bdb1ae17cd3",
"support"
],
"css/css-env/META.yml": [ "css/css-env/META.yml": [
"9d264a62281358545e6e842edb6a56105cb7dd5f", "9d264a62281358545e6e842edb6a56105cb7dd5f",
"support" "support"
@ -566680,14 +566808,6 @@
"e1a67bb1dc7d157d4bf57e1af40c039d67001923", "e1a67bb1dc7d157d4bf57e1af40c039d67001923",
"reftest" "reftest"
], ],
"css/css-timing/META.yml": [
"1ee250307b7043a0b1ac28af8e9e28413ab0d75b",
"support"
],
"css/css-timing/cubic-bezier-timing-functions-output.html": [
"5c2003b13944256e4ef2bf15a759aa534363da66",
"testharness"
],
"css/css-timing/frames-timing-functions-output.html": [ "css/css-timing/frames-timing-functions-output.html": [
"40e03286e71f7126bfbbdd50bc74e25c191a4d30", "40e03286e71f7126bfbbdd50bc74e25c191a4d30",
"testharness" "testharness"
@ -566696,14 +566816,6 @@
"1616bcffa740c20aa73d5af8a84fc4a435baef02", "1616bcffa740c20aa73d5af8a84fc4a435baef02",
"testharness" "testharness"
], ],
"css/css-timing/step-timing-functions-output.html": [
"9a2aa507c888ee303ee52df2e96c4b4c8ad282c9",
"testharness"
],
"css/css-timing/testcommon.js": [
"9fd25b86507258b900911df892540bdb1ae17cd3",
"support"
],
"css/css-transforms/2d-rotate-001.html": [ "css/css-transforms/2d-rotate-001.html": [
"3f28db8f4e3e17c8420e0af3a2d33d65766d557f", "3f28db8f4e3e17c8420e0af3a2d33d65766d557f",
"reftest" "reftest"
@ -572297,11 +572409,11 @@
"testharness" "testharness"
], ],
"css/css-transitions/parsing/transition-timing-function-invalid.html": [ "css/css-transitions/parsing/transition-timing-function-invalid.html": [
"936defa6cce5dd7b69bf9344c60add178de6589a", "00bd2131e0927ba38e633ad7be404b8ec26e51a9",
"testharness" "testharness"
], ],
"css/css-transitions/parsing/transition-timing-function-valid.html": [ "css/css-transitions/parsing/transition-timing-function-valid.html": [
"e11ef0002e43b65e06c8aec7dffab2fe7d48377f", "2e2c1827bfbef9d4cc58e32ec88da3c7fd614225",
"testharness" "testharness"
], ],
"css/css-transitions/properties-value-001.html": [ "css/css-transitions/properties-value-001.html": [
@ -572777,7 +572889,7 @@
"reftest" "reftest"
], ],
"css/css-transitions/transition-timing-function-001.html": [ "css/css-transitions/transition-timing-function-001.html": [
"75665450a1a8ea33b7ef3205755211099fd91490", "4c9598f3919b84dc79d7c92c76b74b7f950423aa",
"testharness" "testharness"
], ],
"css/css-transitions/transition-timing-function-002.html": [ "css/css-transitions/transition-timing-function-002.html": [
@ -625317,7 +625429,7 @@
"support" "support"
], ],
"interfaces/fullscreen.idl": [ "interfaces/fullscreen.idl": [
"87f1599750a6e72e8540865ee3a21cab88eac56b", "491aa7af13e6703023f723cfd6ef41cc6c0e6ace",
"support" "support"
], ],
"interfaces/gamepad.idl": [ "interfaces/gamepad.idl": [
@ -625453,7 +625565,7 @@
"support" "support"
], ],
"interfaces/payment-request.idl": [ "interfaces/payment-request.idl": [
"0795c03627da479992512c334e5b395a81c237dc", "baf9ee36db9c898e500609dcdaf152ccbfbc704a",
"support" "support"
], ],
"interfaces/performance-timeline.idl": [ "interfaces/performance-timeline.idl": [
@ -625965,7 +626077,7 @@
"support" "support"
], ],
"lint.whitelist": [ "lint.whitelist": [
"23f20555e8c30784cbf5ba87ae5ec6b81165b81f", "3de5698c229d7c8b7f32207030540283b9efec63",
"support" "support"
], ],
"longtask-timing/META.yml": [ "longtask-timing/META.yml": [
@ -637689,7 +637801,7 @@
"manual" "manual"
], ],
"payment-request/payment-response/retry-method-manual.https.html": [ "payment-request/payment-response/retry-method-manual.https.html": [
"82821a9a39c6c9ce6def2c076e39aa08f00921cc", "16ed15e54902b93485ee3be7a2635823e8763b06",
"manual" "manual"
], ],
"payment-request/payment-response/shippingAddress-attribute-manual.https.html": [ "payment-request/payment-response/shippingAddress-attribute-manual.https.html": [
@ -662677,7 +662789,7 @@
"support" "support"
], ],
"tools/wptrunner/requirements.txt": [ "tools/wptrunner/requirements.txt": [
"72672707d6f0eceacb8ab9859b32f10fd4633fce", "1fde996a78e8941341ea52ed5e19633bc5e6b179",
"support" "support"
], ],
"tools/wptrunner/requirements_chrome.txt": [ "tools/wptrunner/requirements_chrome.txt": [
@ -666369,7 +666481,7 @@
"testharness" "testharness"
], ],
"web-animations/timing-model/time-transformations/transformed-progress.html": [ "web-animations/timing-model/time-transformations/transformed-progress.html": [
"839ebe1093e5daf2bd2f309711c6174cb6a38a84", "960e333c09268f68d23ba2d0208202f8262ec3ef",
"testharness" "testharness"
], ],
"web-animations/timing-model/timelines/document-timelines.html": [ "web-animations/timing-model/timelines/document-timelines.html": [
@ -669096,6 +669208,22 @@
"5fb88073b169cfac1d8353e5e8416bdd46ceab0e", "5fb88073b169cfac1d8353e5e8416bdd46ceab0e",
"testharness" "testharness"
], ],
"webrtc-identity/META.yml": [
"900769b9d4334bb38d6413beea6a28235d8c927c",
"support"
],
"webrtc-identity/RTCPeerConnection-getIdentityAssertion.sub.html": [
"2bd860d901ded78c9635da65413ac63e7dbf4460",
"testharness"
],
"webrtc-identity/RTCPeerConnection-peerIdentity.html": [
"64ad212a5ba4e0c6bf5589f4cda3a4c7a508cdc2",
"testharness"
],
"webrtc-identity/identity-helper.sub.js": [
"90363662f742fbf1d31634030d2b470e08fe1421",
"support"
],
"webrtc-stats/META.yml": [ "webrtc-stats/META.yml": [
"489264f23d6e8c096652620e6e7732a94644353f", "489264f23d6e8c096652620e6e7732a94644353f",
"support" "support"
@ -669112,8 +669240,12 @@
"ea2846e97af01817f06343322efab3d941060f4c", "ea2846e97af01817f06343322efab3d941060f4c",
"support" "support"
], ],
"webrtc/RTCCertificate-postMessage.html": [
"5885f9fb1bbc3e97e5916d07e3df706316c170e8",
"testharness"
],
"webrtc/RTCCertificate.html": [ "webrtc/RTCCertificate.html": [
"e5f1749eb5bfbccbf769510acda806f2a5eb8dc3", "a33ba9ae5f2b201e663c5aa70d1984f0687c613a",
"testharness" "testharness"
], ],
"webrtc/RTCConfiguration-bundlePolicy.html": [ "webrtc/RTCConfiguration-bundlePolicy.html": [
@ -669177,7 +669309,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCIceCandidate-constructor.html": [ "webrtc/RTCIceCandidate-constructor.html": [
"974ed0c76cfafb788e865c0b1c71fa19007c55b9", "9842593a83c5330e0ed19bedac9f6c9908362c41",
"testharness" "testharness"
], ],
"webrtc/RTCIceTransport-extension-helper.js": [ "webrtc/RTCIceTransport-extension-helper.js": [
@ -669197,7 +669329,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-addIceCandidate.html": [ "webrtc/RTCPeerConnection-addIceCandidate.html": [
"5e321681336ece75202d9c469227d60da4ceee39", "1dd1350acd25ea865631c45f7345cb3d06822f3b",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-addTrack.https.html": [ "webrtc/RTCPeerConnection-addTrack.https.html": [
@ -669244,10 +669376,6 @@
"4fdbdb8dec46de549c077949ed946a7a310e9b74", "4fdbdb8dec46de549c077949ed946a7a310e9b74",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-getIdentityAssertion.sub.html": [
"2bd860d901ded78c9635da65413ac63e7dbf4460",
"testharness"
],
"webrtc/RTCPeerConnection-getStats.https.html": [ "webrtc/RTCPeerConnection-getStats.https.html": [
"247402b83be0a2655fa8d4ad43fa166b6459c587", "247402b83be0a2655fa8d4ad43fa166b6459c587",
"testharness" "testharness"
@ -669257,7 +669385,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-helper.js": [ "webrtc/RTCPeerConnection-helper.js": [
"b13e580998efce83c8bb158bce3d7747ec6f8bd9", "330ce1992d97a5d3fc825f882fcdaa3f1f4a95bf",
"support" "support"
], ],
"webrtc/RTCPeerConnection-iceConnectionState.html": [ "webrtc/RTCPeerConnection-iceConnectionState.html": [
@ -669280,10 +669408,6 @@
"10210129acd598fd959124fbe51462de8a1cdb0b", "10210129acd598fd959124fbe51462de8a1cdb0b",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-peerIdentity.html": [
"64ad212a5ba4e0c6bf5589f4cda3a4c7a508cdc2",
"testharness"
],
"webrtc/RTCPeerConnection-remote-track-mute.https.html": [ "webrtc/RTCPeerConnection-remote-track-mute.https.html": [
"56fe761425096e963589309b828a8a7f7d36a9be", "56fe761425096e963589309b828a8a7f7d36a9be",
"testharness" "testharness"
@ -669353,7 +669477,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnectionIceEvent-constructor.html": [ "webrtc/RTCPeerConnectionIceEvent-constructor.html": [
"07e9736441285536e0549c55b110a562b49276cc", "7de7fcaeb10ef209ece63ad346f668e1c634c4db",
"testharness" "testharness"
], ],
"webrtc/RTCQuicStream.https.html": [ "webrtc/RTCQuicStream.https.html": [
@ -669492,10 +669616,6 @@
"d49503e16d6c5de6f7ea991120e7fb2b53bbcfd5", "d49503e16d6c5de6f7ea991120e7fb2b53bbcfd5",
"testharness" "testharness"
], ],
"webrtc/identity-helper.sub.js": [
"90363662f742fbf1d31634030d2b470e08fe1421",
"support"
],
"webrtc/idlharness.https.window.js": [ "webrtc/idlharness.https.window.js": [
"3c57a022cabfbedcf4a015024ac88ecd3080faf6", "3c57a022cabfbedcf4a015024ac88ecd3080faf6",
"testharness" "testharness"
@ -669516,6 +669636,14 @@
"547856f2a271b5c349b529ec7f1fe1acb5a48ef0", "547856f2a271b5c349b529ec7f1fe1acb5a48ef0",
"testharness" "testharness"
], ],
"webrtc/resources/RTCCertificate-postMessage-iframe.html": [
"9e52ba0c888a8d500072c1669599d88f64cb22c3",
"support"
],
"webrtc/simplecall-no-ssrcs.https.html": [
"266b57663781115154f1ad8ddd2dd69143bc44b9",
"testharness"
],
"webrtc/simplecall.https.html": [ "webrtc/simplecall.https.html": [
"681c42d4cd855dcf53543a7add231d2665c381a9", "681c42d4cd855dcf53543a7add231d2665c381a9",
"testharness" "testharness"

View file

@ -1,4 +1,13 @@
[animation-timing-function-valid.html] [animation-timing-function-valid.html]
[e.style['animation-timing-function'\] = "steps(2, end)" should set the property value] [e.style['animation-timing-function'\] = "steps(2, jump-end)" should set the property value]
expected: FAIL
[e.style['animation-timing-function'\] = "steps(2, jump-both)" should set the property value]
expected: FAIL
[e.style['animation-timing-function'\] = "steps(2, jump-none)" should set the property value]
expected: FAIL
[e.style['animation-timing-function'\] = "steps(2, jump-start)" should set the property value]
expected: FAIL expected: FAIL

View file

@ -1,4 +1,13 @@
[transition-timing-function-valid.html] [transition-timing-function-valid.html]
[e.style['transition-timing-function'\] = "steps(2, end)" should set the property value] [e.style['transition-timing-function'\] = "steps(2, jump-both)" should set the property value]
expected: FAIL
[e.style['transition-timing-function'\] = "steps(2, jump-none)" should set the property value]
expected: FAIL
[e.style['transition-timing-function'\] = "steps(2, jump-start)" should set the property value]
expected: FAIL
[e.style['transition-timing-function'\] = "steps(2, jump-end)" should set the property value]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,13 @@
[transition-timing-function-001.html]
[parse 'steps(3, jump-both)']
expected: FAIL
[parse 'steps(3, jump-start)']
expected: FAIL
[parse 'steps(3, jump-end)']
expected: FAIL
[parse 'steps(3, jump-none)']
expected: FAIL

View file

@ -509,7 +509,7 @@
[single-byte-decoder.html?XMLHttpRequest] [single-byte-decoder.html?XMLHttpRequest]
expected: TIMEOUT expected: CRASH
[ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)] [ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)]
expected: FAIL expected: FAIL

View file

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

View file

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

View file

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

View file

@ -5,29 +5,11 @@
expected: TIMEOUT expected: TIMEOUT
[picture: source (max-width:500px) valid image, img valid image, resize to wide] [picture: source (max-width:500px) valid image, img valid image, resize to wide]
expected: FAIL expected: TIMEOUT
[picture: source (max-width:500px) valid image, img broken image, resize to narrow] [picture: source (max-width:500px) valid image, img broken image, resize to narrow]
expected: TIMEOUT expected: TIMEOUT
[picture: source (max-width:500px) valid image, img valid image, resize to narrow] [picture: source (max-width:500px) valid image, img valid image, resize to narrow]
expected: FAIL expected: TIMEOUT
[picture: source (max-width:500px) broken image, img valid image, resize to narrow]
expected: FAIL
[img (srcset 1 cand) valid image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to wide]
expected: FAIL
[img (srcset 1 cand) valid image, resize to narrow]
expected: FAIL
[picture: source (max-width:500px) valid image, img broken image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to narrow]
expected: FAIL

View file

@ -0,0 +1,52 @@
[parse-a-sizes-attribute-quirks-mode.html]
[<img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown &quot;general-enclosed&quot;) 1px"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (quirks mode)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (quirks mode)]
expected: FAIL

View file

@ -0,0 +1,52 @@
[parse-a-sizes-attribute-width-1000px.html]
[<img srcset="/images/green-1x1.png?e37a 50w, /images/green-16x16.png?e37a 51w" sizes="(min-width:0) min(1px, 100px)"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f49b 50w, /images/green-16x16.png?f49b 51w" sizes="(min-width:0) max(-200vw, 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e38b 50w, /images/green-16x16.png?e38b 51w" sizes="(min-width:max(-200vw, 0)) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w" sizes="(min-width:0) or (min-width:-1px) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e37b 50w, /images/green-16x16.png?e37b 51w" sizes="(min-width:0) max(-100px, 1px)"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e38a 50w, /images/green-16x16.png?e38a 51w" sizes="(min-width:min(0, 200vw)) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w" sizes="(min-width:0) or (unknown &quot;general-enclosed&quot;) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e36b 50w, /images/green-16x16.png?e36b 51w" sizes="min(-100px, 1px)"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f48b 50w, /images/green-16x16.png?f48b 51w" sizes="max(-200vw, 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f48a 50w, /images/green-16x16.png?f48a 51w" sizes="min(1px, 200vw"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w" sizes="(min-width:calc(0)) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w" sizes="(min-width:0) or (unknown-mf-name) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w" sizes="(min-width:0) or unknown-general-enclosed(foo) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w" sizes="(min-width:0) or (min-width:unknown-mf-value) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w" sizes="(min-width:0) or (unknown-general-enclosed !) 1px"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?e36a 50w, /images/green-16x16.png?e36a 51w" sizes="min(1px, 100px)"> ref sizes="1px" (width:1000px)]
expected: FAIL
[<img srcset="/images/green-1x1.png?f49a 50w, /images/green-16x16.png?f49a 51w" sizes="(min-width:0) min(1px, 200vw"> ref sizes="1px" (width:1000px)]
expected: FAIL

View file

@ -1,7 +0,0 @@
[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

@ -1,2 +0,0 @@
[script-onerror-insertion-point-2.html]
expected: TIMEOUT

View file

@ -9,3 +9,6 @@
[document.open should throw an InvalidStateError with XML document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)] [document.open should throw an InvalidStateError with XML document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)]
expected: FAIL expected: FAIL
[document.open should throw an InvalidStateError with XML document even when there is an active parser executing script]
expected: FAIL

View file

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

View file

@ -1,4 +1,4 @@
[limited-quirks.html] [no-quirks.html]
[top: -\\31 .5] [top: -\\31 .5]
expected: FAIL expected: FAIL

View file

@ -14,6 +14,12 @@
[response.formData() with input: &&&a=b&&&&c=d&] [response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL 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] [urlencoded-parser.any.worker.html]
[request.formData() with input: a&b&c] [request.formData() with input: a&b&c]
@ -22,12 +28,15 @@
[request.formData() with input: a=b&c=d&] [request.formData() with input: a=b&c=d&]
expected: FAIL expected: FAIL
[request.formData() with input: a=b&c=d]
expected: FAIL
[request.formData() with input: &&&a=b&&&&c=d&] [request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL expected: FAIL
[response.formData() with input: a=b&c=d] [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]
expected: FAIL expected: FAIL

View file

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

View file

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

View file

@ -1,20 +1,29 @@
// META: script=support-promises.js // META: script=support-promises.js
promise_test(async testCase => { promise_test(async testCase => {
// Delete any databases that may not have been cleaned up after assert_true(indexedDB.databases() instanceof Promise,
// previous test runs. "databases() should return a promise.");
}, "Ensure that databases() returns a promise.");
promise_test(async testCase => {
// Delete any databases that may not have been cleaned up after previous test
// runs.
await deleteAllDatabases(testCase); await deleteAllDatabases(testCase);
const db_name = "TestDatabase"; const db_name = "TestDatabase";
const db = await createNamedDatabase(testCase, db_name, ()=>{}); const db = await createNamedDatabase(testCase, db_name, ()=>{});
const databases_promise = await indexedDB.databases(); const databases_result = await indexedDB.databases();
const expected_result = [ db.close();
{"name": db_name, "version": 1}, const expected_result = {"name": db_name, "version": 1};
]; assert_equals(
assert_object_equals( databases_result.length,
databases_promise, 1,
expected_result, "The result of databases() should contain one result per database.");
"Call to databases() did not retrieve the single expected result."); assert_true(
databases_result[0].name === expected_result.name
&& databases_result[0].version === expected_result.version,
"The result of databases() should be a sequence of the correct names "
+ "and versions of all databases for the origin.");
}, "Enumerate one database."); }, "Enumerate one database.");
promise_test(async testCase => { promise_test(async testCase => {
@ -28,35 +37,81 @@ promise_test(async testCase => {
const db1 = await createNamedDatabase(testCase, db_name1, ()=>{}); const db1 = await createNamedDatabase(testCase, db_name1, ()=>{});
const db2 = await createNamedDatabase(testCase, db_name2, ()=>{}); const db2 = await createNamedDatabase(testCase, db_name2, ()=>{});
const db3 = await createNamedDatabase(testCase, db_name3, ()=>{}); const db3 = await createNamedDatabase(testCase, db_name3, ()=>{});
const databases_promise = await indexedDB.databases(); db1.close();
db2.close();
db3.close();
const version_promise =
await migrateNamedDatabase(testCase, db_name2, 2, () => {});
const databases_result = await indexedDB.databases();
const expected_result = [ const expected_result = [
{"name": db_name1, "version": 1}, {"name": db_name1, "version": 1},
{"name": db_name2, "version": 1}, {"name": db_name2, "version": 2},
{"name": db_name3, "version": 1}, {"name": db_name3, "version": 1},
]; ];
assert_object_equals( assert_equals(
databases_promise, databases_result.length,
expected_result, expected_result.length,
"Call to databases() did not retrieve the multiple expected results"); "The result of databases() should contain one result per database.");
for ( let i = 0; i < expected_result.length; i += 1 ) {
result = expected_result[i];
assert_true(
databases_result.some(
e => e.name === result.name && e.version === result.version),
"The result of databases() should be a sequence of the correct names "
+ "and versions of all databases for the origin.");
}
}, "Enumerate multiple databases."); }, "Enumerate multiple databases.");
promise_test(async testCase => { promise_test(async testCase => {
// Add some databases and close their connections. // Add some databases and close their connections.
const db1 = await createNamedDatabase(testCase, "DB1", ()=>{}); const db1 = await createNamedDatabase(testCase, "DB1", () => {});
const db2 = await createNamedDatabase(testCase, "DB2", ()=>{}); const db2 = await createNamedDatabase(testCase, "DB2", () => {});
db1.onversionchange = () => { db1.close() }; db1.close();
db2.onversionchange = () => { db2.close() }; db2.close();
// Delete any databases that may not have been cleaned up after previous test // Delete any databases that may not have been cleaned up after previous test
// runs as well as the two databases made above. // runs as well as the two databases made above.
await deleteAllDatabases(testCase); await deleteAllDatabases(testCase);
// Make sure the databases are no longer returned. // Make sure the databases are no longer returned.
const databases_promise = await indexedDB.databases(); const databases_result = await indexedDB.databases();
assert_object_equals( assert_equals(
databases_promise, databases_result.length,
[], 0,
"Call to databases() found database it should not have.") "The result of databases() should be an empty sequence for the case of "
+ "no databases for the origin.");
}, "Make sure an empty list is returned for the case of no databases."); }, "Make sure an empty list is returned for the case of no databases.");
done(); promise_test(async testCase => {
// Delete any databases that may not have been cleaned up after previous test
// runs as well as the two databases made above.
await deleteAllDatabases(testCase);
const db1 = await createNamedDatabase(testCase, "DB1", ()=>{});
const db2 = await createNamedDatabase(testCase, "DB2", async () => {
const databases_result1 = await indexedDB.databases();
assert_equals(
databases_result1.length,
1,
"The result of databases() should be only those databases which have "
+ "been created at the time of calling, regardless of versionchange "
+ "transactions currently running.");
});
db1.close();
db2.close();
const databases_result2 = await indexedDB.databases();
assert_equals(
databases_result2.length,
2,
"The result of databases() should include all databases which have "
+ "been created at the time of calling.");
await migrateNamedDatabase(testCase, "DB2", 2, async () => {
const databases_result3 = await indexedDB.databases();
assert_true(
databases_result3[0].version === 1
&& databases_result3[1].version === 1,
"The result of databases() should contain the versions of databases "
+ "at the time of calling, regardless of versionchange transactions "
+ "currently running.");
});
}, "Ensure that databases() doesn't pick up changes that haven't commited.");

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-margin-bottom">
<style>
#container { overflow:hidden; background:blue; }
#container > div { margin-bottom:50%; height:50px; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:456px;" data-expected-width="100" data-expected-height="100">
<div></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "100px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-margin-left">
<style>
#container > div { margin-left:50%; height:100px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:456px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "200px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-margin-right">
<style>
#container > div { margin-right:50%; height:100px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:456px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "200px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-margin-top">
<style>
#container { overflow:hidden; background:blue; }
#container > div { margin-top:50%; height:50px; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:456px;" data-expected-width="100" data-expected-height="100">
<div></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "100px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-padding-bottom">
<style>
#container > div { padding-bottom:10%; width:100px; height:50px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:123px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "500px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-padding-left">
<style>
#container > div { padding-left:10%; width:50px; height:100px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:123px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "500px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-padding-right">
<style>
#container > div { padding-right:10%; width:50px; height:100px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:123px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "500px";
checkLayout("#container");
</script>

View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/CSS22/box.html#propdef-padding-top">
<style>
#container > div { padding-top:10%; width:100px; height:50px; background:blue; }
</style>
<p>There should be a blue square below.</p>
<div id="container" style="width:123px;">
<div data-expected-width="100" data-expected-height="100"></div>
</div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<script>
document.body.offsetTop;
document.getElementById("container").style.width = "500px";
checkLayout("#container");
</script>

View file

@ -23,7 +23,11 @@ test_valid_value("animation-timing-function", "cubic-bezier(0, 0.7, 1, 1.3)");
test_valid_value("animation-timing-function", "steps(4, start)"); test_valid_value("animation-timing-function", "steps(4, start)");
test_valid_value("animation-timing-function", "steps(2, end)"); test_valid_value("animation-timing-function", "steps(2, end)", "steps(2)");
test_valid_value("animation-timing-function", "steps(2, jump-start)");
test_valid_value("animation-timing-function", "steps(2, jump-end)", "steps(2)");
test_valid_value("animation-timing-function", "steps(2, jump-both)");
test_valid_value("animation-timing-function", "steps(2, jump-none)");
test_valid_value("animation-timing-function", "linear, ease, linear"); test_valid_value("animation-timing-function", "linear, ease, linear");
</script> </script>

View file

@ -1,4 +1,4 @@
spec: https://drafts.csswg.org/css-timing/ spec: https://drafts.csswg.org/css-easing/
suggested_reviewers: suggested_reviewers:
- birtles - birtles
- BorisChiou - BorisChiou

View file

@ -4,7 +4,7 @@
content="This test checks the output of Cubic Bézier functions" /> content="This test checks the output of Cubic Bézier functions" />
<title>Tests for the output of Cubic Bézier timing functions</title> <title>Tests for the output of Cubic Bézier timing functions</title>
<link rel="help" <link rel="help"
href="https://drafts.csswg.org/css-timing/#cubic-bezier-timing-functions"> href="https://drafts.csswg.org/css-easing/#cubic-bezier-timing-functions">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="testcommon.js"></script> <script src="testcommon.js"></script>

View file

@ -0,0 +1,318 @@
<!DOCTYPE html>
<meta charset=utf-8>
<meta name="assert"
content="This test checks the output of step timing functions" />
<title>Tests for the output of step timing functions</title>
<link rel="help"
href="https://drafts.csswg.org/css-easing/#step-timing-functions">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="testcommon.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values greater than 1 (but always less than 2)
// in (0.23368794, 1)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 3, 1, 3)' });
// The bezier function produces values:
// Input -> Output
// 0.0 0.0
// 0.114 ~ 0.245 1.5~2.0, so current step is 2, jumps is 1 => 2.0
// 0.245 ~ 0.6 2.0~2.4, so current step is 3, jumps is 1 => 3.0
// 0.6 ~ 0.882 2.4~2.0, so current step is 3, jumps is 1 => 3.0
// 0.882 ~ 0.976 2.0~1.5, so current step is 2, jumps is 1 => 2.0
// 1.0 1.0
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 114;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '300px');
anim.currentTime = 900;
assert_equals(getComputedStyle(target).left, '200px');
}, 'step-start easing with input progress greater than 2');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -1)
// in (0, 0.766312060)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 750;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress less than 0');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -2, 1, -2)' });
// The bezier function produces values less than -1 (but always greater than
// -2) in the range (~0.118, ~0.755)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 100;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '-100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress less than -1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values greater than 1 (but always less than 2)
// in (0.23368794, 1)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 3, 1, 3)' });
// The bezier function produces values:
// Input -> Output
// 0.0 0.0
// 0.114 ~ 0.245 1.5~2.0, so current step is 1, jumps is 1 => 1.0
// 0.245 ~ 0.6 2.0~2.4, so current step is 2, jumps is 1 => 2.0
// 0.6 ~ 0.882 2.4~2.0, so current step is 2, jumps is 1 => 2.0
// 0.882 ~ 0.976 2.0~1.5, so current step is 1, jumps is 1 => 1.0
// 1.0 1.0
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 114;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 900;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress greater than 2');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -1)
// in (0, 0.766312060)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 750;
assert_equals(getComputedStyle(target).left, '-100px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress less than 0');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(1, jump-both)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values greater than 1 (but always less than 2)
// in (0.23368794, 1)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '50px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '50px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'steps(1, jump-both) easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(1, jump-both)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 3, 1, 3)' });
// The bezier function produces values:
// Input -> Output
// 0.0 0.0, so current step is 1, jumps is 2 => 0.5
// 0.114 ~ 0.245 1.5~2.0, so current step is 2, jumps is 2 => 1.0
// 0.245 ~ 0.6 2.0~2.4, so current step is 3, jumps is 2 => 1.5
// 0.6 ~ 0.882 2.4~2.0, so current step is 3, jumps is 2 => 1.5
// 0.882 ~ 0.976 2.0~1.5, so current step is 2, jumps is 2 => 1.0
// 1.0 1.0
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '50px');
anim.currentTime = 114;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '150px');
anim.currentTime = 900;
assert_equals(getComputedStyle(target).left, '100px');
}, 'steps(1, jump-both) easing with input progress greater than 2');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(1, jump-both)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -0.5)
// in (0, 0.766312060).
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '50px');
anim.currentTime = 750;
// current step is 0, jumps is 2.
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '50px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'steps(1, jump-both) easing with input progress less than 0');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(2, jump-none)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values between 0.5 and 1 in
// (~0.0442, 0.23368), and values between 1 and 2 in (0.23368794, 1).
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 45;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'steps(2, jump-none) easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(2, jump-none)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 3, 1, 3)' });
// The bezier function produces values:
// Input -> Output
// 0.0 0.0, so current step is 0, jumps is 1 => 0.0
// 0.114 ~ 0.245 1.5~2.0, so current step is 3, jumps is 1 => 3.0
// 0.245 ~ 0.6 2.0~2.4, so current step is 4, jumps is 1 => 4.0
// 0.6 ~ 0.882 2.4~2.0, so current step is 4, jumps is 1 => 4.0
// 0.882 ~ 0.976 2.0~1.5, so current step is 3, jumps is 1 => 3.0
// 1.0 1.0
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 114;
assert_equals(getComputedStyle(target).left, '300px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '400px');
anim.currentTime = 900;
assert_equals(getComputedStyle(target).left, '300px');
}, 'steps(2, jump-none) easing with input progress greater than 2');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'steps(2, jump-none)' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -0.5)
// in (0, 0.766312060).
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 750;
// current step is -1, jumps is 1.
assert_equals(getComputedStyle(target).left, '-100px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'steps(2, jump-none) easing with input progress less than 0');
</script>
</body>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset=utf-8>
<meta name="assert"
content="This test checks the syntax output of step timing functions" />
<title>Step timing function syntax tests</title>
<link rel="help"
href="https://drafts.csswg.org/css-easing-1/#step-timing-functions">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="testcommon.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<body>
<div id="log"></div>
<script>
"use strict";
test_valid_value("animation-timing-function", "step-start", "steps(1, start)");
test_valid_value("animation-timing-function", "step-end", "steps(1)");
test_valid_value("animation-timing-function", "steps(1, start)");
test_valid_value("animation-timing-function", "steps(1, end)", "steps(1)");
test_valid_value("animation-timing-function", "steps(1, jump-start)");
test_valid_value("animation-timing-function", "steps(1, jump-end)", "steps(1)");
test_valid_value("animation-timing-function", "steps(1, jump-both)");
test_valid_value("animation-timing-function", "steps(2, jump-none)");
test_invalid_value("animation-timing-function", "steps(0, start)");
test_invalid_value("animation-timing-function", "steps(0, end)");
test_invalid_value("animation-timing-function", "steps(0, jump-start)");
test_invalid_value("animation-timing-function", "steps(0, jump-end)");
test_invalid_value("animation-timing-function", "steps(0, jump-both)");
test_invalid_value("animation-timing-function", "steps(1, jump-none)");
</script>
</body>

View file

@ -1,141 +0,0 @@
<!DOCTYPE html>
<meta charset=utf-8>
<meta name="assert"
content="This test checks the output of step timing functions" />
<title>Tests for the output of step timing functions</title>
<link rel="help"
href="https://drafts.csswg.org/css-timing/#step-timing-functions">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="testcommon.js"></script>
<body>
<div id="log"></div>
<script>
'use strict';
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values greater than 1 (but always less than 2)
// in (0.23368794, 1)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 1.5, 1, 1.5)' });
// The bezier function produces values greater than 1 (but always less than 2)
// in (0.23368794, 1)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 230;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 250;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress greater than 1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, 3, 1, 3)' });
// The bezier function produces values greater than 2 (but always less than 3)
// in the range (~0.245, ~0.882)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '200px');
anim.currentTime = 900;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress greater than 2');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -1)
// in (0, 0.766312060)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 750;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress less than 0');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-start' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -2, 1, -2)' });
// The bezier function produces values less than -1 (but always greater than
// -2) in the range (~0.118, ~0.755)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '100px');
anim.currentTime = 100;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 500;
assert_equals(getComputedStyle(target).left, '-100px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-start easing with input progress less than -1');
test(function(t) {
var target = createDiv(t);
target.style.position = 'absolute';
var anim = target.animate([ { left: '0px', easing: 'step-end' },
{ left: '100px' } ],
{ duration: 1000,
fill: 'forwards',
easing: 'cubic-bezier(0, -0.5, 1, -0.5)' });
// The bezier function produces negative values (but always greater than -1)
// in (0, 0.766312060)
anim.currentTime = 0;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 750;
assert_equals(getComputedStyle(target).left, '-100px');
anim.currentTime = 800;
assert_equals(getComputedStyle(target).left, '0px');
anim.currentTime = 1000;
assert_equals(getComputedStyle(target).left, '100px');
}, 'step-end easing with input progress less than 0');
</script>
</body>

View file

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>CSS Animations: parsing transition-timing-function with invalid values</title> <title>CSS Animations: parsing transition-timing-function with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function"> <link rel="help" href="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function">
<link rel="help" href="https://drafts.csswg.org/css-timing-1/#typedef-timing-function"> <link rel="help" href="https://drafts.csswg.org/css-easing-1/#typedef-timing-function">
<meta name="assert" content="transition-timing-function supports only the grammar '<timing-function> #'."> <meta name="assert" content="transition-timing-function supports only the grammar '<timing-function> #'.">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>

View file

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>CSS Transitions: parsing transition-timing-function with valid values</title> <title>CSS Transitions: parsing transition-timing-function with valid values</title>
<link rel="help" href="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function"> <link rel="help" href="https://drafts.csswg.org/css-transitions/#propdef-transition-timing-function">
<link rel="help" href="https://drafts.csswg.org/css-timing-1/#typedef-timing-function"> <link rel="help" href="https://drafts.csswg.org/css-easing-1/#typedef-timing-function">
<meta name="assert" content="transition-timing-function supports the full grammar '<timing-function> #'."> <meta name="assert" content="transition-timing-function supports the full grammar '<timing-function> #'.">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
@ -23,7 +23,11 @@ test_valid_value("transition-timing-function", "cubic-bezier(0, -2, 1, 3)");
test_valid_value("transition-timing-function", "cubic-bezier(0, 0.7, 1, 1.3)"); test_valid_value("transition-timing-function", "cubic-bezier(0, 0.7, 1, 1.3)");
test_valid_value("transition-timing-function", "steps(4, start)"); test_valid_value("transition-timing-function", "steps(4, start)");
test_valid_value("transition-timing-function", "steps(2, end)"); test_valid_value("transition-timing-function", "steps(2, end)", "steps(2)");
test_valid_value("transition-timing-function", "steps(2, jump-start)");
test_valid_value("transition-timing-function", "steps(2, jump-end)", "steps(2)");
test_valid_value("transition-timing-function", "steps(2, jump-both)");
test_valid_value("transition-timing-function", "steps(2, jump-none)");
test_valid_value("transition-timing-function", "linear, ease, linear"); test_valid_value("transition-timing-function", "linear, ease, linear");
</script> </script>

View file

@ -42,12 +42,20 @@
'steps(3, start)': 'steps(3, start)', 'steps(3, start)': 'steps(3, start)',
'steps(3, end)': 'steps(3)', 'steps(3, end)': 'steps(3)',
'steps(3)': 'steps(3)', 'steps(3)': 'steps(3)',
'steps(3, jump-start)': 'steps(3, jump-start)',
'steps(3, jump-end)': 'steps(3)',
'steps(3, jump-both)': 'steps(3, jump-both)',
'steps(3, jump-none)': 'steps(3, jump-none)',
// invalid // invalid
'cubic-bezier(foobar)': defaultValue, 'cubic-bezier(foobar)': defaultValue,
'steps(foobar)': defaultValue, 'steps(foobar)': defaultValue,
'steps(3.3, end)': defaultValue, 'steps(3.3, end)': defaultValue,
'steps(3, top)': defaultValue, 'steps(3, top)': defaultValue,
'steps(-3, top)': defaultValue, 'steps(-3, top)': defaultValue,
'steps(0, jump-start)': defaultValue,
'steps(0, jump-end)': defaultValue,
'steps(0, jump-both)': defaultValue,
'steps(1, jump-none)': defaultValue,
// Both x values must be in the range [0, 1] // Both x values must be in the range [0, 1]
'cubic-bezier(-0.1, -0.2, -0.3, -0.4)': defaultValue, 'cubic-bezier(-0.1, -0.2, -0.3, -0.4)': defaultValue,
'cubic-bezier(1.1, 1.2, 1.3, 1.4)': defaultValue 'cubic-bezier(1.1, 1.2, 1.3, 1.4)': defaultValue

View file

@ -30,6 +30,6 @@ partial interface Document {
attribute EventHandler onfullscreenerror; attribute EventHandler onfullscreenerror;
}; };
partial interface DocumentOrShadowRoot { partial interface mixin DocumentOrShadowRoot {
[LenientSetter] readonly attribute Element? fullscreenElement; [LenientSetter] readonly attribute Element? fullscreenElement;
}; };

View file

@ -153,7 +153,7 @@ interface PaymentResponse : EventTarget {
[NewObject] [NewObject]
Promise<void> complete(optional PaymentComplete result = "unknown"); Promise<void> complete(optional PaymentComplete result = "unknown");
[NewObject] [NewObject]
Promise<void> retry(PaymentValidationErrors errorFields); Promise<void> retry(optional PaymentValidationErrors errorFields);
attribute EventHandler onpayerdetailchange; attribute EventHandler onpayerdetailchange;
}; };

View file

@ -760,7 +760,7 @@ MISSING-LINK: css/css-scroll-anchoring/position-change-heuristic.html
MISSING-LINK: css/css-scroll-anchoring/start-edge-in-block-layout-direction.html MISSING-LINK: css/css-scroll-anchoring/start-edge-in-block-layout-direction.html
MISSING-LINK: css/css-scroll-anchoring/subtree-exclusion.html MISSING-LINK: css/css-scroll-anchoring/subtree-exclusion.html
MISSING-LINK: css/css-scroll-anchoring/wrapped-text.html MISSING-LINK: css/css-scroll-anchoring/wrapped-text.html
SUPPORT-WRONG-DIR: css/css-timing/testcommon.js SUPPORT-WRONG-DIR: css/css-easing/testcommon.js
MISSING-LINK: css/css-typed-om/CSSMatrixComponent-DOMMatrix-mutable.html MISSING-LINK: css/css-typed-om/CSSMatrixComponent-DOMMatrix-mutable.html
MISSING-LINK: css/css-typed-om/declared-styleMap-accepts-inherit.html MISSING-LINK: css/css-typed-om/declared-styleMap-accepts-inherit.html
SUPPORT-WRONG-DIR: css/cssom/stylesheet-same-origin.css SUPPORT-WRONG-DIR: css/cssom/stylesheet-same-origin.css

View file

@ -28,7 +28,7 @@ function checkCompletedCantRetry(button) {
return promise_rejects( return promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
response.retry({}), response.retry(),
"response.[[complete]] is true, so rejects with InvalidStateError." "response.[[complete]] is true, so rejects with InvalidStateError."
); );
}, button.textContent.trim()); }, button.textContent.trim());
@ -38,11 +38,11 @@ function repeatedCallsToRetry(button) {
button.disabled = true; button.disabled = true;
promise_test(async t => { promise_test(async t => {
const { response } = await getPaymentRequestResponse(); const { response } = await getPaymentRequestResponse();
const retryPromise = response.retry({}); const retryPromise = response.retry();
await promise_rejects( await promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
response.retry({}), response.retry(),
"Calling retry() again rejects with an InvalidStateError" "Calling retry() again rejects with an InvalidStateError"
); );
await retryPromise; await retryPromise;
@ -54,7 +54,7 @@ function callCompleteWhileRetrying(button) {
button.disabled = true; button.disabled = true;
promise_test(async t => { promise_test(async t => {
const { response } = await getPaymentRequestResponse(); const { response } = await getPaymentRequestResponse();
const retryPromise = response.retry({}); const retryPromise = response.retry();
await promise_rejects( await promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
@ -70,7 +70,7 @@ function callingRequestAbortMustNotAbort(button) {
button.disabled = true; button.disabled = true;
promise_test(async t => { promise_test(async t => {
const { response, request } = await getPaymentRequestResponse(); const { response, request } = await getPaymentRequestResponse();
const retryPromise = response.retry({}); const retryPromise = response.retry();
await promise_rejects( await promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
@ -87,12 +87,12 @@ function canRetryMultipleTimes(button) {
promise_test(async t => { promise_test(async t => {
const { response } = await getPaymentRequestResponse(); const { response } = await getPaymentRequestResponse();
assert_equals( assert_equals(
await response.retry({}), await response.retry(),
undefined, undefined,
"Expected undefined as the resolve value" "Expected undefined as the resolve value"
); );
assert_equals( assert_equals(
await response.retry({}), await response.retry(),
undefined, undefined,
"Expected undefined as the resolve value" "Expected undefined as the resolve value"
); );
@ -100,7 +100,7 @@ function canRetryMultipleTimes(button) {
await promise_rejects( await promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
response.retry({}), response.retry(),
"Calling retry() after complete() rejects with a InvalidStateError" "Calling retry() after complete() rejects with a InvalidStateError"
); );
}, button.textContent.trim()); }, button.textContent.trim());
@ -113,13 +113,13 @@ function userCanAbortARetry(button) {
await promise_rejects( await promise_rejects(
t, t,
"AbortError", "AbortError",
response.retry({}), response.retry(),
"The user aborting a retry rejects with a AbortError" "The user aborting a retry rejects with a AbortError"
); );
await promise_rejects( await promise_rejects(
t, t,
"InvalidStateError", "InvalidStateError",
response.retry({}), response.retry(),
"After the user aborts, response [[complete]] is true so retry() must reject with InvalidStateError" "After the user aborts, response [[complete]] is true so retry() must reject with InvalidStateError"
); );
await promise_rejects( await promise_rejects(
@ -154,7 +154,7 @@ function abortTheUpdate(button) {
resolve(); resolve();
}; };
}); });
const retryPromise = response.retry({}); const retryPromise = response.retry();
await shippingChangedPromise; await shippingChangedPromise;
await promise_rejects( await promise_rejects(
t, t,
@ -175,11 +175,11 @@ function callingRetryReturnsUniquePromise(button){
button.disabled = true; button.disabled = true;
promise_test(async t => { promise_test(async t => {
const { response } = await getPaymentRequestResponse(); const { response } = await getPaymentRequestResponse();
const retryPromise = response.retry({}); const retryPromise = response.retry();
const promises = new Set([ const promises = new Set([
retryPromise, retryPromise,
response.retry({}), response.retry(),
response.retry({}), response.retry(),
]); ]);
assert_equals(promises.size, 3, "Must have three unique objects"); assert_equals(promises.size, 3, "Must have three unique objects");
await retryPromise; await retryPromise;

View file

@ -2,4 +2,4 @@ html5lib == 1.0.1
mozinfo == 0.10 mozinfo == 0.10
mozlog==3.9 mozlog==3.9
mozdebug==0.1.1 mozdebug==0.1.1
urllib3[secure]==1.24 urllib3[secure]==1.24.1

View file

@ -32,10 +32,9 @@ for (const params of gEasingTests) {
}, `Transformed progress for ${params.desc}`); }, `Transformed progress for ${params.desc}`);
} }
// Additional tests for various boundary conditions of step timing functions and // Additional tests for various boundary conditions of step timing functions.
// frames timing functions.
const gStepAndFramesTimingFunctionTests = [ const gStepTimingFunctionTests = [
{ {
description: 'Test bounds point of step-start easing', description: 'Test bounds point of step-start easing',
effect: { effect: {
@ -255,12 +254,72 @@ const gStepAndFramesTimingFunctionTests = [
] ]
}, },
{ {
description: 'Test bounds point of frames easing', description: 'Test bounds point of steps(jump-both) easing',
effect: { effect: {
delay: 1000, delay: 1000,
duration: 1000, duration: 1000,
fill: 'both', fill: 'both',
easing: 'frames(2)' easing: 'steps(2, jump-both)'
},
conditions: [
{ currentTime: 0, progress: 0 },
{ currentTime: 999, progress: 0 },
{ currentTime: 1000, progress: 1/3 },
{ currentTime: 1499, progress: 1/3 },
{ currentTime: 1500, progress: 2/3 },
{ currentTime: 2000, progress: 1 }
]
},
{
description: 'Test bounds point of steps(jump-both) easing ' +
'with iterationStart and delay',
effect: {
duration: 1000,
fill: 'both',
delay: 1000,
iterationStart: 0.5,
easing: 'steps(2, jump-both)'
},
conditions: [
{ currentTime: 0, progress: 1/3 },
{ currentTime: 999, progress: 1/3 },
{ currentTime: 1000, progress: 2/3 },
{ currentTime: 1499, progress: 2/3 },
{ currentTime: 1500, progress: 1/3 },
{ currentTime: 1999, progress: 1/3 },
{ currentTime: 2000, progress: 2/3 },
{ currentTime: 2500, progress: 2/3 }
]
},
{
description: 'Test bounds point of steps(jump-both) easing ' +
'with iterationStart not at a transition point',
effect: {
delay: 1000,
duration: 1000,
fill: 'both',
iterationStart: 0.75,
easing: 'steps(2, jump-both)'
},
conditions: [
{ currentTime: 0, progress: 2/3 },
{ currentTime: 999, progress: 2/3 },
{ currentTime: 1000, progress: 2/3 },
{ currentTime: 1249, progress: 2/3 },
{ currentTime: 1250, progress: 1/3 },
{ currentTime: 1749, progress: 1/3 },
{ currentTime: 1750, progress: 2/3 },
{ currentTime: 2000, progress: 2/3 },
{ currentTime: 2500, progress: 2/3 }
]
},
{
description: 'Test bounds point of steps(jump-none) easing',
effect: {
delay: 1000,
duration: 1000,
fill: 'both',
easing: 'steps(2, jump-none)'
}, },
conditions: [ conditions: [
{ currentTime: 0, progress: 0 }, { currentTime: 0, progress: 0 },
@ -271,27 +330,51 @@ const gStepAndFramesTimingFunctionTests = [
] ]
}, },
{ {
description: 'Test bounds point of frames easing ' + description: 'Test bounds point of steps(jump-none) easing ' +
'with iterationStart and delay', 'with iterationStart and delay',
effect: { effect: {
delay: 1000,
duration: 1000, duration: 1000,
fill: 'both', fill: 'both',
delay: 1000,
iterationStart: 0.5, iterationStart: 0.5,
easing: 'frames(2)' easing: 'steps(2, jump-none)'
}, },
conditions: [ conditions: [
{ currentTime: 0, progress: 1 }, { currentTime: 0, progress: 0 },
{ currentTime: 999, progress: 0 },
{ currentTime: 1000, progress: 1 }, { currentTime: 1000, progress: 1 },
{ currentTime: 1499, progress: 1 }, { currentTime: 1499, progress: 1 },
{ currentTime: 1500, progress: 0 }, { currentTime: 1500, progress: 0 },
{ currentTime: 1999, progress: 0 }, { currentTime: 1999, progress: 0 },
{ currentTime: 2000, progress: 1 } { currentTime: 2000, progress: 1 },
{ currentTime: 2500, progress: 1 }
] ]
} },
{
description: 'Test bounds point of steps(jump-none) easing ' +
'with iterationStart not at a transition point',
effect: {
delay: 1000,
duration: 1000,
fill: 'both',
iterationStart: 0.75,
easing: 'steps(2, jump-none)'
},
conditions: [
{ currentTime: 0, progress: 1 },
{ currentTime: 999, progress: 1 },
{ currentTime: 1000, progress: 1 },
{ currentTime: 1249, progress: 1 },
{ currentTime: 1250, progress: 0 },
{ currentTime: 1749, progress: 0 },
{ currentTime: 1750, progress: 1 },
{ currentTime: 2000, progress: 1 },
{ currentTime: 2500, progress: 1 }
]
},
]; ];
for (const options of gStepAndFramesTimingFunctionTests) { for (const options of gStepTimingFunctionTests) {
test(t => { test(t => {
const target = createDiv(t); const target = createDiv(t);
const animation = target.animate(null, options.effect); const animation = target.animate(null, options.effect);

View file

@ -0,0 +1,3 @@
spec: https://github.com/w3c/webrtc-identity
suggested_reviewers:
- martinthomson

View file

@ -0,0 +1,77 @@
<!doctype html>
<meta charset="utf-8">
<title>RTCCertificate persistent Tests</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<body>
<script>
function findMatchingFingerprint(fingerprints, fingerprint) {
for (let f of fingerprints) {
if (f.value == fingerprint.value && f.algorithm == fingerprint.algorithm)
return true;
}
return false;
}
function with_iframe(url) {
return new Promise(function(resolve) {
var frame = document.createElement('iframe');
frame.src = url;
frame.onload = function() { resolve(frame); };
document.body.appendChild(frame);
});
}
function testPostMessageCertificate(isCrossOrigin) {
promise_test(async t => {
let certificate = await RTCPeerConnection.generateCertificate({ name: 'ECDSA', namedCurve: 'P-256' });
let url = "resources/RTCCertificate-postMessage-iframe.html";
if (isCrossOrigin)
url = get_host_info().HTTP_REMOTE_ORIGIN + "/webrtc/" + url;
let iframe = await with_iframe(url);
let promise = new Promise((resolve, reject) => {
window.onmessage = (event) => {
resolve(event.data);
};
t.step_timeout(() => reject("Timed out waiting for frame to send back certificate"), 5000);
});
iframe.contentWindow.postMessage(certificate, "*");
let certificate2 = await promise;
new RTCPeerConnection({certificates: [certificate]});
new RTCPeerConnection({certificates: [certificate2]});
assert_equals(certificate.expires, certificate2.expires);
for (let fingerprint of certificate2.getFingerprints())
assert_true(findMatchingFingerprint(certificate.getFingerprints(), fingerprint), "check fingerprints");
iframe.remove();
}, "Check " + (isCrossOrigin ? "cross-origin" : "same-origin") + " RTCCertificate serialization");
}
testPostMessageCertificate(false);
testPostMessageCertificate(true);
promise_test(async t => {
let url = get_host_info().HTTP_REMOTE_ORIGIN + "/webrtc/resources/RTCCertificate-postMessage-iframe.html";
let iframe = await with_iframe(url);
let promise = new Promise((resolve, reject) => {
window.onmessage = (event) => {
resolve(event.data);
};
t.step_timeout(() => reject("Timed out waiting for frame to send back certificate"), 5000);
});
iframe.contentWindow.postMessage(null, "*");
let certificate2 = await promise;
assert_throws("InvalidAccessError", () => { new RTCPeerConnection({certificates: [certificate2]}) });
iframe.remove();
}, "Check cross-origin created RTCCertificate");
</script>
</body>

View file

@ -6,8 +6,8 @@
<script> <script>
'use strict'; 'use strict';
// Test is based on the following editor draft: // Test is based on the Candidate Recommendation:
// https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html // https://www.w3.org/TR/webrtc/
/* /*
4.2.1. RTCConfiguration Dictionary 4.2.1. RTCConfiguration Dictionary
@ -26,8 +26,8 @@
4.10.2. RTCCertificate Interface 4.10.2. RTCCertificate Interface
interface RTCCertificate { interface RTCCertificate {
readonly attribute DOMTimeStamp expires; readonly attribute DOMTimeStamp expires;
static sequence<AlgorithmIdentifier> getSupportedAlgorithms();
sequence<RTCDtlsFingerprint> getFingerprints(); sequence<RTCDtlsFingerprint> getFingerprints();
AlgorithmIdentifier getAlgorithm();
}; };
5.5.1 The RTCDtlsFingerprint Dictionary 5.5.1 The RTCDtlsFingerprint Dictionary
@ -257,10 +257,9 @@
TODO TODO
4.10.2. RTCCertificate Interface 4.10.2. RTCCertificate Interface
getAlgorithm getSupportedAlgorithms
Returns the result of the WebCrypto algorithm normalization process Returns a sequence providing a representative set of supported
[WebCryptoAPI] that occurred when this certificate was generated certificate algorithms. At least one algorithm MUST be returned.
with generateCertificate().
The RTCCertificate object can be stored and retrieved from persistent The RTCCertificate object can be stored and retrieved from persistent
storage by an application. When a user agent is required to obtain a storage by an application. When a user agent is required to obtain a

View file

@ -34,7 +34,7 @@
candidate: '', candidate: '',
sdpMid: null, sdpMid: null,
sdpMLineIndex: null, sdpMLineIndex: null,
ufrag: undefined usernameFragment: undefined
})); }));
}, 'new RTCIceCandidate({ ... }) with manually filled default values'); }, 'new RTCIceCandidate({ ... }) with manually filled default values');
@ -77,7 +77,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, 'audio'); assert_equals(candidate.sdpMid, 'audio');
assert_equals(candidate.sdpMLineIndex, null); assert_equals(candidate.sdpMLineIndex, null);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, `new RTCIceCandidate({ sdpMid: 'audio' })`); }, `new RTCIceCandidate({ sdpMid: 'audio' })`);
test(t => { test(t => {
@ -86,7 +86,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, null); assert_equals(candidate.sdpMid, null);
assert_equals(candidate.sdpMLineIndex, 0); assert_equals(candidate.sdpMLineIndex, 0);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, 'new RTCIceCandidate({ sdpMLineIndex: 0 })'); }, 'new RTCIceCandidate({ sdpMLineIndex: 0 })');
test(t => { test(t => {
@ -98,7 +98,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, 'audio'); assert_equals(candidate.sdpMid, 'audio');
assert_equals(candidate.sdpMLineIndex, 0); assert_equals(candidate.sdpMLineIndex, 0);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, `new RTCIceCandidate({ sdpMid: 'audio', sdpMLineIndex: 0 })`); }, `new RTCIceCandidate({ sdpMid: 'audio', sdpMLineIndex: 0 })`);
test(t => { test(t => {
@ -110,7 +110,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, 'audio'); assert_equals(candidate.sdpMid, 'audio');
assert_equals(candidate.sdpMLineIndex, null); assert_equals(candidate.sdpMLineIndex, null);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, `new RTCIceCandidate({ candidate: '', sdpMid: 'audio' }`); }, `new RTCIceCandidate({ candidate: '', sdpMid: 'audio' }`);
test(t => { test(t => {
@ -122,7 +122,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, null); assert_equals(candidate.sdpMid, null);
assert_equals(candidate.sdpMLineIndex, 0); assert_equals(candidate.sdpMLineIndex, 0);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, `new RTCIceCandidate({ candidate: '', sdpMLineIndex: 0 }`); }, `new RTCIceCandidate({ candidate: '', sdpMLineIndex: 0 }`);
test(t => { test(t => {
@ -134,7 +134,7 @@
assert_equals(candidate.candidate, candidateString); assert_equals(candidate.candidate, candidateString);
assert_equals(candidate.sdpMid, 'audio'); assert_equals(candidate.sdpMid, 'audio');
assert_equals(candidate.sdpMLineIndex, null); assert_equals(candidate.sdpMLineIndex, null);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, 'new RTCIceCandidate({ ... }) with valid candidate string and sdpMid'); }, 'new RTCIceCandidate({ ... }) with valid candidate string and sdpMid');
test(t =>{ test(t =>{
@ -147,7 +147,7 @@
assert_equals(candidate.candidate, arbitraryString); assert_equals(candidate.candidate, arbitraryString);
assert_equals(candidate.sdpMid, 'audio'); assert_equals(candidate.sdpMid, 'audio');
assert_equals(candidate.sdpMLineIndex, null); assert_equals(candidate.sdpMLineIndex, null);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, 'new RTCIceCandidate({ ... }) with invalid candidate string and sdpMid'); }, 'new RTCIceCandidate({ ... }) with invalid candidate string and sdpMid');
test(t => { test(t => {
@ -155,13 +155,13 @@
candidate: candidateString, candidate: candidateString,
sdpMid: 'video', sdpMid: 'video',
sdpMLineIndex: 1, sdpMLineIndex: 1,
ufrag: 'test' usernameFragment: 'test'
}); });
assert_equals(candidate.candidate, candidateString); assert_equals(candidate.candidate, candidateString);
assert_equals(candidate.sdpMid, 'video'); assert_equals(candidate.sdpMid, 'video');
assert_equals(candidate.sdpMLineIndex, 1); assert_equals(candidate.sdpMLineIndex, 1);
assert_equals(candidate.ufrag, 'test'); assert_equals(candidate.usernameFragment, 'test');
}, 'new RTCIceCandidate({ ... }) with non default value for all fields'); }, 'new RTCIceCandidate({ ... }) with non default value for all fields');
@ -174,7 +174,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, arbitraryString); assert_equals(candidate.sdpMid, arbitraryString);
assert_equals(candidate.sdpMLineIndex, null); assert_equals(candidate.sdpMLineIndex, null);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, 'new RTCIceCandidate({ ... }) with invalid sdpMid'); }, 'new RTCIceCandidate({ ... }) with invalid sdpMid');
@ -190,7 +190,7 @@
assert_equals(candidate.candidate, ''); assert_equals(candidate.candidate, '');
assert_equals(candidate.sdpMid, null); assert_equals(candidate.sdpMid, null);
assert_equals(candidate.sdpMLineIndex, 65535); assert_equals(candidate.sdpMLineIndex, 65535);
assert_equals(candidate.ufrag, null); assert_equals(candidate.usernameFragment, null);
}, 'new RTCIceCandidate({ ... }) with invalid sdpMLineIndex'); }, 'new RTCIceCandidate({ ... }) with invalid sdpMLineIndex');
</script> </script>

View file

@ -5,32 +5,6 @@
<script> <script>
'use strict'; 'use strict';
// Test is based on the following editor draft:
// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.htm
/*
4.3.2. Interface Definition
interface RTCPeerConnection : EventTarget {
...
Promise<void> addIceCandidate((RTCIceCandidateInit or RTCIceCandidate) candidate);
};
interface RTCIceCandidate {
readonly attribute DOMString candidate;
readonly attribute DOMString? sdpMid;
readonly attribute unsigned short? sdpMLineIndex;
readonly attribute DOMString? ufrag;
...
};
dictionary RTCIceCandidateInit {
DOMString candidate = "";
DOMString? sdpMid = null;
unsigned short? sdpMLineIndex = null;
DOMString ufrag;
};
*/
// SDP copied from JSEP Example 7.1 // SDP copied from JSEP Example 7.1
// It contains two media streams with different ufrags // It contains two media streams with different ufrags
// to test if candidate is added to the correct stream // to test if candidate is added to the correct stream
@ -89,11 +63,11 @@ a=rtcp-rsize
// valid candidate attributes // valid candidate attributes
const sdpMid = 'a1'; const sdpMid = 'a1';
const sdpMLineIndex = 0; const sdpMLineIndex = 0;
const ufrag = 'ETEn'; const usernameFragment = 'ETEn';
const sdpMid2 = 'v1'; const sdpMid2 = 'v1';
const sdpMLineIndex2 = 1; const sdpMLineIndex2 = 1;
const ufrag2 = 'BGKk'; const usernameFragment2 = 'BGKk';
const mediaLine1 = 'm=audio'; const mediaLine1 = 'm=audio';
const mediaLine2 = 'm=video'; const mediaLine2 = 'm=video';
@ -151,7 +125,7 @@ a=rtcp-rsize
}, 'Add null candidate should reject with TypeError'); }, 'Add null candidate should reject with TypeError');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4. Return the result of enqueuing the following steps: 4. Return the result of enqueuing the following steps:
1. If remoteDescription is null return a promise rejected with a 1. If remoteDescription is null return a promise rejected with a
newly created InvalidStateError. newly created InvalidStateError.
@ -164,7 +138,7 @@ a=rtcp-rsize
return promise_rejects(t, 'InvalidStateError', return promise_rejects(t, 'InvalidStateError',
pc.addIceCandidate({ pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
})); }));
}, 'Add ICE candidate before setting remote description should reject with InvalidStateError'); }, 'Add ICE candidate before setting remote description should reject with InvalidStateError');
@ -179,7 +153,7 @@ a=rtcp-rsize
return pc.setRemoteDescription(sessionDesc) return pc.setRemoteDescription(sessionDesc)
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
})); }));
}, 'Add ICE candidate after setting remote description should succeed'); }, 'Add ICE candidate after setting remote description should succeed');
@ -191,7 +165,7 @@ a=rtcp-rsize
return pc.setRemoteDescription(sessionDesc) return pc.setRemoteDescription(sessionDesc)
.then(() => pc.addIceCandidate(new RTCIceCandidate({ .then(() => pc.addIceCandidate(new RTCIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
}))); })));
}, 'Add ICE candidate with RTCIceCandidate should succeed'); }, 'Add ICE candidate with RTCIceCandidate should succeed');
@ -214,12 +188,15 @@ a=rtcp-rsize
}, 'Add candidate with only valid sdpMLineIndex should succeed'); }, 'Add candidate with only valid sdpMLineIndex should succeed');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4.6.2. If candidate is applied successfully, the user agent MUST queue 4.6.2. If candidate is applied successfully, the user agent MUST queue
a task that runs the following steps: a task that runs the following steps:
2. Let remoteDescription be connection's pendingRemoteDescription 2. If connection.pendingRemoteDescription is non-null, and represents
if not null, otherwise connection's currentRemoteDescription. the ICE generation for which candidate was processed, add
3. Add candidate to remoteDescription. candidate to connection.pendingRemoteDescription.
3. If connection.currentRemoteDescription is non-null, and represents
the ICE generation for which candidate was processed, add
candidate to connection.currentRemoteDescription.
*/ */
promise_test(t => { promise_test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
@ -229,7 +206,7 @@ a=rtcp-rsize
return pc.setRemoteDescription(sessionDesc) return pc.setRemoteDescription(sessionDesc)
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
})) }))
.then(() => { .then(() => {
assert_candidate_line_between(pc.remoteDescription.sdp, assert_candidate_line_between(pc.remoteDescription.sdp,
@ -247,7 +224,7 @@ a=rtcp-rsize
candidate: candidateStr2, candidate: candidateStr2,
sdpMid: sdpMid2, sdpMid: sdpMid2,
sdpMLineIndex: sdpMLineIndex2, sdpMLineIndex: sdpMLineIndex2,
ufrag: ufrag2 usernameFragment: usernameFragment2
})) }))
.then(() => { .then(() => {
assert_candidate_line_after(pc.remoteDescription.sdp, assert_candidate_line_after(pc.remoteDescription.sdp,
@ -264,13 +241,13 @@ a=rtcp-rsize
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, sdpMid, sdpMLineIndex,
ufrag: null usernameFragment: null
})) }))
.then(() => { .then(() => {
assert_candidate_line_between(pc.remoteDescription.sdp, assert_candidate_line_between(pc.remoteDescription.sdp,
mediaLine1, candidateLine1, mediaLine2); mediaLine1, candidateLine1, mediaLine2);
}); });
}, 'Add candidate for first media stream with null ufrag should add candidate to first media stream'); }, 'Add candidate for first media stream with null usernameFragment should add candidate to first media stream');
promise_test(t => { promise_test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
@ -280,13 +257,13 @@ a=rtcp-rsize
return pc.setRemoteDescription(sessionDesc) return pc.setRemoteDescription(sessionDesc)
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
})) }))
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr2, candidate: candidateStr2,
sdpMid: sdpMid2, sdpMid: sdpMid2,
sdpMLineIndex: sdpMLineIndex2, sdpMLineIndex: sdpMLineIndex2,
ufrag: ufrag2 usernameFragment: usernameFragment2
})) }))
.then(() => { .then(() => {
assert_candidate_line_between(pc.remoteDescription.sdp, assert_candidate_line_between(pc.remoteDescription.sdp,
@ -298,15 +275,18 @@ a=rtcp-rsize
}, 'Adding multiple candidates should add candidates to their corresponding media stream'); }, 'Adding multiple candidates should add candidates to their corresponding media stream');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4.6. If candidate.candidate is an empty string, process candidate as an 4.6. If candidate.candidate is an empty string, process candidate as an
end-of-candidates indication for the corresponding media description end-of-candidates indication for the corresponding media description
and ICE candidate generation. and ICE candidate generation.
2. If candidate is applied successfully, the user agent MUST queue 2. If candidate is applied successfully, the user agent MUST queue
a task that runs the following steps: a task that runs the following steps:
2. Let remoteDescription be connection's pendingRemoteDescription 2. If connection.pendingRemoteDescription is non-null, and represents
if not null, otherwise connection's currentRemoteDescription. the ICE generation for which candidate was processed, add
3. Add candidate to remoteDescription. candidate to connection.pendingRemoteDescription.
3. If connection.currentRemoteDescription is non-null, and represents
the ICE generation for which candidate was processed, add
candidate to connection.currentRemoteDescription.
*/ */
promise_test(t => { promise_test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
@ -316,12 +296,12 @@ a=rtcp-rsize
return pc.setRemoteDescription(sessionDesc) return pc.setRemoteDescription(sessionDesc)
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
})) }))
.then(() => pc.addIceCandidate({ .then(() => pc.addIceCandidate({
candidate: '', candidate: '',
sdpMid, sdpMLineIndex, sdpMid, sdpMLineIndex,
ufrag usernameFragment
})) }))
.then(() => { .then(() => {
assert_candidate_line_between(pc.remoteDescription.sdp, assert_candidate_line_between(pc.remoteDescription.sdp,
@ -333,7 +313,7 @@ a=rtcp-rsize
}, 'Add with empty candidate string (end of candidate) should succeed'); }, 'Add with empty candidate string (end of candidate) should succeed');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
3. If both sdpMid and sdpMLineIndex are null, return a promise rejected 3. If both sdpMid and sdpMLineIndex are null, return a promise rejected
with a newly created TypeError. with a newly created TypeError.
*/ */
@ -403,12 +383,12 @@ a=rtcp-rsize
candidate: '', candidate: '',
sdpMid: null, sdpMid: null,
sdpMLineIndex: null, sdpMLineIndex: null,
ufrag: undefined usernameFragment: undefined
}))); })));
}, 'Add candidate with manually filled default values should reject with TypeError'); }, 'Add candidate with manually filled default values should reject with TypeError');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4.3. If candidate.sdpMid is not null, run the following steps: 4.3. If candidate.sdpMid is not null, run the following steps:
1. If candidate.sdpMid is not equal to the mid of any media 1. If candidate.sdpMid is not equal to the mid of any media
description in remoteDescription , reject p with a newly description in remoteDescription , reject p with a newly
@ -424,12 +404,12 @@ a=rtcp-rsize
promise_rejects(t, 'OperationError', promise_rejects(t, 'OperationError',
pc.addIceCandidate({ pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid: 'invalid', sdpMLineIndex, ufrag sdpMid: 'invalid', sdpMLineIndex, usernameFragment
}))); })));
}, 'Add candidate with invalid sdpMid should reject with OperationError'); }, 'Add candidate with invalid sdpMid should reject with OperationError');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4.4. Else, if candidate.sdpMLineIndex is not null, run the following 4.4. Else, if candidate.sdpMLineIndex is not null, run the following
steps: steps:
1. If candidate.sdpMLineIndex is equal to or larger than the 1. If candidate.sdpMLineIndex is equal to or larger than the
@ -447,7 +427,7 @@ a=rtcp-rsize
pc.addIceCandidate({ pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMLineIndex: 2, sdpMLineIndex: 2,
ufrag usernameFragment
}))); })));
}, 'Add candidate with invalid sdpMLineIndex should reject with OperationError'); }, 'Add candidate with invalid sdpMLineIndex should reject with OperationError');
@ -463,7 +443,7 @@ a=rtcp-rsize
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMid,
sdpMLineIndex: 2, sdpMLineIndex: 2,
ufrag usernameFragment
})); }));
}, 'Invalid sdpMLineIndex should be ignored if valid sdpMid is provided'); }, 'Invalid sdpMLineIndex should be ignored if valid sdpMid is provided');
@ -477,18 +457,18 @@ a=rtcp-rsize
candidate: candidateStr2, candidate: candidateStr2,
sdpMid: sdpMid2, sdpMid: sdpMid2,
sdpMLineIndex: sdpMLineIndex2, sdpMLineIndex: sdpMLineIndex2,
ufrag: null usernameFragment: null
})) }))
.then(() => { .then(() => {
assert_candidate_line_after(pc.remoteDescription.sdp, assert_candidate_line_after(pc.remoteDescription.sdp,
mediaLine2, candidateLine2); mediaLine2, candidateLine2);
}); });
}, 'Add candidate for media stream 2 with null ufrag should succeed'); }, 'Add candidate for media stream 2 with null usernameFragment should succeed');
/* /*
4.3.2. addIceCandidate 4.3.2. addIceCandidate
4.5. If candidate.ufrag is neither undefined nor null, and is not equal 4.5. If candidate.usernameFragment is neither undefined nor null, and is not equal
to any ufrag present in the corresponding media description of an to any usernameFragment present in the corresponding media description of an
applied remote description, reject p with a newly created applied remote description, reject p with a newly created
OperationError and abort these steps. OperationError and abort these steps.
*/ */
@ -503,12 +483,12 @@ a=rtcp-rsize
pc.addIceCandidate({ pc.addIceCandidate({
candidate: candidateStr1, candidate: candidateStr1,
sdpMid, sdpMLineIndex, sdpMid, sdpMLineIndex,
ufrag: 'invalid' usernameFragment: 'invalid'
}))); })));
}, 'Add candidate with invalid ufrag should reject with OperationError'); }, 'Add candidate with invalid usernameFragment should reject with OperationError');
/* /*
4.3.2. addIceCandidate 4.4.2. addIceCandidate
4.6.1. If candidate could not be successfully added the user agent MUST 4.6.1. If candidate could not be successfully added the user agent MUST
queue a task that runs the following steps: queue a task that runs the following steps:
2. Reject p with a DOMException object whose name attribute has 2. Reject p with a DOMException object whose name attribute has
@ -524,7 +504,7 @@ a=rtcp-rsize
promise_rejects(t, 'OperationError', promise_rejects(t, 'OperationError',
pc.addIceCandidate({ pc.addIceCandidate({
candidate: invalidCandidateStr, candidate: invalidCandidateStr,
sdpMid, sdpMLineIndex, ufrag sdpMid, sdpMLineIndex, usernameFragment
}))); })));
}, 'Add candidate with invalid candidate string should reject with OperationError'); }, 'Add candidate with invalid candidate string should reject with OperationError');
@ -540,52 +520,8 @@ a=rtcp-rsize
candidate: candidateStr2, candidate: candidateStr2,
sdpMid: sdpMid2, sdpMid: sdpMid2,
sdpMLineIndex: sdpMLineIndex2, sdpMLineIndex: sdpMLineIndex2,
ufrag: ufrag usernameFragment
}))); })));
}, 'Add candidate with sdpMid belonging to different ufrag should reject with OperationError'); }, 'Add candidate with sdpMid belonging to different usernameFragment should reject with OperationError');
/*
TODO
4.3.2. addIceCandidate
4.6. In parallel, add the ICE candidate candidate as described in [JSEP]
(section 4.1.17.). Use candidate.ufrag to identify the ICE generation;
If the ufrag is null, process the candidate for the most recent ICE
generation.
- Call with candidate string containing partial malformed syntax, i.e. malformed IP.
Some browsers may ignore the syntax error and add it to the SDP regardless.
Non-Testable
4.3.2. addIceCandidate
4.6. (The steps are non-testable because the abort step in enqueue operation
steps in before they can reach here):
1. If candidate could not be successfully added the user agent MUST
queue a task that runs the following steps:
1. If connection's [[isClosed]] slot is true, then abort
these steps.
2. If candidate is applied successfully, the user agent MUST queue
a task that runs the following steps:
1. If connection's [[isClosed]] slot is true, then abort these steps.
Issues
w3c/webrtc-pc#1213
addIceCandidate end of candidates woes
w3c/webrtc-pc#1216
Clarify addIceCandidate behavior when adding candidate after end of candidate
w3c/webrtc-pc#1227
addIceCandidate may add ice candidate to the wrong remote description
w3c/webrtc-pc#1345
Make promise rejection/enqueing consistent
Coverage Report
Total: 23
Tested: 19
Not Tested: 2
Non-Testable: 2
*/
</script> </script>

View file

@ -358,7 +358,7 @@ const trackFactories = {
*/ */
canCreate(requested) { canCreate(requested) {
const supported = { const supported = {
audio: !!window.MediaStreamAudioDestinationNode, audio: !!window.AudioContext && !!window.MediaStreamAudioDestinationNode,
video: !!HTMLCanvasElement.prototype.captureStream video: !!HTMLCanvasElement.prototype.captureStream
}; };

View file

@ -92,11 +92,11 @@ both the sdpMid and sdpMLineIndex dictionary members are null, throw a TypeError
const candidate = ""; const candidate = "";
const sdpMid = "sdpMid"; const sdpMid = "sdpMid";
const sdpMLineIndex = 1; const sdpMLineIndex = 1;
const ufrag = ""; const usernameFragment = "";
const url = "foo.bar"; const url = "foo.bar";
test(() => { test(() => {
const iceCandidate = new RTCIceCandidate({ candidate, sdpMid, sdpMLineIndex, ufrag }); const iceCandidate = new RTCIceCandidate({ candidate, sdpMid, sdpMLineIndex, usernameFragment });
const event = new RTCPeerConnectionIceEvent("type", { const event = new RTCPeerConnectionIceEvent("type", {
candidate: iceCandidate, candidate: iceCandidate,
url, url,
@ -108,33 +108,10 @@ test(() => {
}, "RTCPeerConnectionIceEvent with RTCIceCandidate"); }, "RTCPeerConnectionIceEvent with RTCIceCandidate");
test(() => { test(() => {
const plain = { candidate, sdpMid, sdpMLineIndex, ufrag }; const plain = { candidate, sdpMid, sdpMLineIndex, usernameFragment };
assert_throws(new TypeError(), () => new RTCPeerConnectionIceEvent("type", { candidate: plain })); assert_throws(new TypeError(), () => new RTCPeerConnectionIceEvent("type", { candidate: plain }));
}, "RTCPeerConnectionIceEvent with non RTCIceCandidate object throws"); }, "RTCPeerConnectionIceEvent with non RTCIceCandidate object throws");
/*
This will remain commented out until https://github.com/w3c/webrtc-pc/issues/1232
is resolved.
test(() => {
// When firing an RTCPeerConnectionIceEvent event that contains a RTCIceCandidate
// object, it must include values for both sdpMid and sdpMLineIndex.
assert_throws(new TypeError(), () => {
new RTCPeerConnectionIceEvent("type", {
candidate: new RTCIceCandidate({ candidate, sdpMid, ufrag })
});
});
assert_throws(new TypeError(), () => {
new RTCPeerConnectionIceEvent("type", {
candidate: new RTCIceCandidate({ candidate, sdpMLineIndex, ufrag })
});
});
}, "RTCIceCandidate must include values for both sdpMid and sdpMLineIndex");
*/
test(() => { test(() => {
const event = new RTCPeerConnectionIceEvent("type", { const event = new RTCPeerConnectionIceEvent("type", {
candidate: null, candidate: null,
@ -145,4 +122,5 @@ test(() => {
assert_true(event.bubbles); assert_true(event.bubbles);
assert_true(event.cancelable); assert_true(event.cancelable);
}, "RTCPeerConnectionIceEvent bubbles and cancelable"); }, "RTCPeerConnectionIceEvent bubbles and cancelable");
</script> </script>

View file

@ -0,0 +1,9 @@
<!doctype html>
<script>
window.onmessage = async (event) => {
let certificate = event.data;
if (!certificate)
certificate = await RTCPeerConnection.generateCertificate({ name: 'ECDSA', namedCurve: 'P-256'});
event.source.postMessage(certificate, "*");
}
</script>

View file

@ -0,0 +1,122 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>RTCPeerConnection Connection Test</title>
<script src="RTCPeerConnection-helper.js"></script>
</head>
<body>
<div id="log"></div>
<div>
<video id="local-view" muted autoplay="autoplay"></video>
<video id="remote-view" muted autoplay="autoplay"/>
</video>
</div>
<!-- These files are in place when executing on W3C. -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="text/javascript">
var test = async_test('Can set up a basic WebRTC call without announcing ssrcs.', {timeout: 5000});
var gFirstConnection = null;
var gSecondConnection = null;
// if the remote video gets video data that implies the negotiation
// as well as the ICE and DTLS connection are up.
document.getElementById('remote-view')
.addEventListener('loadedmetadata', function() {
// Call negotiated: done.
test.done();
});
function getNoiseStreamOkCallback(localStream) {
gFirstConnection = new RTCPeerConnection(null);
gFirstConnection.onicecandidate = onIceCandidateToFirst;
localStream.getTracks().forEach(function(track) {
gFirstConnection.addTrack(track, localStream);
});
gFirstConnection.createOffer().then(onOfferCreated, failed('createOffer'));
var videoTag = document.getElementById('local-view');
videoTag.srcObject = localStream;
};
var onOfferCreated = test.step_func(function(offer) {
gFirstConnection.setLocalDescription(offer);
// remove all a=ssrc: lines, the msid-semantic line and any a=msid:.
var sdp = offer.sdp.replace(/^a=ssrc:.*$\r\n/gm, '')
.replace(/^a=msid-semantic.*$\r\n/gm, '')
.replace(/^a=msid:.*$\r\n/gm, '');
// This would normally go across the application's signaling solution.
// In our case, the "signaling" is to call this function.
receiveCall(sdp);
});
function receiveCall(offerSdp) {
gSecondConnection = new RTCPeerConnection(null);
gSecondConnection.onicecandidate = onIceCandidateToSecond;
gSecondConnection.ontrack = onRemoteTrack;
var parsedOffer = new RTCSessionDescription({ type: 'offer',
sdp: offerSdp });
gSecondConnection.setRemoteDescription(parsedOffer);
gSecondConnection.createAnswer().then(onAnswerCreated,
failed('createAnswer'));
};
var onAnswerCreated = test.step_func(function(answer) {
gSecondConnection.setLocalDescription(answer);
// remove all a=ssrc: lines, the msid-semantic line and any a=msid:.
var sdp = answer.sdp.replace(/^a=ssrc:.*$\r\n/gm, '')
.replace(/^a=msid-semantic.*$\r\n/gm, '')
.replace(/^a=msid:.*$\r\n/gm, '');
// Similarly, this would go over the application's signaling solution.
handleAnswer(sdp);
});
function handleAnswer(answerSdp) {
var parsedAnswer = new RTCSessionDescription({ type: 'answer',
sdp: answerSdp });
gFirstConnection.setRemoteDescription(parsedAnswer);
};
var onIceCandidateToFirst = test.step_func(function(event) {
// If event.candidate is null = no more candidates.
if (event.candidate) {
gSecondConnection.addIceCandidate(event.candidate);
}
});
var onIceCandidateToSecond = test.step_func(function(event) {
if (event.candidate) {
gFirstConnection.addIceCandidate(event.candidate);
}
});
var onRemoteTrack = test.step_func(function(event) {
var videoTag = document.getElementById('remote-view');
if (!videoTag.srcObject) {
videoTag.srcObject = event.streams[0];
}
});
// Returns a suitable error callback.
function failed(function_name) {
return test.unreached_func('WebRTC called error callback for ' + function_name);
}
// This function starts the test.
test.step(function() {
getNoiseStream({ video: true, audio: true })
.then(test.step_func(getNoiseStreamOkCallback), failed('getNoiseStream'));
});
</script>
</body>
</html>