Auto merge of #26478 - servo-wpt-sync:wpt_update_09-05-2020, r=servo-wpt-sync

Sync WPT with upstream (09-05-2020)

Automated downstream sync of changes from upstream as of 09-05-2020.
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2020-05-09 07:10:58 -04:00 committed by GitHub
commit 75fce11335
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
112 changed files with 2252 additions and 926 deletions

View file

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

View file

@ -1,4 +0,0 @@
[hit-test-floats-002.html]
[Hit test float]
expected: FAIL

View file

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

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box]
expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

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

View file

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

View file

@ -2,3 +2,6 @@
[elementsFromPoint on the root document for points in iframe elements]
expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[HTMLMediaElement.html]
expected: TIMEOUT

View file

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

View file

@ -53,9 +53,6 @@
[combined text/javascript ]
expected: FAIL
[separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -11,9 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL
[X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
[X-Content-Type-Options%3A%20%40%23%24%23%25%25%26%5E%26%5E*()()11!%2Cnosniff]
expected: FAIL

View file

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

View file

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

View file

@ -1,16 +1,20 @@
[supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Host element with delegatesFocus including no focusable descendants should be skipped]
expected: FAIL
expected: NOTRUN
[Element with tabindex should support autofocus]
expected: FAIL
expected: TIMEOUT
[Area element should support autofocus]
expected: FAIL
expected: NOTRUN
[Host element with delegatesFocus should support autofocus]
expected: FAIL
expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: NOTRUN

View file

@ -3,6 +3,3 @@
[The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: FAIL

View file

@ -0,0 +1,16 @@
[event-handler-sourcetext.html]
[error event handler on disconnected body]
expected: FAIL
[error event handler not on body]
expected: FAIL
[error event handler on connected body, reflected to Window]
expected: FAIL
[error event handler on disconnected frameset]
expected: FAIL
[non-error event handler]
expected: FAIL

View file

@ -0,0 +1,9 @@
[constructor-shared.tentative.any.worker.html]
[Shared memory]
expected: FAIL
[constructor-shared.tentative.any.html]
[Shared memory]
expected: FAIL

View file

@ -0,0 +1,9 @@
[grow.any.worker.html]
[Growing shared memory does not detach old buffer]
expected: FAIL
[grow.any.html]
[Growing shared memory does not detach old buffer]
expected: FAIL

View file

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

View file

@ -136961,6 +136961,32 @@
{}
]
],
"grid-flex-item-003.html": [
"1996370f03caa8ab3c9bdaed4c451fd2301b5514",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"grid-flex-item-004.html": [
"885fb8c1952cf0767653f646c3e1ea4c92815769",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"image-items-flake-001.html": [
"90319f1ad83d26d414d8ddcd4a9ab59042a4bd62",
[
@ -163300,6 +163326,84 @@
{}
]
],
"block-aspect-ratio-009.tentative.html": [
"980a06b8ab49b2690f8be42b36b703829d20e4c8",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"block-aspect-ratio-010.tentative.html": [
"5cb7c841aea9ca429e8d2883aae73fe967c0762f",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"block-aspect-ratio-011.tentative.html": [
"17790c93a66555fff3e96d33cbce869e288f8cde",
[
null,
[
[
"/css/css-sizing/aspect-ratio/reference/ref-square-with-vertical-scrollbar.html",
"=="
]
],
{}
]
],
"block-aspect-ratio-012.tentative.html": [
"2cace2e1704798fabe7119ac294e0b1e5b02d181",
[
null,
[
[
"/css/css-sizing/aspect-ratio/reference/ref-square-with-scrollbar.html",
"=="
]
],
{}
]
],
"block-aspect-ratio-013.tentative.html": [
"d8e9ad805bb1ef2977968d9e1414fffe1cdcfe5a",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"block-aspect-ratio-014.tentative.html": [
"e93dbe2cc224e328f631d13090f8e4a1e07204b9",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"flex-aspect-ratio-001.tentative.html": [
"3b477e299ad763a1c0108e16f05981c76c25bb77",
[
@ -163379,7 +163483,72 @@
]
],
"flex-aspect-ratio-007.tentative.html": [
"c7144c3cf67c56459d670be2f12631898151b43b",
"80bae831a3422e164dd770106c0ad69a58e9b5fb",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"flex-aspect-ratio-008.tentative.html": [
"f5a3b36c65b913a39b7b70ee77f1451f3e1c90ef",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"percentage-resolution-001.tentative.html": [
"d606bfc65e340f95fbbc355b764a7de5e7aeb6a1",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"percentage-resolution-002.tentative.html": [
"766e51d74f78591eda946949a05a26aca362895f",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"percentage-resolution-003.tentative.html": [
"914bfb79183d33146c116f647c34a06c68b28e4b",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"percentage-resolution-004.tentative.html": [
"5d222a9be2131028f50ecd476f6e484c51bbfe22",
[
null,
[
@ -164213,6 +164382,32 @@
{}
]
],
"intrinsic-percent-replaced-dynamic-009.html": [
"0c7a411a7284c69d6bdbf025245b20148351aad9",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square-only.html",
"=="
]
],
{}
]
],
"intrinsic-percent-replaced-dynamic-010.html": [
"04c154e8fcdb8b176d7e82c177fd43aa5d4f8b25",
[
null,
[
[
"/css/reference/ref-filled-green-100px-square-only.html",
"=="
]
],
{}
]
],
"ortho-writing-mode-001.html": [
"9342802645faa7b57a12ce4b8ef17d755fcaface",
[
@ -300655,6 +300850,18 @@
"086e654a8e039f259b5e828d024f808c2e95016b",
[]
],
"aspect-ratio": {
"reference": {
"ref-square-with-scrollbar.html": [
"128bf336e71e442410620cf2b52720ef6d2037cc",
[]
],
"ref-square-with-vertical-scrollbar.html": [
"5663e16dd8ab8a193bed2f82dfc1770027cdf9e2",
[]
]
}
},
"auto-scrollbar-inside-stf-abspos-ref.html": [
"076893b2728772662f06b9474bcc1918c860b480",
[]
@ -331475,7 +331682,7 @@
[]
],
"idle-detection.idl": [
"2b8ff2543c87b5d0ee88d0abf9f80689adaa48e9",
"066e1ede78dfeca799edeedbe1ccc23e8776798a",
[]
],
"mock.js": [
@ -331492,7 +331699,7 @@
[]
],
"idlharness-worker.js": [
"a37d2273931ede26b74b1d074ea2f450b9842ac5",
"6527dc45525adf276b87d8859f12d2c98e61d548",
[]
]
}
@ -333072,11 +333279,11 @@
[]
],
"test-adapter.js": [
"7a3d2c20b831824e609ee4326ef15a93d868b334",
"3272790f7ae50df40f71b4cdff5283823b8223dc",
[]
],
"util.js": [
"2ef971ddb79166bbf8c6593c4d57ca3a5feca83b",
"8a06d72bb663f22050a24732550fa5c5cf232149",
[]
]
}
@ -334954,7 +335161,7 @@
],
"resources": {
"orientation-event-helpers.js": [
"3168b71c5ec6476f4120ea2e59d00cb371e40596",
"84bfc5115f38b6999a3d0fb234ce7b0a3e7608b3",
[]
]
}
@ -337962,7 +338169,7 @@
[]
],
"webxr-test.js": [
"7d4ad809bfd35163807eee542b4a765843f4805f",
"4809ac86bd3e487aceefbfb62ccd191e6395d70a",
[]
],
"webxr-test.js.headers": [
@ -341608,6 +341815,14 @@
"ee86b537ae987483687cc8ba6181db82f99ab162",
[]
],
"animations": {
"support": {
"animated-path-helpers.js": [
"3f6fffb9078b74ea674951d1299e2a29ce1f93ac",
[]
]
}
},
"coordinate-systems": {
"support": {
"abspos-ref.html": [
@ -342724,7 +342939,7 @@
[]
],
"test_valid.py": [
"85c015e521a6fcbe9e4050e4db7b9a191c3e113c",
"c0863dfb2f5af338d13f5e6b7847838e33bc2a8f",
[]
]
}
@ -350081,6 +350296,12 @@
"c81672f208b1505430dd1ee909afaf12d9b2db20",
[]
],
"memory": {
"assertions.js": [
"b539513adcab7d84e67d65fcf97453e9bc22de43",
[]
]
},
"table": {
"assertions.js": [
"b1aeaf1a65dab748c56c8cdf9c1393f97bfdf0e5",
@ -354104,7 +354325,7 @@
[]
],
"webxr_util.js": [
"7c157518755dfef1f0ffe2e00cbb27d8a2939dcb",
"81dc3d620aa1f739fc7402857ef394a17768e9cd",
[]
]
},
@ -389700,6 +389921,13 @@
{}
]
],
"marker-animate.html": [
"d4cd09ae96ef99518e9734f2def1a482aff49476",
[
null,
{}
]
],
"marker-computed-content.html": [
"b2df337adcd1f0f65b21a270319e5e89180515ed",
[
@ -391888,7 +392116,7 @@
]
},
"quirks-mode-001.tentative.html": [
"a1222208aba3ac779d5860607ff3e278c173a8ea",
"8f857a37adebdf73f7c21553ce155895dd244306",
[
null,
{}
@ -391900,6 +392128,13 @@
null,
{}
]
],
"quirks-mode-003.tentative.html": [
"18fe2f1b481c2294e8440027d159cfeaf117b67c",
[
null,
{}
]
]
},
"aspect-ratio-affects-container-width-when-height-changes.html": [
@ -403554,7 +403789,7 @@
]
},
"customized-built-in-constructor-exceptions.html": [
"32729bdb6bb2c82f54c074c7609ff5c79883a37a",
"f9c440fe5943da48584c3ee3e2016539fa329138",
[
null,
{}
@ -424952,7 +425187,7 @@
]
],
"preload.https.sub.html": [
"323d2eb06e605a4a5da6ad05ce646ee7d50c99c0",
"29042a854740eb8070b5e7713e9a8e39d1198680",
[
null,
{
@ -462474,6 +462709,13 @@
{}
]
],
"event-handler-sourcetext.html": [
"57555faa7b891f4800c2e630ddd3fe844ea10289",
[
null,
{}
]
],
"event-handler-spec-example.window.js": [
"abf46882aabda3184052e471ab94c542e01eeef7",
[
@ -462989,7 +463231,7 @@
]
],
"protocol.https.html": [
"18c7ad1b42b06f8a148c998361bad0d5e7ad788c",
"d8b3e55d751e34cae2fdcdc356ddb88d79b1f2a8",
[
null,
{}
@ -463117,7 +463359,7 @@
},
"idle-detection": {
"basics.tentative.https.window.js": [
"2bb74fbcd2ae5c7cf068aab0574504704a36093c",
"8abbbb70b22959f695ab9fec5031cc9091f5e076",
[
"idle-detection/basics.tentative.https.window.html",
{
@ -463182,7 +463424,7 @@
]
],
"idle-permission.tentative.https.window.js": [
"502ba2ef347587e052bce50ee6fe5a5f230a423f",
"af83876821a62f1f84b069774c252b901b446713",
[
"idle-detection/idle-permission.tentative.https.window.html",
{
@ -463218,7 +463460,7 @@
]
],
"idlharness.https.window.js": [
"7b410e0c6c48ba633a06da194bd96a9f66b6fb4d",
"dec8fee98825732d578a57db3194cef079e1c54b",
[
"idle-detection/idlharness.https.window.html",
{
@ -463244,7 +463486,7 @@
]
],
"interceptor.https.html": [
"449c9c86aac967dbe4bdb8dc0455fb0784d57367",
"31acf2829f2f778686dcd83dc07f5be1713af91d",
[
null,
{
@ -465285,7 +465527,21 @@
]
],
"simple-block-movement.html": [
"533f85a68e68949a52772792b915b04696340a4e",
"aafc869a274e605ce4be871663b4e21cbf9af86d",
[
null,
{}
]
],
"sources-enclosure.html": [
"8d1596ad498393ee8f6ea62b5da4c41cc943741c",
[
null,
{}
]
],
"sources-maximpact.html": [
"497932b065e170c3a0c04f79fe67f6059e2bf3d1",
[
null,
{}
@ -471190,7 +471446,7 @@
]
],
"multiple-event-listeners.https.html": [
"207fdd2d9c00b5998601508e33911002697026c0",
"3b13d632ac8a3e4d240b8b4844054f0e9e84193c",
[
null,
{
@ -471199,7 +471455,7 @@
]
],
"null-values.https.html": [
"a6035543ba457fd701f40f89ccacf32f8a0b503e",
"b6a2a1622fe003d6ea02d5ca4620bb95499f4157",
[
null,
{
@ -471217,7 +471473,7 @@
},
"orientation": {
"absolute-fallback.https.html": [
"835d2441b358a1ba3aa3013838b19c3aac531d1f",
"610b1b3c5643246ce8fcf004ddcb2e113aa8c761",
[
null,
{
@ -471235,7 +471491,7 @@
]
],
"basic-operation-absolute.https.html": [
"05ac82cd35f3e373c3590a71bc2541d4dba4897f",
"61fd218781df1b8f6103d1c63d7ab8027db42026",
[
null,
{
@ -471244,7 +471500,7 @@
]
],
"basic-operation.https.html": [
"3806ee0792aeba94e639dddb06b40a9db76bd2f7",
"45fe38006ea2bd68a472b2f1ea3cb4a1a0db7c71",
[
null,
{
@ -471260,7 +471516,7 @@
]
],
"multiple-event-listeners.https.html": [
"13d05f0c745fa0930b74c707ac9381005d4910ba",
"473b7f88284bb7ac9670e22aa1da079763c322ca",
[
null,
{
@ -471278,7 +471534,7 @@
]
],
"null-values.https.html": [
"55039ea2763bbb182b8aaf3ad68904dfa7a90619",
"f9e4aa642052cb3d3d30605c0d97c073510cc555",
[
null,
{
@ -471294,7 +471550,7 @@
]
],
"updates.https.html": [
"de203da0a3af07d6b1d82c5550f8224562c623f2",
"c84588d5985d4a327ce164826fd915bf54a52a8b",
[
null,
{
@ -473725,7 +473981,7 @@
]
},
"idlharness.window.js": [
"90e812598256bc887c81753cf4426efd040870e6",
"b41a65f3ed0e58ab0bdfab55302c0d49cfb7df24",
[
"pointerevents/idlharness.window.html",
{
@ -473737,8 +473993,13 @@
[
"script",
"/resources/idlharness.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
]
],
@ -475177,7 +475438,7 @@
},
"push-api": {
"idlharness.https.any.js": [
"16c0826a7592a4636caa70c53ec7a6bfb0f7b1c3",
"c0e278eb5742b50802f5f40824acba21ed8fc70f",
[
"push-api/idlharness.https.any.html",
{
@ -475197,8 +475458,13 @@
[
"script",
"/service-workers/service-worker/resources/test-helpers.sub.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -475220,8 +475486,13 @@
[
"script",
"/service-workers/service-worker/resources/test-helpers.sub.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -475243,8 +475514,13 @@
[
"script",
"/service-workers/service-worker/resources/test-helpers.sub.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -475266,8 +475542,13 @@
[
"script",
"/service-workers/service-worker/resources/test-helpers.sub.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
]
]
@ -486694,7 +486975,7 @@
},
"screen_enumeration": {
"getScreens.tentative.https.window.js": [
"14079b02c09a5a0b462a3dcd8c2e13965e62d38b",
"76223b7907cd09f971acd0166318d7eb84c84c98",
[
"screen_enumeration/getScreens.tentative.https.window.html",
{
@ -486702,6 +486983,14 @@
[
"global",
"window,dedicatedworker,sharedworker,serviceworker"
],
[
"script",
"/resources/testdriver.js"
],
[
"script",
"/resources/testdriver-vendor.js"
]
]
}
@ -486777,7 +487066,7 @@
]
],
"scroll-animation-inactive-timeline.html": [
"07dae95692eb58d1b0079ecf5b8f5048875ad3a9",
"1c0befa6943bca12c1e200d429f61473bfd2764b",
[
null,
{}
@ -486826,6 +487115,13 @@
null,
{}
]
],
"setting-start-time.html": [
"643f62a9b58b186de441bdb6c3dd5cc70d35fb73",
[
null,
{}
]
]
},
"scroll-to-text-fragment": {
@ -486911,7 +487207,7 @@
]
],
"idlharness.any.js": [
"5bd1d44d6f7d9c299ff41c241802652924ce77b2",
"396dfff1fdff9d65a4f8a5a3308312b5ef5a349d",
[
"secure-contexts/idlharness.any.html",
{
@ -486927,8 +487223,13 @@
[
"script",
"/resources/idlharness.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -486946,8 +487247,13 @@
[
"script",
"/resources/idlharness.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -486965,8 +487271,13 @@
[
"script",
"/resources/idlharness.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
],
[
@ -486984,8 +487295,13 @@
[
"script",
"/resources/idlharness.js"
],
[
"timeout",
"long"
]
]
],
"timeout": "long"
}
]
],
@ -496976,64 +497292,64 @@
{}
]
],
"animate-path-animation-Cc-Ss.html": [
"63c450a6c70cacae1688a5bf4862190c178eb770",
"animate-path-animation-Cc-Ss.tentative.html": [
"69b3cc7af4cf00c301c1e2e6d86641181b356b5a",
[
null,
{}
]
],
"animate-path-animation-Ll-Vv-Hh.html": [
"4f6d85421a64863c604de1b43d0f638cc0c29fcc",
"animate-path-animation-Ll-Vv-Hh.tentative.html": [
"8a1e2cb032f268f3609521d33fa6d4d9d9f96cb7",
[
null,
{}
]
],
"animate-path-animation-Mm-Aa-Z.html": [
"777ca30137576f04fa300a35896b2e325bff0d80",
"animate-path-animation-Mm-Aa-Z.tentative.html": [
"fd0787792f85a6f6b1dcb920b949d484e6fa9cfd",
[
null,
{}
]
],
"animate-path-animation-Qq-Tt.html": [
"d964303fa2ded2efcece490376c08063b255b7f2",
"animate-path-animation-Qq-Tt.tentative.html": [
"e8b0ad8f71aa31aa969eea3e6d66dee36ff79353",
[
null,
{}
]
],
"animate-path-animation-cC-sS-inverse.html": [
"709372706d87679c36d717ad48d27c9f01c4e43e",
"animate-path-animation-cC-sS-inverse.tentative.html": [
"5b19f69b2d2ceec98bba6bcabdc8f43738aaa7d2",
[
null,
{}
]
],
"animate-path-animation-lL-vV-hH-inverse.html": [
"a5c6e88a1b9154822678c7c5c2aeb1d48445dbcd",
"animate-path-animation-lL-vV-hH-inverse.tentative.html": [
"3a96eb294542221fe122aa2facdb286e52da8b6d",
[
null,
{}
]
],
"animate-path-animation-mM-aA-Z-inverse.html": [
"3e7e6e3199a19f5c30cff0a11d42e1457e087146",
"animate-path-animation-mM-aA-Z-inverse.tentative.html": [
"df32a4a2500fc9f3ba2e805c49bd12fc35678bf2",
[
null,
{}
]
],
"animate-path-animation-qQ-tT-inverse.html": [
"85b98d4d5fee9dd03f71194e72479c9b43cf4a8d",
"animate-path-animation-qQ-tT-inverse.tentative.html": [
"6ae4d1f1dcd540d1439c9c364307b514f0fde9c0",
[
null,
{}
]
],
"animate-path-to-animation.html": [
"769113ce4907aeee04146014927aec1a8c385784",
"animate-path-to-animation.tentative.html": [
"a20a33f6a48c4349d947c1872efac9a25864fb8b",
[
null,
{}
@ -497911,8 +498227,8 @@
{}
]
],
"svgpath-animation-1.html": [
"220130532e9fbd223e0ed8b02e1771a06229e3bf",
"svgpath-animation-1.tentative.html": [
"3df821d7c310f6c1607786f14a6c6bafef272fb5",
[
null,
{}
@ -504294,8 +504610,8 @@
}
]
],
"constructor.any.js": [
"f505719d2c5e411ca9debc0076a2b40ded020e1c",
"constructor-shared.tentative.any.js": [
"216fc4ca55591f1fa412aeadf5fd538c3afa0af3",
[
null,
{
@ -504308,6 +504624,71 @@
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
],
[
"wasm/jsapi/memory/constructor-shared.tentative.any.html",
{
"script_metadata": [
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
],
[
"wasm/jsapi/memory/constructor-shared.tentative.any.worker.html",
{
"script_metadata": [
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
]
],
"constructor.any.js": [
"6524c8acc49016e10746d686c860eeba6fd3c16d",
[
null,
{
"jsshell": true,
"script_metadata": [
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
@ -504323,6 +504704,10 @@
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
@ -504338,13 +504723,17 @@
[
"script",
"/wasm/jsapi/assertions.js"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
]
],
"grow.any.js": [
"db9e7813617b96471a90c35c96b85f0926998dc3",
"c511129491f4de423f6d6b3fac71d3bf02192326",
[
null,
{
@ -504353,6 +504742,10 @@
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
@ -504364,6 +504757,10 @@
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}
@ -504375,6 +504772,10 @@
[
"global",
"window,dedicatedworker,jsshell"
],
[
"script",
"/wasm/jsapi/memory/assertions.js"
]
]
}

View file

@ -1,4 +0,0 @@
[hit-test-floats-002.html]
[Hit test float]
expected: FAIL

View file

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

View file

@ -2,3 +2,6 @@
[Hit test intersecting scaled box]
expected: FAIL
[Hit test within unscaled box]
expected: FAIL

View file

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

View file

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

View file

@ -2,3 +2,6 @@
[elementsFromPoint on the root document for points in iframe elements]
expected: FAIL
[elementsFromPoint on inner documents]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementsFromPoint-invalid-cases.html]
[The root element is the last element returned for otherwise empty queries within the viewport]
expected: FAIL

View file

@ -1,2 +0,0 @@
[HTMLMediaElement.html]
expected: TIMEOUT

View file

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

View file

@ -53,9 +53,6 @@
[combined text/javascript ]
expected: FAIL
[separate text/javascript;charset=windows-1252 error text/javascript]
expected: FAIL
[separate text/javascript x/x]
expected: FAIL

View file

@ -11,9 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
[X-Content-Type-Options%3A%20%2Cnosniff]
expected: FAIL
[X-Content-Type-Options%3A%0D%0AX-Content-Type-Options%3A%20nosniff]
[X-Content-Type-Options%3A%20%40%23%24%23%25%25%26%5E%26%5E*()()11!%2Cnosniff]
expected: FAIL

View file

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

View file

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

View file

@ -1,16 +1,20 @@
[supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Element with tabindex should support autofocus]
expected: FAIL
expected: TIMEOUT
[Host element with delegatesFocus including no focusable descendants should be skipped]
expected: FAIL
expected: NOTRUN
[Area element should support autofocus]
expected: FAIL
expected: NOTRUN
[Host element with delegatesFocus should support autofocus]
expected: FAIL
expected: NOTRUN
[Non-HTMLElement should not support autofocus]
expected: NOTRUN

View file

@ -4,6 +4,3 @@
[The incumbent settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: FAIL

View file

@ -0,0 +1,16 @@
[event-handler-sourcetext.html]
[error event handler on disconnected body]
expected: FAIL
[error event handler not on body]
expected: FAIL
[error event handler on connected body, reflected to Window]
expected: FAIL
[error event handler on disconnected frameset]
expected: FAIL
[non-error event handler]
expected: FAIL

View file

@ -0,0 +1,9 @@
[constructor-shared.tentative.any.worker.html]
[Shared memory]
expected: FAIL
[constructor-shared.tentative.any.html]
[Shared memory]
expected: FAIL

View file

@ -0,0 +1,9 @@
[grow.any.worker.html]
[Growing shared memory does not detach old buffer]
expected: FAIL
[grow.any.html]
[Growing shared memory does not detach old buffer]
expected: FAIL

View file

@ -0,0 +1,11 @@
<!doctype html>
<link rel="help" href="https://crbug.com/1077524">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="Grid item in 0-height grid flex-item doesn't get the flexbox's height." />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; display: flex; flex-direction: column; width: 100px; height: 100px;">
<div style="background: blue; display: grid; grid-template-rows: auto;">
<div style="background: red;"></div>
</div>
</div>

View file

@ -0,0 +1,11 @@
<!doctype html>
<link rel="help" href="https://crbug.com/1077524">
<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
<meta name="assert" content="Grid item in 0-height ortho grid flex-item doesn't get the flexbox's height." />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; display: flex; flex-direction: column; width: 100px; height: 100px;">
<div style="background: blue; display: grid; grid-template-rows: auto; writing-mode: vertical-lr;">
<div style="background: red;"></div>
</div>
</div>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: Reverted styles for ::marker</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#marker-pseudo">
<link rel="help" href="https://drafts.csswg.org/web-animations-1/">
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
<meta name="assert" content="This test checks that ::marker can be animated with Web Animations, but only the supported properties." />
<div id="log"></div>
<ul>
<li id="target">list item</li>
</ul>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const target = document.getElementById("target");
const cs = getComputedStyle(target, "::marker");
const options = {
pseudoElement: "::marker",
duration: 2,
delay: -1,
};
// 'color' applies to ::marker so it should be animatable
test(function() {
const anim = target.animate([
{color: "rgb(0, 100, 200)"},
{color: "rgb(200, 0, 100)"},
], options);
this.add_cleanup(() => anim.cancel());
assert_equals(cs.color, "rgb(100, 50, 150)", "color");
}, "'color' animation");
// 'opacity' doesn't apply to ::marker so it shouldn't be animatable
test(function() {
const anim = target.animate([
{opacity: .2},
{opacity: .8},
], options);
this.add_cleanup(() => anim.cancel());
assert_equals(cs.opacity, "1", "opacity");
}, "'opacity' animation");
// When both 'color' and 'opacity' are specified, only the former should be animated.
test(function() {
const anim = target.animate([
{
color: "rgb(0, 100, 200)",
opacity: .2,
},
{
color: "rgb(200, 0, 100)",
opacity: .8,
},
], options);
this.add_cleanup(() => anim.cancel());
assert_equals(cs.color, "rgb(100, 50, 150)", "color");
assert_equals(cs.opacity, "1", "opacity");
}, "'color' + 'opacity' animation");
</script>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; aspect-ratio: 2/1;">
<div style="height: 100px"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<meta name="assert" content="Setting overflow to non-visible/clip should not apply min-height: auto">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; aspect-ratio: 1/1; overflow: hidden;">
<div style="height: 100px"></div>
<div style="height: 500px; background: red;"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="reference/ref-square-with-vertical-scrollbar.html" />
<meta name="assert" content="Setting overflow to non-visible/clip should not apply min-height: auto">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; aspect-ratio: 1/1; overflow: auto;">
<div style="height: 100px"></div>
<div style="height: 500px; background: red;"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="reference/ref-square-with-scrollbar.html" />
<meta name="assert" content="Setting overflow to non-visible/clip should not apply min-height: auto">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; aspect-ratio: 1/1; overflow: scroll;">
<div style="height: 100px"></div>
<div style="height: 500px; background: red;"></div>
</div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<meta name="assert" content="With min-height: auto and content smaller than the aspect ratio size, we should still size per aspect-ratio">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; aspect-ratio: 1/1;">
<div style="height: 50px"></div>
</div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + min-height: auto</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="writing-mode: vertical-lr; background: green; height: 100px; aspect-ratio: 1/2;">
<div style="width: 100px"></div>
</div>

View file

@ -7,7 +7,7 @@
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 100px; aspect-ratio: 1/1;">
<div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 100px; aspect-ratio: 1/1; min-height: 0;">
<div style="background: green; width: 50px; height: 100px;"></div>
<div style="background: green; width: 50px; height: 100px;"></div>
</div>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: Wrapping column flexbox line length</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="help" href="https://drafts.csswg.org/css-flexbox/#line-sizing" title="9.2.3.B">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="display: flex; flex-direction: column; flex-wrap: wrap; width: 200px; aspect-ratio: 4/1;">
<div style="background: green; width: 100px; height: 50px;"></div>
<div style="background: green; width: 100px; height: 50px;"></div>
</div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + percentage resolution</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; aspect-ratio: 1/1;">
<div style="background: green; height: 100%;"></div>
</div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + percentage resolution</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; aspect-ratio: 1/1;">
<div style="background: green; height: 100%; width: 100%; writing-mode: vertical-lr;"></div>
</div>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + percentage resolution</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; aspect-ratio: 1/1; writing-mode: vertical-lr;">
<div style="background: green; height: 100%; width: 100%;"></div>
</div>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>CSS aspect-ratio: div block size + percentage resolution</title>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht" />
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="width: 100px; aspect-ratio: 2/1;"> <!-- height = 100px due to min-height: auto -->
<div style="background: green; height: 50px;"></div>
<div style="background: green; height: 100%;"></div> <!-- should be 50px -->
</div>

View file

@ -12,4 +12,4 @@ onload = function() {
}, "body height is 100");
};
</script>
<body style="width: 100px; aspect-ratio: 1/1;">
<body style="width: 100px; aspect-ratio: 1/1; min-height: 0;">

View file

@ -0,0 +1,15 @@
<!-- quirks mode -->
<title>Aspect ratio and quirks mode</title>
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio">
<link rel="author" title="Google LLC" href="https://www.google.com/">
<meta name="flags" content="dom" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
onload = function() {
test(function() {
assert_equals(document.body.clientHeight, document.documentElement.clientHeight);
}, "body height should match documentElement due to min-height: auto");
};
</script>
<body style="width: 100px; aspect-ratio: 1/1;">

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; height: 100px; overflow: scroll;">
<div style="height: 600px"></div>
</div>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<link rel="author" title="Google LLC" href="https://www.google.com/">
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div style="background: green; width: 100px; height: 100px; overflow-y: scroll;">
<div style="height: 600px"></div>
</div>

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<meta name="assert" content="This test checks that a dynamic change in the height of an element calculates the intrinsic min/max size correctly when a replaced element is present."/>
<p>Test passes if there is a filled green square.</p>
<div id="target" style="float: left; background: green; line-height: 0;">
<span style="display: inline-block; height: 100%;">
<canvas width="1" height="1" style="height: 100%;"></canvas>
</div>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.height = '100px';
</script>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#intrinsic">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<meta name="assert" content="This test checks that a dynamic change in the height of an element calculates the intrinsic min/max size correctly when a replaced element is present."/>
<p>Test passes if there is a filled green square.</p>
<div id="target" style="float: left; background: green; color: transparent;">
<span>
<div style="float: left; height: 100%;">
<canvas width="1" height="1" style="height: 100%;"></canvas>
</div>
</span>
</div>
<script>
document.body.offsetTop;
document.getElementById('target').style.height = '100px';
</script>

View file

@ -73,3 +73,35 @@ test(t => {
}, 'Throwing exception in customized built-in constructor should not crash and should return correct element type (form)');
</script>
<script>
class MyInput extends HTMLInputElement { };
customElements.define('my-input', MyInput, { extends: 'input' });
</script>
<input id=customized-input is='my-input'>
<script>
test(t => {
const input = document.getElementById('customized-input');
assert_true(input instanceof MyInput);
assert_true(input instanceof HTMLInputElement);
}, 'Make sure customized <input> element doesnt crash');
</script>
<script>
class MyInputAttrs extends HTMLInputElement {
constructor() {
super();
this.setAttribute('foo', 'bar');
}
}
customElements.define('my-input-attr', MyInputAttrs, { extends: 'input' });
</script>
<input id=customized-input-attr is='my-input-attr'>
<script>
test(t => {
const input = document.getElementById('customized-input-attr');
assert_true(input instanceof MyInputAttrs);
assert_true(input instanceof HTMLInputElement);
assert_equals(input.getAttribute('foo'),'bar');
}, 'Make sure customized <input> element that sets attributes doesnt crash');
</script>

View file

@ -22,11 +22,10 @@
if (as !== undefined) {
e.setAttribute("as", as);
}
e.onload = e.onerror = t.step_func_done(e => {
e.onload = e.onerror = t.step_func(e => {
fetch("/fetch/metadata/resources/record-header.py?retrieve=true&file=" + key)
.then(t.step_func(response => response.text()))
.then(t.step_func(text => assert_header_equals(text, expected)))
.then(t.step_func_done(_ => resolve()))
.then(t.step_func_done(text => assert_header_equals(text, expected, `preload ${as} ${host}`)))
.catch(t.unreached_func());
});

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Test the sourceText of event handlers</title>
<link rel="help" href="https://github.com/whatwg/html/issues/5500">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
"use strict";
test(() => {
const el = document.createElement("div");
el.setAttribute("onclick", "foo");
assert_equals(el.onclick.toString(), "function onclick(event) {\nfoo\n}");
}, "non-error event handler");
test(() => {
const el = document.createElement("div");
el.setAttribute("onerror", "foo");
assert_equals(el.onerror.toString(), "function onerror(event) {\nfoo\n}");
}, "error event handler not on body");
test(() => {
const el = document.createElement("body");
el.setAttribute("onerror", "foo");
assert_equals(el.onerror.toString(), "function onerror(event, source, lineno, colno, error) {\nfoo\n}");
}, "error event handler on disconnected body");
test(() => {
const el = document.createElement("frameset");
el.setAttribute("onerror", "foo");
assert_equals(el.onerror.toString(), "function onerror(event, source, lineno, colno, error) {\nfoo\n}");
}, "error event handler on disconnected frameset");
test(() => {
document.body.setAttribute("onerror", "foo");
assert_equals(window.onerror.toString(), "function onerror(event, source, lineno, colno, error) {\nfoo\n}");
}, "error event handler on connected body, reflected to Window");
</script>

View file

@ -11,7 +11,7 @@
registration requests on a page, you might need to disable or significantly
increase that limit for the tests below to run.</p>
<script type='text/javascript'>
<script>
test(() => {
assert_idl_attribute(navigator, 'registerProtocolHandler');
}, 'the registerProtocolHandler method should exist on the navigator object');
@ -21,7 +21,7 @@ test(() => {
}, 'the unregisterProtocolHandler method should exist on the navigator object');
/* URL argument */
const valid_urls = [
[
'%s',
'foo/%s',
location.href + '/%s',
@ -31,8 +31,7 @@ const valid_urls = [
location.href + '/%s/bar/baz/',
location.href + '/%s/bar/baz/?foo=1337&bar#baz',
location.href + '/%s/foo/%s/',
];
for (const url of valid_urls) {
].forEach(url => {
test(() => {
navigator.registerProtocolHandler('tel', url, 'foo');
}, 'registerProtocolHandler: Valid URL "' + url + '" should work.');
@ -40,9 +39,10 @@ for (const url of valid_urls) {
test(() => {
navigator.unregisterProtocolHandler('tel', url);
}, 'unregisterProtocolHandler: Valid URL "' + url + '" should work.');
}
});
const invalid_urls1 = [
/* Invalid URLs */
[
'',
'%S',
location.href + '',
@ -50,19 +50,20 @@ const invalid_urls1 = [
location.href + '/%a',
'http://example.com',
'http://[v8.:::]//url=%s',
];
for (const url of invalid_urls1) {
'https://test:test/',
].forEach(url => {
test(() => {
assert_throws_dom('SYNTAX_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); });
}, 'registerProtocolHandler: Invalid URL "' + url + '" should throw SYNTAX_ERR.');
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('x', url, 'foo'); });
}, `registerProtocolHandler: Invalid URL "${url}" should throw (but after scheme)`);
test(() => {
assert_throws_dom('SYNTAX_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); });
}, 'unregisterProtocolHandler: Invalid URL "' + url + '" should throw SYNTAX_ERR.');
}
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('x', url, 'foo'); });
}, `unregisterProtocolHandler: Invalid URL "${url}" should throw (but after scheme)`);
});
const invalid_urls2 = [
[
'http://%s.com',
'http://%s.example.com',
'http://example.com/%s',
@ -73,8 +74,7 @@ const invalid_urls2 = [
`ftp://${location.host}/%s`,
`chrome://${location.host}/%s`,
`foo://${location.host}/%s`,
];
for (const url of invalid_urls2) {
].forEach(url => {
test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler('mailto', url, 'foo'); });
}, 'registerProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.');
@ -82,13 +82,13 @@ for (const url of invalid_urls2) {
test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler('mailto', url); });
}, 'unregisterProtocolHandler: Invalid URL "' + url + '" should throw SECURITY_ERR.');
}
});
/* Protocol argument */
/* Overriding any of the following protocols must never be allowed. That would
* break the browser. */
const denylist = [
[
'about',
'attachment',
'blob',
@ -135,23 +135,22 @@ const denylist = [
'web+dots.are.forbidden',
'web+dashes-are-forbidden',
'web+digits123areforbidden',
'web+UpperCasesAreForbidden',
];
for (const scheme of denylist) {
].forEach(scheme => {
test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler(scheme, location.href + '/%s', 'foo'); });
// https://test:test/ does not parse and does not contain %s, but the scheme check happens first
assert_throws_dom('SECURITY_ERR', () => { navigator.registerProtocolHandler(scheme, 'https://test:test/', 'foo'); });
}, 'registerProtocolHandler: Attempting to override the "' + scheme + '" protocol should throw SECURITY_ERR.');
test(() => {
assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler(scheme, location.href + '/%s'); });
assert_throws_dom('SECURITY_ERR', () => { navigator.unregisterProtocolHandler(scheme, 'https://test:test/'); });
}, 'unregisterProtocolHandler: Attempting to override the "' + scheme + '" protocol should throw SECURITY_ERR.');
}
});
/* The following protocols must be possible to override.
* We're just testing that the call goes through here. Whether or not they
* actually work as handlers is covered by the interactive tests. */
const safelist = [
[
/* safelisted schemes listed in
* https://html.spec.whatwg.org/multipage/system-state.html#safelisted-scheme */
'bitcoin',
@ -184,8 +183,10 @@ const safelist = [
'WebCAL',
'WTAI',
'web+myprotocol',
];
for (const scheme of safelist) {
'web+UpperCasedIsLowercased',
'WEB+seeabove',
'WeB+SeEaBoVe'
].forEach(scheme => {
test(() => {
navigator.registerProtocolHandler(scheme, location.href + '/%s', "foo");
}, 'registerProtocolHandler: overriding the "' + scheme + '" protocol should work');
@ -193,5 +194,5 @@ for (const scheme of safelist) {
test(() => {
navigator.unregisterProtocolHandler(scheme, location.href + '/%s');
}, 'unregisterProtocolHandler: overriding the "' + scheme + '" protocol should work');
}
});
</script>

View file

@ -9,64 +9,90 @@ promise_setup(async t => {
})
promise_test(async t => {
let status = new IdleDetector();
let watcher = new EventWatcher(t, status, ["change"]);
let detector = new IdleDetector();
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
await status.start();
await detector.start();
await initial_state;
assert_true(['active', 'idle'].includes(status.state.user),
'status has a valid user state');
assert_true(['locked', 'unlocked'].includes(status.state.screen),
'status has a valid screen state');
assert_true(['active', 'idle'].includes(detector.userState),
'has a valid user state');
assert_true(['locked', 'unlocked'].includes(detector.screenState),
'has a valid screen state');
}, 'start() basics');
promise_test(async t => {
let used = false;
new IdleDetector({
const detector = new IdleDetector();
detector.start({
get threshold() {
used = true;
return 60000;
}
});
assert_true(used, 'constructor options "threshold" member was used');
}, 'constructor uses threshold property');
assert_true(used, 'start() options "threshold" member was used');
}, 'start() uses threshold property');
promise_test(async t => {
assert_throws_js(TypeError, () => new IdleDetector({threshold: 0}));
}, 'constructor throws with invalid threshold (0)');
let used = false;
const controller = new AbortController();
const detector = new IdleDetector();
detector.start({
get signal() {
used = true;
return controller.signal;
}
});
assert_true(used, 'start() options "signal" member was used');
}, 'start() uses signal property');
promise_test(async t => {
assert_throws_js(TypeError, () => new IdleDetector({threshold: 59000}));
}, 'constructor throws with threshold below minimum (59000)');
const detector = new IdleDetector();
await promise_rejects_js(t, TypeError, detector.start({threshold: 0}));
}, 'start() rejects with invalid threshold (0)');
promise_test(async t => {
new IdleDetector({threshold: 60000});
}, 'constructor allows threshold (60000)');
const detector = new IdleDetector();
await promise_rejects_js(t, TypeError, detector.start({threshold: 59000}));
}, 'start() rejects with threshold below minimum (59000)');
promise_test(async t => {
new IdleDetector({threshold: 61000});
}, 'constructor allows threshold (61000)');
const detector = new IdleDetector();
await detector.start({threshold: 60000});
}, 'start() rejects threshold (60000)');
promise_test(async t => {
assert_throws_js(TypeError, () => new IdleDetector({threshold: null}));
}, 'constructor throws with invalid threshold (null)');
const detector = new IdleDetector();
await detector.start({threshold: 61000});
}, 'start() allows threshold (61000)');
promise_test(async t => {
assert_throws_js(TypeError, () => new IdleDetector({threshold: -1}));
}, 'constructor throws with invalid threshold (-1)');
const detector = new IdleDetector();
await promise_rejects_js(t, TypeError, detector.start({threshold: null}));
}, 'start() rejects with invalid threshold (null)');
promise_test(async t => {
assert_throws_js(TypeError, () => new IdleDetector({threshold: NaN}));
}, 'constructor throws with invalid threshold (NaN)');
const detector = new IdleDetector();
await promise_rejects_js(t, TypeError, detector.start({threshold: -1}));
}, 'start() rejects with invalid threshold (-1)');
promise_test(async t => {
new IdleDetector();
}, 'constructor uses a default value for the threshold when none is passed');
const detector = new IdleDetector();
await promise_rejects_js(t, TypeError, detector.start({threshold: NaN}));
}, 'start() rejects with invalid threshold (NaN)');
promise_test(async t => {
new IdleDetector({threshold: undefined});
}, 'constructor uses a default value for the threshold');
const detector = new IdleDetector();
await detector.start();
}, 'start() uses a default value for the threshold when none is passed');
promise_test(async t => {
const detector = new IdleDetector();
await detector.start({threshold: undefined});
}, 'start() uses a default value for the threshold');

View file

@ -1,24 +1,6 @@
dictionary IdleOptions {
[EnforceRange] unsigned long threshold = 60000;
};
[
SecureContext,
Constructor(optional IdleOptions options),
Exposed=(Window,Worker)
] interface IdleDetector : EventTarget {
readonly attribute IdleState state;
attribute EventHandler onchange;
Promise<any> start();
void stop();
};
[
SecureContext,
Exposed=(Window,Worker)
] interface IdleState {
readonly attribute UserIdleState user;
readonly attribute ScreenIdleState screen;
[EnforceRange] unsigned long threshold;
AbortSignal signal;
};
enum UserIdleState {
@ -30,3 +12,14 @@ enum ScreenIdleState {
"locked",
"unlocked"
};
[
SecureContext,
Exposed=(Window,Worker)
] interface IdleDetector : EventTarget {
constructor();
readonly attribute UserIdleState? userState;
readonly attribute ScreenIdleState? screenState;
attribute EventHandler onchange;
Promise<any> start(optional IdleOptions options = {});
};

View file

@ -6,19 +6,19 @@ promise_test(async t => {
await test_driver.set_permission(
{ name: 'notifications' }, 'denied', false);
let status = new IdleDetector();
await promise_rejects_dom(t, 'NotAllowedError', status.start());
let detector = new IdleDetector();
await promise_rejects_dom(t, 'NotAllowedError', detector.start());
}, "Deny notifications permission should work.");
promise_test(async t => {
await test_driver.set_permission(
{ name: 'notifications' }, 'granted', false);
let status = new IdleDetector();
await status.start();
let detector = new IdleDetector();
await detector.start();
assert_true(['active', 'idle'].includes(status.state.user),
'status has a valid user state');
assert_true(['locked', 'unlocked'].includes(status.state.screen),
'status has a valid screen state');
assert_true(['active', 'idle'].includes(detector.userState),
'has a valid user state');
assert_true(['locked', 'unlocked'].includes(detector.screenState),
'has a valid screen state');
}, "Grant notifications permission should work.");

View file

@ -23,7 +23,7 @@ promise_test(async (t) => {
idl_array.add_dependency_idls(dom);
idl_array.add_dependency_idls(html);
self.idle = new IdleDetector({threshold: 60000});
self.idle = new IdleDetector();
let watcher = new EventWatcher(t, self.idle, ["change"]);
let initial_state = watcher.wait_for("change");
await self.idle.start();
@ -31,7 +31,6 @@ promise_test(async (t) => {
idl_array.add_objects({
IdleDetector: ['idle'],
IdleState: ['idle.state']
});
idl_array.test();

View file

@ -29,17 +29,18 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start();
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.state.user, "active");
assert_equals(detector.state.screen, "locked");
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "locked");
detector.stop();
controller.abort();
}, 'start()');
promise_test(async t => {
@ -63,20 +64,21 @@ promise_test(async t => {
return first;
});
let detector = new IdleDetector({threshold: 60000});
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start();
await detector.start({ signal: controller.signal });
await initial_state;
// Wait for the first change in state.
await watcher.wait_for("change");
assert_equals(detector.state.user, "idle");
assert_equals(detector.state.screen, "unlocked");
assert_equals(detector.userState, "idle");
assert_equals(detector.screenState, "unlocked");
detector.stop();
controller.abort();
}, 'updates once');
@ -108,22 +110,23 @@ promise_test(async t => {
return first;
});
let detector = new IdleDetector({threshold: 60000});
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start();
await detector.start({ signal: controller.signal });
await initial_state;
// Waits for the first event.
await watcher.wait_for("change");
assert_equals(detector.state.user, "idle");
assert_equals(detector.userState, "idle");
// Waits for the second event.
await watcher.wait_for("change");
assert_equals(detector.state.user, "active");
assert_equals(detector.userState, "active");
detector.stop();
controller.abort();
}, 'updates twice');
promise_test(async t => {
@ -137,16 +140,17 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
const controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
await detector.start();
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.state.screen, "locked");
assert_equals(detector.screenState, "locked");
detector.stop();
controller.abort();
}, 'locked screen');
promise_test(async t => {
@ -159,21 +163,22 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
const controller = new AbortController();
const detector = new IdleDetector();
let event = new Promise((resolve, reject) => {
detector.onchange = resolve;
});
await detector.start();
await detector.start({ signal: controller.signal });
// Waits for the first event.
await event;
assert_equals(detector.state.user, "active");
assert_equals(detector.state.screen, "locked");
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "locked");
detector.stop();
controller.abort();
}, 'IdleDetector.onchange');
promise_test(async t => {
@ -186,30 +191,26 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
const controller = new AbortController();
const detector = new IdleDetector();
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
const watcher = new EventWatcher(t, detector, ["change"]);
const initial_state = watcher.wait_for("change");
// Calling start() multiple times should be safe.
await Promise.all([
detector.start(),
detector.start(),
detector.start(),
detector.start()
]);
// Only the first call to start() is allowed.
const start_promise = detector.start();
await promise_rejects_dom(t, 'InvalidStateError', detector.start());
await start_promise;
await initial_state;
assert_equals(detector.state.user, "active");
assert_equals(detector.state.screen, "unlocked");
assert_equals(detector.userState, "active");
assert_equals(detector.screenState, "unlocked");
// Calling stop() multiple times should be safe.
await Promise.all([
detector.stop(),
detector.stop(),
detector.stop(),
detector.stop()
]);
// Calling abort() multiple times is safe.
controller.abort();
controller.abort();
controller.abort();
controller.abort();
}, 'Safe to call start() or stop() multiple times');
promise_test(async t => {
@ -222,21 +223,14 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
const controller = new AbortController();
const detector = new IdleDetector();
// Calling stop() before start() is a no-op.
detector.stop();
// Calling abort() before start() causes start() to fail.
controller.abort();
let watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
await detector.start();
await initial_state;
assert_equals(detector.state.user, "active");
assert_equals(detector.state.screen, "unlocked");
detector.stop();
await promise_rejects_dom(
t, 'AbortError', detector.start({ signal: controller.signal }));
}, 'Calling stop() after start() is a no-op');
promise_test(async t => {
@ -249,15 +243,15 @@ promise_test(async t => {
});
});
let detector = new IdleDetector({threshold: 60000});
let watcher = new EventWatcher(t, detector, ["change"]);
let controller = new AbortController();
const detector = new IdleDetector();
const watcher = new EventWatcher(t, detector, ["change"]);
let initial_state = watcher.wait_for("change");
await detector.start();
await detector.start({ signal: controller.signal });
await initial_state;
detector.stop();
controller.abort();
expect(addMonitor).andReturn((threshold, monitorPtr) => {
return Promise.resolve({
@ -269,13 +263,15 @@ promise_test(async t => {
});
// Restarting the monitor.
initial_state = watcher.wait_for("change");
await detector.start();
await initial_state;
assert_equals(detector.state.user, "idle");
assert_equals(detector.state.screen, "locked");
controller = new AbortController();
detector.stop();
initial_state = watcher.wait_for("change");
await detector.start({ signal: controller.signal });
await initial_state;
assert_equals(detector.userState, "idle");
assert_equals(detector.screenState, "locked");
controller.abort();
}, 'Calling start() after stop(): re-starting monitor.');
</script>

View file

@ -7,7 +7,7 @@ idl_test(
['../idle-detection/idle-detection'],
['dom', 'html'],
async (idl_array, t) => {
self.idle = new IdleDetector({threshold: 60000});
self.idle = new IdleDetector();
let watcher = new EventWatcher(t, self.idle, ["change"]);
let initial_state = watcher.wait_for("change");
await self.idle.start();
@ -15,7 +15,6 @@ idl_test(
idl_array.add_objects({
IdleDetector: ['idle'],
IdleState: ['idle.state']
});
}
);

View file

@ -1,5 +1,5 @@
// Abstracts expectations for reuse in different test frameworks.
cls_expect = (watcher, expectation) => {
assert_equals(watcher.score, expectation.score);
watcher.checkExpectation(expectation);
};

View file

@ -68,3 +68,22 @@ ScoreWatcher = function() {
});
observer.observe({entryTypes: ['layout-shift']});
};
ScoreWatcher.prototype.checkExpectation = function(expectation) {
if (expectation.score)
assert_equals(this.score, expectation.score);
if (expectation.sources)
check_sources(expectation.sources, this.lastEntry.sources);
};
check_sources = (expect_sources, actual_sources) => {
assert_equals(expect_sources.length, actual_sources.length);
let rect_match = (e, a) =>
e[0] == a.x && e[1] == a.y && e[2] == a.width && e[3] == a.height;
let match = e => a =>
e.node === a.node &&
rect_match(e.previousRect, a.previousRect) &&
rect_match(e.currentRect, a.currentRect);
for (let e of expect_sources)
assert_true(actual_sources.some(match(e)), e.node + " not found");
};

View file

@ -1,14 +1,14 @@
<!DOCTYPE html>
<title>Layout Instability: simple block movement is detected</title>
<link rel="help" href="https://wicg.github.io/layout-instability/" />
<style>
#shifter { position: relative; width: 300px; height: 200px; }
</style>
<div id="shifter"></div>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-adapter.js"></script>
<script src="resources/util.js"></script>
<style>
#shifter { position: relative; width: 300px; height: 200px; }
</style>
<div id="shifter"></div>
<script>
promise_test(async () => {

View file

@ -0,0 +1,62 @@
<!DOCTYPE html>
<title>Layout Instability: source attribution with redundant enclosure</title>
<link rel="help" href="https://wicg.github.io/layout-instability/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-adapter.js"></script>
<script src="resources/util.js"></script>
<style>
body { margin: 0; }
#shifter {
position: relative; background: #def;
width: 300px; height: 200px;
}
#inner {
position: relative; background: #f97;
width: 100px; height: 100px;
}
#absfollow {
position: absolute; background: #ffd; opacity: 50%;
width: 350px; height: 200px; left: 0; top: 160px;
}
.stateB { top: 160px; }
.stateB #inner { left: 100px; }
.stateC ~ #absfollow { top: 0; }
</style>
<div id="shifter" class="stateA">
<div id="inner"></div>
</div>
<div id="absfollow"></div>
<script>
promise_test(async () => {
const watcher = new ScoreWatcher;
let shifter = document.querySelector("#shifter");
let absfollow = document.querySelector("#absfollow");
// Wait for the initial render to complete.
await waitForAnimationFrames(2);
shifter.className = "stateB";
await watcher.promise;
// Shift of #inner ignored as redundant, fully enclosed by #shifter.
cls_expect(watcher, {sources: [{
node: shifter,
previousRect: [0, 0, 300, 200],
currentRect: [0, 160, 300, 200]
}]});
shifter.className = "stateC";
await watcher.promise;
// Shift of #shifter ignored as redundant, fully enclosed by #absfollow.
cls_expect(watcher, {sources: [{
node: absfollow,
previousRect: [0, 160, 350, 200],
currentRect: [0, 0, 350, 200]
}]});
}, "Sources with redundant enclosure.");
</script>

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<title>Layout Instability: source attribution prioritization</title>
<link rel="help" href="https://wicg.github.io/layout-instability/" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-adapter.js"></script>
<script src="resources/util.js"></script>
<style>
body { margin: 0; }
#a, #b, #c, #d, #e, #f {
display: inline-block;
background: gray;
min-width: 10px;
min-height: 10px;
vertical-align: top;
}
#a { width: 30px; height: 30px; }
#b { width: 20px; height: 20px; }
#c { height: 50px; }
#d { width: 50px; }
#e { width: 40px; height: 30px; }
#f { width: 30px; height: 40px; }
</style>
<div id="grow"></div>
<div id="a"></div
><div id="b"></div
><div id="c"></div
><div id="d"></div
><div id="e"></div
><div id="f"></div>
<script>
let $ = id => document.querySelector(id);
promise_test(async () => {
const watcher = new ScoreWatcher;
// Wait for the initial render to complete.
await waitForAnimationFrames(2);
$("#grow").style.height = "50px";
await watcher.promise;
cls_expect(watcher, {sources: [
{
node: $("#a"),
previousRect: [0, 0, 30, 30],
currentRect: [0, 50, 30, 30]
},
{
node: $("#f"),
previousRect: [150, 0, 30, 40],
currentRect: [150, 50, 30, 40]
},
{
node: $("#c"),
previousRect: [50, 0, 10, 50],
currentRect: [50, 50, 10, 50]
},
{
node: $("#d"),
previousRect: [60, 0, 50, 10],
currentRect: [60, 50, 50, 10]
},
{
node: $("#e"),
previousRect: [110, 0, 40, 30],
currentRect: [110, 50, 40, 30]
}
]});
}, "Source attribution prioritizes by impact.");
</script>

View file

@ -11,32 +11,16 @@ sensor_test(async (t, sensorProvider) => {
const motionData1 = generateMotionData(1, 2, 3,
4, 5, 6,
7, 8, 9);
setMockMotionData(sensorProvider, motionData1);
await Promise.all([
waitForEvent(getExpectedMotionEvent(motionData1)),
waitForEvent(getExpectedMotionEvent(motionData1))
]);
const motionData2 = generateMotionData(11, 12, 13,
14, 15, 16,
17, 18, 19);
let firstListener = null;
let firstEventPromise = new Promise(resolve => {
firstListener = resolve;
});
// We directly add the listener instead of using EventWatcher
// because we want to remove listener after the first event fires
// but EventWatcher could only stop watching after test done.
window.addEventListener('devicemotion', firstListener);
const watcher = new EventWatcher(t, window, ['devicemotion']);
setMockMotionData(sensorProvider, motionData1);
let firstEvent = await firstEventPromise;
assertEventEquals(firstEvent, getExpectedMotionEvent(motionData1));
let secondEvent = await watcher.wait_for('devicemotion');
assertEventEquals(secondEvent, getExpectedMotionEvent(motionData1));
window.removeEventListener('devicemotion', firstListener);
// At this point only the second event listener is active.
setMockMotionData(sensorProvider, motionData2);
let thirdEvent = await watcher.wait_for('devicemotion');
assertEventEquals(thirdEvent, getExpectedMotionEvent(motionData2));
await waitForEvent(getExpectedMotionEvent(motionData2));
}, 'Tests using multiple event handlers for the Device Motion API.');
</script>

View file

@ -24,21 +24,16 @@ sensor_test(async (t, sensorProvider) => {
null, null, null,
null, null, null);
const watcher = new EventWatcher(t, window, ['devicemotion']);
setMockMotionData(sensorProvider, motionData1);
const firstEvent = await watcher.wait_for('devicemotion');
assertEventEquals(firstEvent, getExpectedMotionEvent(motionData1));
await waitForEvent(getExpectedMotionEvent(motionData1));
setMockMotionData(sensorProvider, motionData2);
const secondEvent = await watcher.wait_for('devicemotion');
assertEventEquals(secondEvent, getExpectedMotionEvent(motionData2));
await waitForEvent(getExpectedMotionEvent(motionData2));
setMockMotionData(sensorProvider, motionData3);
const thirdEvent = await watcher.wait_for('devicemotion');
assertEventEquals(thirdEvent, getExpectedMotionEvent(motionData3));
await waitForEvent(getExpectedMotionEvent(motionData3));
setMockMotionData(sensorProvider, motionData4);
const fourthEvent = await watcher.wait_for('devicemotion');
assertEventEquals(fourthEvent, getExpectedMotionEvent(motionData4));
await waitForEvent(getExpectedMotionEvent(motionData4));
}, 'Tests using null values for some or all of the event properties.');
</script>
</script>

View file

@ -9,13 +9,11 @@
sensor_test(async (t, sensorProvider) => {
const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
const watcher = new EventWatcher(t, window, ['deviceorientation']);
// Make the relative orientation sensor unavailable and set mock data for
// the absolute one.
sensorProvider.setGetSensorShouldFail('RelativeOrientationEulerAngles', true);
setMockOrientationData(sensorProvider, orientationData);
const event = await watcher.wait_for('deviceorientation');
assertEventEquals(event, getExpectedOrientationEvent(orientationData));
return waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData));
}, 'Tests that deviceorientation falls back to using absolute orientation data if relative is unavailable.');
</script>

View file

@ -9,11 +9,8 @@
sensor_test(async (t, sensorProvider) => {
const orientationData = generateOrientationData(1.1, 2.2, 3.3, true);
const watcher = new EventWatcher(t, window, ['deviceorientationabsolute']);
setMockOrientationData(sensorProvider, orientationData);
const event = await watcher.wait_for('deviceorientationabsolute');
assertEventEquals(event, getExpectedAbsoluteOrientationEvent(orientationData));
return waitForEvent(getExpectedAbsoluteOrientationEvent(orientationData));
}, 'Tests basic operation of deviceorientationabsolute event using mock data.');
sensor_test(async (t, sensorProvider) => {

View file

@ -9,11 +9,8 @@
sensor_test(async (t, sensorProvider) => {
const orientationData = generateOrientationData(1.1, 2.2, 3.3, false);
const watcher = new EventWatcher(t, window, ['deviceorientation']);
setMockOrientationData(sensorProvider, orientationData);
const event = await watcher.wait_for('deviceorientation');
assertEventEquals(event, getExpectedOrientationEvent(orientationData));
return waitForEvent(getExpectedOrientationEvent(orientationData));
}, 'Tests basic operation of deviceorientation event using mock data.');
sensor_test(async (t, sensorProvider) => {

View file

@ -9,30 +9,14 @@
sensor_test(async (t, sensorProvider) => {
const orientationData1 = generateOrientationData(1, 2, 3, false);
const orientationData2 = generateOrientationData(11, 12, 13, false);
let firstListener = null;
let firstEventPromise = new Promise(resolve => {
firstListener = resolve;
});
// We directly add the listener instead of using EventWatcher
// because we want to remove listener after the first event fires
// but EventWatcher could only stop watching after test done.
window.addEventListener('deviceorientation', firstListener);
const watcher = new EventWatcher(t, window, ['deviceorientation']);
setMockOrientationData(sensorProvider, orientationData1);
await Promise.all([
waitForEvent(getExpectedOrientationEvent(orientationData1)),
waitForEvent(getExpectedOrientationEvent(orientationData1))
]);
let firstEvent = await firstEventPromise;
assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
let secondEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData1));
window.removeEventListener('deviceorientation', firstListener);
// At this point only the second event listener is still active.
const orientationData2 = generateOrientationData(11, 12, 13, false);
setMockOrientationData(sensorProvider, orientationData2);
let thirdEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(thirdEvent, getExpectedOrientationEvent(orientationData2));
await waitForEvent(getExpectedOrientationEvent(orientationData2));
}, 'Tests using multiple event handlers for the Device Orientation API.');
</script>

View file

@ -15,21 +15,16 @@ sensor_test(async (t, sensorProvider) => {
// will stop updating the sensor when it sees a null event.
const orientationData4 = generateOrientationData(null, null, null, false);
const watcher = new EventWatcher(t, window, ['deviceorientation']);
setMockOrientationData(sensorProvider, orientationData1);
const firstEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
await waitForEvent(getExpectedOrientationEvent(orientationData1));
setMockOrientationData(sensorProvider, orientationData2);
const secondEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData2));
await waitForEvent(getExpectedOrientationEvent(orientationData2));
setMockOrientationData(sensorProvider, orientationData3);
const thirdEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(thirdEvent, getExpectedOrientationEvent(orientationData3));
await waitForEvent(getExpectedOrientationEvent(orientationData3));
setMockOrientationData(sensorProvider, orientationData4);
const fourthEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(fourthEvent, getExpectedOrientationEvent(orientationData4));
await waitForEvent(getExpectedOrientationEvent(orientationData4));
}, 'Tests using null values for some of the event properties.');
</script>

View file

@ -9,15 +9,11 @@
sensor_test(async (t, sensorProvider) => {
const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
const watcher = new EventWatcher(t, window, ['deviceorientation']);
setMockOrientationData(sensorProvider, orientationData1);
const firstEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(firstEvent, getExpectedOrientationEvent(orientationData1));
await waitForEvent(getExpectedOrientationEvent(orientationData1));
const orientationData2 = generateOrientationData(11.1, 22.2, 33.3, false);
setMockOrientationData(sensorProvider, orientationData2);
const secondEvent = await watcher.wait_for('deviceorientation');
assertEventEquals(secondEvent, getExpectedOrientationEvent(orientationData2));
await waitForEvent(getExpectedOrientationEvent(orientationData2));
}, 'Tests that updates to the orientation causes new events to fire.');
</script>

View file

@ -179,3 +179,12 @@ function getExpectedMotionEvent(expectedMotionData) {
interval: expectedMotionData.interval,
});
}
function waitForEvent(expected_event) {
return new Promise(resolve => {
window.addEventListener(expected_event.type, (event) => {
assertEventEquals(event, expected_event);
resolve();
}, { once: true });
});
}

View file

@ -1,5 +1,6 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: timeout=long
'use strict';

View file

@ -2,6 +2,7 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
// META: timeout=long
// https://w3c.github.io/push-api/

View file

@ -1527,21 +1527,4 @@ class MockXRPresentationProvider {
}
}
// This is a temporary workaround for the fact that spinning up webxr before
// the mojo interceptors are created will cause the interceptors to not get
// registered, so we have to create this before we query xr;
const XRTest = new ChromeXRTest();
// This test API is also used to run Chrome's internal legacy VR tests; however,
// those fail if navigator.xr has been used. Those tests will set a bool telling
// us not to try to check navigator.xr
if ((typeof legacy_vr_test === 'undefined') || !legacy_vr_test) {
// Some tests may run in the http context where navigator.xr isn't exposed
// This should just be to test that it isn't exposed, but don't try to set up
// the test framework in this case.
if (navigator.xr) {
navigator.xr.test = XRTest;
}
} else {
navigator.vr = { test: XRTest };
}
navigator.xr.test = new ChromeXRTest();

View file

@ -1,4 +1,6 @@
// META: global=window,dedicatedworker,sharedworker,serviceworker
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
'use strict';
promise_test(async testCase => {
@ -6,6 +8,7 @@ promise_test(async testCase => {
}, 'self.getScreens is present');
promise_test(async testCase => {
await test_driver.set_permission({name: 'window-placement'}, 'granted');
const screens = await self.getScreens();
assert_greater_than(screens.length, 0);
@ -27,4 +30,10 @@ promise_test(async testCase => {
assert_equals(typeof screens[0].scaleFactor, 'number');
assert_equals(typeof screens[0].id, 'string');
assert_equals(typeof screens[0].touchSupport, 'boolean');
}, 'self.getScreens returns at least 1 Screen');
}, 'self.getScreens returns at least 1 Screen with permission granted');
promise_test(async testCase => {
await test_driver.set_permission({name: 'window-placement'}, 'denied');
const screens = await self.getScreens();
assert_equals(screens.length, 0);
}, 'self.getScreens returns no Screen objects with permission denied');

View file

@ -63,6 +63,38 @@ promise_test(async t => {
}, 'Animation start and current times are correct if scroll timeline is ' +
'activated after animation.play call.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const target = animation.effect.target;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Set start time when the timeline is inactive.
animation.startTime = 0;
assert_equals(animation.currentTime, null,
'Sanity check current time is unresolved when the timeline is inactive.');
// Make the scroll timeline active.
scroller.style.overflow = 'auto';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_equals(animation.currentTime, 0,
'Animation current time is resolved when the timeline is active.');
assert_equals(animation.startTime, 0,
'Animation start time is resolved.');
assert_times_equal(
animation.effect.getComputedTiming().localTime, 0,
'Effect local time is resolved when the timeline is active.');
assert_equals(Number(getComputedStyle(target).opacity), 0,
'Animation has an effect when the timeline is active.');
}, 'Animation start and current times are correct if scroll timeline is ' +
'activated after setting start time.');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;

View file

@ -0,0 +1,339 @@
<!DOCTYPE html>
<meta charset=utf-8>
<title>Setting the start time of scroll animation</title>
<link rel="help" href="https://drafts.csswg.org/web-animations/#setting-the-start-time-of-an-animation">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="testcommon.js"></script>
<style>
.scroller {
overflow: auto;
height: 200px;
width: 100px;
}
.contents {
height: 1000px;
width: 100%;
}
</style>
<body>
<div id="log"></div>
<script>
'use strict';
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// So long as a hold time is set, querying the current time will return
// the hold time.
// Since the start time is unresolved at this point, setting the current time
// will set the hold time
animation.currentTime = 300;
assert_equals(animation.startTime, null, 'The start time stays unresolved');
assert_times_equal(animation.currentTime, 300,
'The current time is calculated from the hold time');
// If we set the start time, however, we should clear the hold time.
animation.startTime = 0;
assert_times_equal(animation.startTime, 0,
'The start time is set to the requested value');
assert_times_equal(animation.currentTime, 200,
'The current time is calculated from the start time, not' +
' the hold time');
// Sanity check
assert_equals(animation.playState, 'running',
'Animation reports it is running after setting a resolved ' +
'start time');
}, 'Setting the start time clears the hold time');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive');
// So long as a hold time is set, querying the current time will return
// the hold time.
// Since the start time is unresolved at this point, setting the current time
// will set the hold time
animation.currentTime = 300;
assert_equals(animation.startTime, null, 'The start time stays unresolved');
assert_times_equal(animation.currentTime, 300,
'The current time is calculated from the hold time');
// If we set the start time, however, we should clear the hold time.
animation.startTime = 0;
assert_times_equal(animation.startTime, 0,
'The start time is set to the requested value');
assert_equals(animation.currentTime, null,
'The current time is calculated from the start time, not' +
' the hold time');
// Sanity check
assert_equals(animation.playState, 'running',
'Animation reports it is running after setting a resolved ' +
'start time');
}, 'Setting the start time clears the hold time when the timeline is inactive');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
const maxScroll = scroller.scrollHeight - scroller.clientHeight;
scroller.scrollTop = 0.2 * maxScroll;
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Set up a running animation (i.e. both start time and current time
// are resolved).
animation.startTime = 50;
assert_equals(animation.playState, 'running');
assert_times_equal(animation.startTime, 50,
'The start time is set to the requested value');
assert_times_equal(animation.currentTime, 150,
'Current time is resolved for a running animation');
// Clear start time
animation.startTime = null;
assert_equals(animation.startTime, null,
'The start time is set to the requested value');
assert_times_equal(animation.currentTime, 150,
'Hold time is set after start time is made unresolved');
assert_equals(animation.playState, 'paused',
'Animation reports it is paused after setting an unresolved'
+ ' start time');
}, 'Setting an unresolved start time sets the hold time');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive');
// Set up a running animation (i.e. both start time and current time
// are resolved).
animation.startTime = 50;
assert_equals(animation.playState, 'running');
assert_times_equal(animation.startTime, 50,
'The start time is set to the requested value');
assert_equals(animation.currentTime, null,
'Current time is unresolved for a running animation when the ' +
'timeline is inactive');
// Clear start time
animation.startTime = null;
assert_equals(animation.startTime, null,
'The start time is set to the requested value');
assert_equals(animation.currentTime, null,
'Hold time is set to unresolved after start time is made ' +
'unresolved');
assert_equals(animation.playState, 'idle',
'Animation reports it is idle after setting an unresolved'
+ ' start time');
}, 'Setting an unresolved start time sets the hold time to unresolved when ' +
'the timeline is inactive');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
let readyPromiseCallbackCalled = false;
animation.ready.then(() => { readyPromiseCallbackCalled = true; } );
// Put the animation in the play-pending state
animation.play();
// Sanity check
assert_true(animation.pending && animation.playState === 'running',
'Animation is in play-pending state');
// Setting the start time should resolve the 'ready' promise, i.e.
// it should schedule a microtask to run the promise callbacks.
animation.startTime = 100;
assert_times_equal(animation.startTime, 100,
'The start time is set to the requested value');
assert_false(readyPromiseCallbackCalled,
'Ready promise callback is not called synchronously');
// If we schedule another microtask then it should run immediately after
// the ready promise resolution microtask.
await Promise.resolve();
assert_true(readyPromiseCallbackCalled,
'Ready promise callback called after setting startTime');
}, 'Setting the start time resolves a pending ready promise');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive');
let readyPromiseCallbackCalled = false;
animation.ready.then(() => { readyPromiseCallbackCalled = true; } );
// Put the animation in the play-pending state
animation.play();
// Sanity check
assert_true(animation.pending && animation.playState === 'running',
'Animation is in play-pending state');
// Setting the start time should resolve the 'ready' promise, i.e.
// it should schedule a microtask to run the promise callbacks.
animation.startTime = 100;
assert_times_equal(animation.startTime, 100,
'The start time is set to the requested value');
assert_false(readyPromiseCallbackCalled,
'Ready promise callback is not called synchronously');
// If we schedule another microtask then it should run immediately after
// the ready promise resolution microtask.
await Promise.resolve();
assert_true(readyPromiseCallbackCalled,
'Ready promise callback called after setting startTime');
}, 'Setting the start time resolves a pending ready promise when the timeline' +
'is inactive');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Put the animation in the play-pending state
animation.play();
// Sanity check
assert_true(animation.pending, 'Animation is pending');
assert_equals(animation.playState, 'running', 'Animation is play-pending');
assert_times_equal(animation.startTime, 0, 'Start time is zero');
// Setting start time should cancel the pending task.
animation.startTime = null;
assert_false(animation.pending, 'Animation is no longer pending');
assert_equals(animation.playState, 'paused', 'Animation is paused');
}, 'Setting an unresolved start time on a play-pending animation makes it'
+ ' paused');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
const scroller = animation.timeline.scrollSource;
// Make the scroll timeline inactive.
scroller.style.overflow = 'visible';
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
assert_equals(animation.timeline.currentTime, null,
'Sanity check the timeline is inactive');
// Put the animation in the play-pending state
animation.play();
// Sanity check
assert_true(animation.pending, 'Animation is pending');
assert_equals(animation.playState, 'running', 'Animation is play-pending');
assert_times_equal(animation.startTime, 0, 'Start time is zero');
// Setting start time should cancel the pending task.
animation.startTime = null;
assert_false(animation.pending, 'Animation is no longer pending');
assert_equals(animation.playState, 'idle', 'Animation is idle');
}, 'Setting an unresolved start time on a play-pending animation makes it'
+ ' idle when the timeline is inactive');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
// Set start time such that the current time is past the end time
animation.startTime = -1100;
assert_times_equal(animation.startTime, -1100,
'The start time is set to the requested value');
assert_equals(animation.playState, 'finished',
'Seeked to finished state using the startTime');
// If the 'did seek' flag is true, the current time should be greater than
// the effect end.
assert_greater_than(animation.currentTime,
animation.effect.getComputedTiming().endTime,
'Setting the start time updated the finished state with'
+ ' the \'did seek\' flag set to true');
// Furthermore, that time should persist if we have correctly updated
// the hold time
const finishedCurrentTime = animation.currentTime;
await waitForNextFrame();
assert_equals(animation.currentTime, finishedCurrentTime,
'Current time does not change after seeking past the effect'
+ ' end time by setting the current time');
}, 'Setting the start time updates the finished state');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
assert_equals(animation.playState, 'running');
// Setting the start time updates the finished state. The hold time is not
// constrained by the effect end time.
animation.startTime = -1100;
assert_equals(animation.playState, 'finished');
assert_times_equal(animation.currentTime, 1100);
}, 'Setting the start time on a running animation updates the play state');
promise_test(async t => {
const animation = createScrollLinkedAnimation(t);
// Wait for new animation frame which allows the timeline to compute new
// current time.
await waitForNextFrame();
animation.play();
await animation.ready;
// Setting the start time updates the finished state. The hold time is not
// constrained by the normal range of the animation time.
animation.currentTime = 1000;
assert_equals(animation.playState, 'finished', 'Animation is finished');
animation.playbackRate = -1;
assert_equals(animation.playState, 'running', 'Animation is running');
animation.startTime = -2000;
assert_equals(animation.playState, 'finished', 'Animation is finished');
assert_times_equal(animation.currentTime, -2000);
}, 'Setting the start time on a reverse running animation updates the play '
+ 'state');
</script>
</body>

View file

@ -1,6 +1,7 @@
// META: global=window,worker
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: timeout=long
// https://w3c.github.io/webappsec-secure-contexts/

View file

@ -1,24 +1,19 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<title>Path animation where coordinate modes of start and end differ (C-c and S-s)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", "M -20 -20 C 20 -20 20 -20 20 20 S 20 40 -20 20 Z");
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
@ -33,33 +28,35 @@ rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M -20 -20 C 20 -20 20 -20 20 20 S 20 40 -20 20 Z");
// Check initial/end conditions
assert_animated_path_equals(
path, "M -20 -20 C 20 -20 20 -20 20 20 S 20 40 -20 20 Z");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M -20 -20 C 10 -10 10 -10 20 20 S 30 35 -10 10 Z");
assert_animated_path_equals(
path, "M -20 -20 c 30 10 30 10 40 40 s 10 15 -30 -10 Z");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M -20 -20 c 10 30 10 30 40 40 s 30 5 -10 -30 Z");
assert_animated_path_equals(
path, "M -20 -20 c 10 30 10 30 40 40 s 30 5 -10 -30 Z");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M -20 -20 c 0.00999832 39.99 0.00999832 39.99 40 40 s 39.99 0.00499916 -0.00999832 -39.99 Z");
assert_animated_path_equals(
path, "M -20 -20 c 0.00999832 39.99 0.00999832 39.99 40 40 s 39.99 0.00499916 -0.00999832 -39.99 Z");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>
</script>

View file

@ -1,24 +1,19 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<title>Path animation where coordinate modes of start and end differ (L-l, V-v and H-h)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", "M -30 -30 L 30 0 V 30 H 0 Z");
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
@ -33,33 +28,31 @@ rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M -30 -30 L 30 0 V 30 H 0 Z");
// Check initial/end conditions
assert_animated_path_equals(path, "M -30 -30 L 30 0 V 30 H 0 Z");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M -15 -15 L 15 0 V 15 H 0 Z");
assert_animated_path_equals(path, "M -15 -15 l 30 15 v 15 h -15 Z");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M 15 15 l -30 -15 v -15 h 15 Z");
assert_animated_path_equals(path, "M 15 15 l -30 -15 v -15 h 15 Z");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M 29.985 29.985 l -59.97 -29.985 v -29.985 h 29.985 Z");
assert_animated_path_equals(path, "M 29.985 29.985 l -59.97 -29.985 v -29.985 h 29.985 Z");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>
</script>

View file

@ -1,65 +0,0 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
animate.setAttribute("id", "animation");
animate.setAttribute("attributeName", "d");
animate.setAttribute("from", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
animate.setAttribute("to", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
animate.setAttribute("begin", "0s");
animate.setAttribute("dur", "4s");
path.appendChild(animate);
rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M -77.5 37.5 A 152.5 162.5 37.5 1 1 -2.5 92.5 M 57.5 80 A 172.5 182.5 97.5 1 1 277.5 222.5 Z M 282.5 95");
}
function sample3() {
assert_equals(path.getAttribute('d'), "m -72.5 32.5 a 157.5 167.5 52.5 1 1 65 45 m 100 42.5 a 177.5 187.5 112.5 1 1 140 147.5 Z m 155 -35");
}
function sample4() {
assert_equals(path.getAttribute('d'), "m -70.0025 30.0025 a 159.997 169.997 59.9925 1 1 60.005 40.005 m 119.98 69.9725 a 179.997 189.997 119.993 1 1 100.04 149.998 Z m 120.035 -59.975");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>

View file

@ -0,0 +1,62 @@
<!doctype html>
<meta charset="utf-8">
<title>Path animation where coordinate modes of start and end differ (M-m, A-a and Z)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
path.setAttribute("fill", "green");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
animate.setAttribute("id", "animation");
animate.setAttribute("attributeName", "d");
animate.setAttribute("from", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
animate.setAttribute("to", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
animate.setAttribute("begin", "0s");
animate.setAttribute("dur", "4s");
path.appendChild(animate);
rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_animated_path_equals(
path, "M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100");
}
function sample2() {
assert_animated_path_equals(
path, "m -77.5 37.5 a 152.5 162.5 37.5 1 1 75 55 m 60 -12.5 a 172.5 182.5 97.5 1 1 220 142.5 Z m 225 15");
}
function sample3() {
assert_animated_path_equals(
path, "m -72.5 32.5 a 157.5 167.5 52.5 1 1 65 45 m 100 42.5 a 177.5 187.5 112.5 1 1 140 147.5 Z m 155 -35");
}
function sample4() {
assert_animated_path_equals(
path, "m -70.0025 30.0025 a 159.997 169.997 59.9925 1 1 60.005 40.005 m 119.98 69.9725 a 179.997 189.997 119.993 1 1 100.04 149.998 Z m 120.035 -59.975");
}
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>

View file

@ -1,24 +1,19 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<title>Path animation where coordinate modes of start and end differ (Q-q and T-t)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", "M -30 -30 Q 30 -30 30 0 T -30 30 Z");
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
@ -33,33 +28,31 @@ rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M -30 -30 Q 30 -30 30 0 T -30 30 Z");
// Check initial/end conditions
assert_animated_path_equals(path, "M -30 -30 Q 30 -30 30 0 T -30 30 Z");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M -30 -30 Q 22.5 -30 22.5 0 T -30 30 Z");
assert_animated_path_equals(path, "M -30 -30 q 52.5 0 52.5 30 t -52.5 30 Z");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M -30 -30 q 37.5 0 37.5 30 t -37.5 30 Z");
assert_animated_path_equals(path, "M -30 -30 q 37.5 0 37.5 30 t -37.5 30 Z");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M -30 -30 q 30.0075 0 30.0075 30 t -30.0075 30 Z");
assert_animated_path_equals(path, "M -30 -30 q 30.0075 0 30.0075 30 t -30.0075 30 Z");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>
</script>

View file

@ -1,24 +1,19 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<title>Path animation where coordinate modes of start and end differ (c-C and s-S)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", "M -20 -20 c 0 40 0 40 40 40 s 40 0 0 -40 Z");
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
@ -33,33 +28,35 @@ rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M -20 -20 c 0 40 0 40 40 40 s 40 0 0 -40 Z");
// Check initial/end conditions
assert_animated_path_equals(
path, "M -20 -20 c 0 40 0 40 40 40 s 40 0 0 -40 Z");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M -20 -20 c 10 30 10 30 40 40 s 30 5 -10 -30 Z");
assert_animated_path_equals(
path, "M -20 -20 C -10 10 -10 10 20 20 S 50 25 10 -10 Z");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M -20 -20 C 10 -10 10 -10 20 20 S 30 35 -10 10 Z");
assert_animated_path_equals(
path, "M -20 -20 C 10 -10 10 -10 20 20 S 30 35 -10 10 Z");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M -20 -20 C 19.99 -19.99 19.99 -19.99 20 20 S 20.01 39.995 -19.99 19.99 Z");
assert_animated_path_equals(
path, "M -20 -20 C 19.99 -19.99 19.99 -19.99 20 20 S 20.01 39.995 -19.99 19.99 Z");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>
</script>

View file

@ -1,24 +1,19 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<title>Path animation where coordinate modes of start and end differ (l-L, v-V and h-H)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", "M 30 30 l -60 -30 v -30 h 30 Z");
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
@ -33,33 +28,31 @@ rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "M 30 30 l -60 -30 v -30 h 30 Z");
// Check initial/end conditions
assert_animated_path_equals(path, "M 30 30 l -60 -30 v -30 h 30 Z");
}
function sample2() {
assert_equals(path.getAttribute('d'), "M 15 15 l -30 -15 v -15 h 15 Z");
assert_animated_path_equals(path, "M 15 15 L -15 0 V -15 H 0 Z");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M -15 -15 L 15 0 V 15 H 0 Z");
assert_animated_path_equals(path, "M -15 -15 L 15 0 V 15 H 0 Z");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M -29.985 -29.985 L 29.985 0 V 29.985 H 0 Z");
assert_animated_path_equals(path, "M -29.985 -29.985 L 29.985 0 V 29.985 H 0 Z");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>
</script>

View file

@ -1,65 +0,0 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Test path animation where coordinate modes of start and end differ. You should see PASS messages</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<svg>
</svg>
<script>
var rootSVGElement = document.querySelector("svg");
var epsilon = 1.0;
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
path.setAttribute("fill", "green");
path.setAttribute("onclick", "executeTest()");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
animate.setAttribute("id", "animation");
animate.setAttribute("attributeName", "d");
animate.setAttribute("from", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
animate.setAttribute("to", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
animate.setAttribute("begin", "0s");
animate.setAttribute("dur", "4s");
path.appendChild(animate);
rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_equals(path.getAttribute('d'), "m -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60");
}
function sample2() {
assert_equals(path.getAttribute('d'), "m -72.5 32.5 a 157.5 167.5 52.5 1 1 65 45 m 100 42.5 a 177.5 187.5 112.5 1 1 140 147.5 Z m 155 -35");
}
function sample3() {
assert_equals(path.getAttribute('d'), "M -77.5 37.5 A 152.5 162.5 37.5 1 1 -2.5 92.5 M 57.5 80 A 172.5 182.5 97.5 1 1 277.5 222.5 Z M 282.5 95");
}
function sample4() {
assert_equals(path.getAttribute('d'), "M -79.9975 39.9975 A 150.003 160.003 30.0075 1 1 -0.00249481 99.9925 M 40.0175 60.02 A 170.003 180.003 90.0075 1 1 299.977 200.022 Z M 299.982 99.995");
}
smil_async_test((t) => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>

View file

@ -0,0 +1,63 @@
<!doctype html>
<html>
<meta charset="utf-8">
<title>Path animation where coordinate modes of start and end differ (m-M, a-A and Z)</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/SVGAnimationTestCase-testharness.js"></script>
<script src="support/animated-path-helpers.js"></script>
<svg></svg>
<script>
var rootSVGElement = document.querySelector("svg");
// Setup test document
var path = createSVGElement("path");
path.setAttribute("id", "path");
path.setAttribute("d", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
path.setAttribute("fill", "green");
path.setAttribute("transform", "translate(50, 50)");
var animate = createSVGElement("animate");
animate.setAttribute("id", "animation");
animate.setAttribute("attributeName", "d");
animate.setAttribute("from", 'm -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60');
animate.setAttribute("to", 'M -80 40 A 150 160 30 1 1 0 100 M 40 60 A 170 180 90 1 1 300 200 Z M 300 100');
animate.setAttribute("begin", "0s");
animate.setAttribute("dur", "4s");
path.appendChild(animate);
rootSVGElement.appendChild(path);
// Setup animation test
function sample1() {
// Check initial/end conditions
assert_animated_path_equals(
path, "m -70 30 a 160 170 60 1 1 60 40 m 120 70 a 180 190 120 1 1 100 150 Z m 120 -60");
}
function sample2() {
assert_animated_path_equals(
path, "M -72.5 32.5 A 157.5 167.5 52.5 1 1 -7.5 77.5 M 92.5 120 A 177.5 187.5 112.5 1 1 232.5 267.5 Z M 247.5 85");
}
function sample3() {
assert_animated_path_equals(
path, "M -77.5 37.5 A 152.5 162.5 37.5 1 1 -2.5 92.5 M 57.5 80 A 172.5 182.5 97.5 1 1 277.5 222.5 Z M 282.5 95");
}
function sample4() {
assert_animated_path_equals(
path, "M -79.9975 39.9975 A 150.003 160.003 30.0075 1 1 -0.00249481 99.9925 M 40.0175 60.02 A 170.003 180.003 90.0075 1 1 299.977 200.022 Z M 299.982 99.995");
}
smil_async_test(t => {
const expectedValues = [
// [animationId, time, sampleCallback]
["animation", 0.0, sample1],
["animation", 1.0, sample2],
["animation", 3.0, sample3],
["animation", 3.999, sample4],
["animation", 4.001, sample1]
];
runAnimationTest(t, expectedValues);
});
</script>

Some files were not shown because too many files have changed in this diff Show more