Update web-platform-tests to revision b'89142292ab8c7f3564d978a76fdabc66626c421e'

This commit is contained in:
WPT Sync Bot 2023-01-26 01:42:16 +00:00
parent 7f838a4f5f
commit cda7a10498
98 changed files with 2782 additions and 1163 deletions

View file

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

View file

@ -216863,6 +216863,32 @@
{} {}
] ]
], ],
"scoped-reference-animation-001.html": [
"891bda52a39b42322cf15cb01727f9cad58cf026",
[
null,
[
[
"/css/css-scoping/scoped-reference-animation-ref.html",
"=="
]
],
{}
]
],
"scoped-reference-animation-002.html": [
"d5c25f06c0aa73269615ec9bf2b6399729ea261a",
[
null,
[
[
"/css/css-scoping/scoped-reference-animation-ref.html",
"=="
]
],
{}
]
],
"shadow-assign-dynamic-001.html": [ "shadow-assign-dynamic-001.html": [
"b9a0d1a2991c071bb3654995f93c4ac7ff495aee", "b9a0d1a2991c071bb3654995f93c4ac7ff495aee",
[ [
@ -231462,7 +231488,7 @@
] ]
], ],
"line-break-normal-015a.xht": [ "line-break-normal-015a.xht": [
"db3ee2a586fb90433f85b626cf05c2da5eb143cb", "d2e0fe34995f43ffc1e4da10209efb9a71912ceb",
[ [
null, null,
[ [
@ -231657,7 +231683,7 @@
] ]
], ],
"line-break-strict-015a.xht": [ "line-break-strict-015a.xht": [
"9114120bc86e2b629a555539fd97682c8bfe6d6e", "ad31e4fc54d80cd815e09889ae11a6bc633d80a8",
[ [
null, null,
[ [
@ -237907,6 +237933,19 @@
{} {}
] ]
], ],
"break-spaces-011.html": [
"8c40a31a35688512742727639c11091ac8163dd8",
[
null,
[
[
"/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html",
"=="
]
],
{}
]
],
"break-spaces-051.html": [ "break-spaces-051.html": [
"2626511808335491910d3c14d752bb08494fcbc2", "2626511808335491910d3c14d752bb08494fcbc2",
[ [
@ -385291,6 +385330,10 @@
[] []
] ]
}, },
"scoped-reference-animation-ref.html": [
"9f407eb690e0fb3d033afba0817082f84e30b783",
[]
],
"slotted-placeholder-ref.html": [ "slotted-placeholder-ref.html": [
"f99c0385d061766b49d55e7703bf596fe69d6ec2", "f99c0385d061766b49d55e7703bf596fe69d6ec2",
[] []
@ -388560,7 +388603,7 @@
[] []
], ],
"line-break-normal-015a-ref.xht": [ "line-break-normal-015a-ref.xht": [
"941e18242d9868a45dbde986a189feecaed8b05c", "23cf1487b1b3c11d67787b5d4dfc422f61495254",
[] []
], ],
"line-break-normal-015b-ref.xht": [ "line-break-normal-015b-ref.xht": [
@ -388616,7 +388659,7 @@
[] []
], ],
"line-break-strict-015a-ref.xht": [ "line-break-strict-015a-ref.xht": [
"f8a1222a3334edb8117e9141359958c9b8f51748", "252818c22a0c0cce5d2844a283d447a32f4b5420",
[] []
], ],
"line-break-strict-015b-ref.xht": [ "line-break-strict-015b-ref.xht": [
@ -410106,8 +410149,12 @@
] ]
}, },
"tools": { "tools": {
"PRESUBMIT.py": [
"048e96b7012b70b276922ace2d7cdd811ebb3291",
[]
],
"gentest.py": [ "gentest.py": [
"cb1f720590ce8b41fe6bcb113ee24a60e173d263", "bca7b9ecfcb72dccec216b5435f9071f47fde0be",
[] []
], ],
"gentest_union.py": [ "gentest_union.py": [
@ -410115,11 +410162,11 @@
[] []
], ],
"gentestutils.py": [ "gentestutils.py": [
"1206aa91bfbe737b55a1ba500713e18cbf8e07fd", "16ca5f410c0dd1182271b151fc2fa3e0530248e6",
[] []
], ],
"gentestutilsunion.py": [ "gentestutilsunion.py": [
"c6fba8453d0ebbe389f6b9103f6272869076e641", "047dd6c802b14f375f8049afa211ba921715ca6c",
[] []
], ],
"name2dir-canvas.yaml": [ "name2dir-canvas.yaml": [
@ -410967,10 +411014,6 @@
"d5c99062d2bb8f9660b68c172754867b598ed43f", "d5c99062d2bb8f9660b68c172754867b598ed43f",
[] []
], ],
"named_targeting.https.html.headers": [
"d5c99062d2bb8f9660b68c172754867b598ed43f",
[]
],
"popup-so.https.html.headers": [ "popup-so.https.html.headers": [
"46ad58d83bf6e98913ca4c564b7acb8f19fa0093", "46ad58d83bf6e98913ca4c564b7acb8f19fa0093",
[] []
@ -422136,7 +422179,7 @@
}, },
"server": { "server": {
"context.any.js.ini": [ "context.any.js.ini": [
"72009c61e6efb374ff3ce0aa9470d994a737789d", "49220324f2f08b8e2bd700e2161615ba93f78b59",
[] []
], ],
"http2-context.sub.h2.any.js.ini": [ "http2-context.sub.h2.any.js.ini": [
@ -423153,7 +423196,7 @@
[] []
], ],
"payment-handler.idl": [ "payment-handler.idl": [
"d0e5bd9fda832377e89a8b2b62fb4f597847a780", "65b64bdf31c7dfed778ba475e154cd780ca44e86",
[] []
], ],
"payment-request.idl": [ "payment-request.idl": [
@ -423830,7 +423873,7 @@
[] []
], ],
"largest-contentful-paint-helpers.js": [ "largest-contentful-paint-helpers.js": [
"043587ca654c44fb97ae41e32cff094852199365", "b0fe1b08cb44b1871ba6dac4c1d25018c6032019",
[] []
], ],
"lcp-sw-from-cache.js": [ "lcp-sw-from-cache.js": [
@ -423912,7 +423955,7 @@
] ]
}, },
"lint.ignore": [ "lint.ignore": [
"11821957cf4db2a454da4f7b135198797ceb437f", "011f05c607e24b53f0d1120dc9c8a6cf5fdf06d9",
[] []
], ],
"loading": { "loading": {
@ -426772,10 +426815,6 @@
"f97229762ce388ff0695d56684099b9286326a29", "f97229762ce388ff0695d56684099b9286326a29",
[] []
], ],
"register-and-activate-service-worker.js": [
"fb54c5c06488f319b0b4152837cc6a1b530cab7a",
[]
],
"supports-shipping-contact-delegation-manual-manifest.json": [ "supports-shipping-contact-delegation-manual-manifest.json": [
"fd6bc89ef6d38e0cee82bfadcc697e36a2952070", "fd6bc89ef6d38e0cee82bfadcc697e36a2952070",
[] []
@ -429882,7 +429921,7 @@
[] []
], ],
"entry-invariants.js": [ "entry-invariants.js": [
"dc907533946b383ccadd62ce1c81135ee6c1d19c", "bbc913b722903085963a133dab0a8a96f77b2506",
[] []
], ],
"eventsource.py": [ "eventsource.py": [
@ -430062,7 +430101,7 @@
[] []
], ],
"resource-loaders.js": [ "resource-loaders.js": [
"70889b709f15a40f9cdc12cfeafb7a46c88b9a0c", "37fea16b1750faa5df8983cc88ce197125c21490",
[] []
], ],
"resource-timing-content-length.py": [ "resource-timing-content-length.py": [
@ -444681,7 +444720,7 @@
[] []
], ],
"test_update_expectations.py": [ "test_update_expectations.py": [
"92022e9b1ea1bcc516a654e1e4975db851c6ac92", "1635dce7ec67809e7824ba39806cf16e2f40b31a",
[] []
], ],
"test_wpt.py": [ "test_wpt.py": [
@ -445043,7 +445082,7 @@
[] []
], ],
"manifestupdate.py": [ "manifestupdate.py": [
"ce12bc3370a3fb06a85ffc0db2e93a42eb093159", "0bc25187976ddd9f970506ff74f63b9720e62588",
[] []
], ],
"metadata.py": [ "metadata.py": [
@ -445095,7 +445134,7 @@
[] []
], ],
"testloader.py": [ "testloader.py": [
"0e24c0deaa1adb34e401aa4effebbe816b2892f1", "93e2a87826c59926a649bcfb16949aa5c6c93342",
[] []
], ],
"testrunner.py": [ "testrunner.py": [
@ -445162,7 +445201,7 @@
[] []
], ],
"test_wpttest.py": [ "test_wpttest.py": [
"d11b3a22451b9659a362461f0259239098e65af2", "2d3578a903ccc45f03eef2fc29f4a54e3b87983e",
[] []
] ]
}, },
@ -488120,6 +488159,27 @@
{} {}
] ]
], ],
"anchor-transition-001.html": [
"b5849510e838b47fd5ddcf30489842e755225d5b",
[
null,
{}
]
],
"anchor-transition-002.html": [
"b6a1ff4511ac9ddfb20a531086137741b137b36b",
[
null,
{}
]
],
"anchor-transition-003.html": [
"e7441275141176078e14fc16aadf134bf9b65a37",
[
null,
{}
]
],
"at-fallback-position-allowed-declarations.html": [ "at-fallback-position-allowed-declarations.html": [
"873fa13140047c0943dde64faa8ab7dc54b28203", "873fa13140047c0943dde64faa8ab7dc54b28203",
[ [
@ -501598,7 +501658,7 @@
] ]
], ],
"parsing.html": [ "parsing.html": [
"66d1566586cd7d94f3c1da014e1ef3e4134daeac", "8e445faf1c9b8b0942f684d5093c5a7071d43a91",
[ [
null, null,
{} {}
@ -503271,7 +503331,7 @@
] ]
], ],
"at-property.html": [ "at-property.html": [
"d996091dc203eab079fff2d2b980d064300af39b", "b91b143e368ff5371bce34d9b0e43ca78ed358cf",
[ [
null, null,
{} {}
@ -504684,6 +504744,13 @@
{} {}
] ]
], ],
"focus-element-no-snap.html": [
"9ec004c6287008693e73bb51d0503f99e2f0b087",
[
null,
{}
]
],
"move-current-target.html": [ "move-current-target.html": [
"ccadc884c5ba23f90b4b7d273e5aaf355cf648d1", "ccadc884c5ba23f90b4b7d273e5aaf355cf648d1",
[ [
@ -515806,21 +515873,21 @@
] ]
], ],
"only-child-group.html": [ "only-child-group.html": [
"034df41dde165f7624effddf70209472ea74a322", "c3e9d669a30e24c93cbe0dc20c211b8e3e92d9a8",
[ [
null, null,
{} {}
] ]
], ],
"only-child-image-pair.html": [ "only-child-image-pair.html": [
"830b37313eaaa3165d5739b39f2ccb415886e724", "93fcc0a5ea8bcfce67c6f375ecd19602337949ef",
[ [
null, null,
{} {}
] ]
], ],
"only-child-new.html": [ "only-child-new.html": [
"2f8a7a4023ec7ffde81a6eeda6a65ca4533540ce", "62328f27cf259d5b50fbea43e02ba3200364b8e7",
[ [
null, null,
{} {}
@ -515834,7 +515901,14 @@
] ]
], ],
"only-child-old.html": [ "only-child-old.html": [
"4ca6fed20ce7b2f092de2c324ad6197caed22bc9", "56dfa168e253eddc61e41db8bcd766c3282ae726",
[
null,
{}
]
],
"only-child-on-root-element-with-view-transition.html": [
"0bf6d8b84b397f6818b133374b4ba0446af70842",
[ [
null, null,
{} {}
@ -519079,6 +519153,13 @@
{} {}
] ]
], ],
"match-media-parsing.html": [
"9d9aa3dd581579dfb6e14e2ad82ee54f8f575696",
[
null,
{}
]
],
"media-query-matches-in-iframe.html": [ "media-query-matches-in-iframe.html": [
"5828936732e7133d4365eb288b99e99cb428fb19", "5828936732e7133d4365eb288b99e99cb428fb19",
[ [
@ -521219,7 +521300,7 @@
] ]
], ],
"form-disabled-callback.html": [ "form-disabled-callback.html": [
"954c3f3f6eecc95b12ffb235ffe287675f734429", "c61a7719fc628c21d380e7f16c8c19921e3ceb2b",
[ [
null, null,
{} {}
@ -588362,7 +588443,7 @@
] ]
], ],
"iframe-popup.https.html": [ "iframe-popup.https.html": [
"2c6f0b62822f61bc4aac8a9bdd50cdbd724c07eb", "17840724d9e342aa52cdcc474356b25d554dfd63",
[ [
"html/cross-origin-opener-policy/tentative/restrict-properties/iframe-popup.https.html?1-2", "html/cross-origin-opener-policy/tentative/restrict-properties/iframe-popup.https.html?1-2",
{ {
@ -588447,7 +588528,7 @@
] ]
], ],
"popup-with-same-origin.https.html": [ "popup-with-same-origin.https.html": [
"491cbc3b9d091e91976624b807a76f254fa68958", "c0020fa23a478fd75aa27b69edb95c84f3e3789a",
[ [
null, null,
{ {
@ -601923,6 +602004,13 @@
{} {}
] ]
], ],
"popover-target-element-disabled.tentative.html": [
"3d139c5950eb6bc1048c10e0ea6053369cb93403",
[
null,
{}
]
],
"popover-top-layer-combinations.tentative.html": [ "popover-top-layer-combinations.tentative.html": [
"001bf88a25ef851e6607dc6e0ba7a7cf3b8cf4f8", "001bf88a25ef851e6607dc6e0ba7a7cf3b8cf4f8",
[ [
@ -614775,7 +614863,7 @@
] ]
], ],
"image-upscaling.html": [ "image-upscaling.html": [
"a4f7d8079d3b9a75f79b896743cbc018cc81c9ce", "5cb3767ca7d29a30103797c8c8abe1c692787466",
[ [
null, null,
{} {}
@ -625798,7 +625886,7 @@
] ]
], ],
"idlharness.https.any.js": [ "idlharness.https.any.js": [
"dfb0190abacb96c61cf5c125c68a1ad346f60205", "d34e20630bf7d60faa5aa8333d1595754420c080",
[ [
"payment-handler/idlharness.https.any.html", "payment-handler/idlharness.https.any.html",
{ {
@ -625912,13 +626000,6 @@
} }
] ]
], ],
"payment-instruments.https.html": [
"121c131568852eafe1b9ce5f9ec148c2cbee3fb6",
[
null,
{}
]
],
"payment-request-event-constructor.https.html": [ "payment-request-event-constructor.https.html": [
"31ac8cafa78fb52fb7c02722003b5359ceadb7e2", "31ac8cafa78fb52fb7c02722003b5359ceadb7e2",
[ [
@ -625941,7 +626022,7 @@
] ]
], ],
"same-object-attributes.https.html": [ "same-object-attributes.https.html": [
"2e5dea3a4aed33378f25b09b6e58929e22f2f72c", "27c204484359d6b1afbb3412ae4feabf1295d6b1",
[ [
null, null,
{} {}
@ -643761,7 +643842,7 @@
] ]
], ],
"cross-origin-start-end-time-with-redirects.html": [ "cross-origin-start-end-time-with-redirects.html": [
"1b107d3aef7764d9b9603ea2658cf469cf285980", "8e368d13807745761083b090bc097217ff22e598",
[ [
null, null,
{} {}
@ -644212,7 +644293,7 @@
] ]
], ],
"object-not-found-after-cross-origin-redirect.html": [ "object-not-found-after-cross-origin-redirect.html": [
"4d5d121fe32c4232dc8094906f92b7c8ac8d2ef1", "6990c6c06082e5d62ba3aa576eccd42d13246d2a",
[ [
null, null,
{ {
@ -644342,7 +644423,7 @@
] ]
], ],
"response-status-code.html": [ "response-status-code.html": [
"3c606c5496e6c7f9b0ecd5a7bfec9a611ad4f86f", "3a184c6f016b28c7003ea4650b7827b74388faf8",
[ [
null, null,
{ {
@ -652672,6 +652753,13 @@
} }
] ]
], ],
"delegatesFocus-tabindex-change.html": [
"f159c22164bb62064b62bc089faf5bd05cba555f",
[
null,
{}
]
],
"focus-autofocus.html": [ "focus-autofocus.html": [
"75a50b84c6df5525b5da0df86192637b70247820", "75a50b84c6df5525b5da0df86192637b70247820",
[ [
@ -677573,7 +677661,7 @@
] ]
], ],
"getcredential-prf.https.html": [ "getcredential-prf.https.html": [
"6f8670f64d19e1a7366eb6cf42a83a3b6eedd387", "61b52ac5958c7b242168285ad5e83581b4c1497e",
[ [
null, null,
{ {

View file

@ -1,6 +1,3 @@
[block-in-inline-hittest-002.html] [block-in-inline-hittest-002.html]
[elementsFromPoint] [elementsFromPoint]
expected: FAIL expected: FAIL
[elementFromPoint]
expected: FAIL

View file

@ -0,0 +1,2 @@
[opacity-animation-ending-correctly-002.html]
expected: TIMEOUT

View file

@ -1,3 +0,0 @@
[hittest-anonymous-box.html]
[Hit-testing within an anonymous flex-item should return the flexbox as the hittest result.]
expected: FAIL

View file

@ -319,3 +319,18 @@
[Matching font-style: 'oblique -21deg' should prefer 'oblique -21deg' over 'oblique -60deg -40deg'] [Matching font-style: 'oblique -21deg' should prefer 'oblique -21deg' over 'oblique -60deg -40deg']
expected: FAIL expected: FAIL
[Matching font-weight: '399' should prefer '340 360' over '200 300']
expected: FAIL
[Matching font-stretch: '110%' should prefer '100%' over '50% 80%']
expected: FAIL
[Matching font-style: 'oblique 21deg' should prefer 'oblique 40deg 50deg' over 'oblique 20deg']
expected: FAIL
[Matching font-style: 'oblique 10deg' should prefer 'oblique 10deg' over 'oblique 5deg']
expected: FAIL
[Matching font-style: 'oblique -10deg' should prefer 'oblique -1deg 0deg' over 'oblique -20deg -15deg']
expected: FAIL

View file

@ -1,2 +0,0 @@
[line-break-normal-015a.xht]
expected: FAIL

View file

@ -1,2 +0,0 @@
[line-break-strict-015a.xht]
expected: FAIL

View file

@ -0,0 +1,2 @@
[break-spaces-011.html]
expected: FAIL

View file

@ -53,152 +53,425 @@
[background-position length(px) / events] [background-position length(px) / events]
expected: FAIL expected: FAIL
[margin-right length(cm) / values] [background-color color(rgba) / values]
expected: FAIL expected: FAIL
[margin-right length(in) / values] [border-top-width length(pt) / values]
expected: FAIL expected: FAIL
[margin-top length(pt) / values] [border-top-width length(pc) / values]
expected: FAIL expected: FAIL
[margin-top length(pc) / values] [border-top-width length(px) / values]
expected: FAIL expected: FAIL
[margin-top length(px) / values] [border-top-width length(em) / values]
expected: FAIL expected: FAIL
[margin-top length(em) / values] [border-top-width length(ex) / values]
expected: FAIL expected: FAIL
[margin-top length(ex) / values] [border-top-width length(mm) / values]
expected: FAIL expected: FAIL
[margin-top length(mm) / values] [border-top-width length(cm) / values]
expected: FAIL expected: FAIL
[margin-top length(cm) / values] [border-top-width length(in) / values]
expected: FAIL expected: FAIL
[margin-top length(in) / values] [border-right-width length(pt) / values]
expected: FAIL expected: FAIL
[height length(pt) / values] [border-right-width length(pc) / values]
expected: FAIL expected: FAIL
[height length(pc) / values] [border-right-width length(px) / values]
expected: FAIL expected: FAIL
[height length(px) / values] [border-right-width length(em) / values]
expected: FAIL expected: FAIL
[height length(em) / values] [border-right-width length(ex) / values]
expected: FAIL expected: FAIL
[height length(ex) / values] [border-right-width length(mm) / values]
expected: FAIL expected: FAIL
[height length(mm) / values] [border-right-width length(cm) / values]
expected: FAIL expected: FAIL
[height length(cm) / values] [border-right-width length(in) / values]
expected: FAIL expected: FAIL
[height length(in) / values] [border-bottom-width length(pt) / values]
expected: FAIL expected: FAIL
[height percentage(%) / values] [border-bottom-width length(pc) / values]
expected: FAIL expected: FAIL
[width length(pt) / values] [border-bottom-width length(px) / values]
expected: FAIL expected: FAIL
[width length(pc) / values] [border-bottom-width length(em) / values]
expected: FAIL expected: FAIL
[width length(px) / values] [border-bottom-width length(ex) / values]
expected: FAIL expected: FAIL
[width length(em) / values] [border-bottom-width length(mm) / values]
expected: FAIL expected: FAIL
[width length(ex) / values] [border-bottom-width length(cm) / values]
expected: FAIL expected: FAIL
[width length(mm) / values] [border-bottom-width length(in) / values]
expected: FAIL expected: FAIL
[width length(cm) / values] [border-left-width length(pt) / values]
expected: FAIL expected: FAIL
[width length(in) / values] [border-left-width length(pc) / values]
expected: FAIL expected: FAIL
[width percentage(%) / values] [border-left-width length(px) / values]
expected: FAIL expected: FAIL
[min-height length(pt) / values] [border-left-width length(em) / values]
expected: FAIL expected: FAIL
[min-height length(pc) / values] [border-left-width length(ex) / values]
expected: FAIL expected: FAIL
[min-height length(px) / values] [border-left-width length(mm) / values]
expected: FAIL expected: FAIL
[min-height length(em) / values] [border-left-width length(cm) / values]
expected: FAIL expected: FAIL
[min-height length(ex) / values] [border-left-width length(in) / values]
expected: FAIL expected: FAIL
[min-height length(mm) / values] [border-top-color color(rgba) / values]
expected: FAIL expected: FAIL
[min-height length(cm) / values] [border-right-color color(rgba) / values]
expected: FAIL expected: FAIL
[min-height length(in) / values] [border-bottom-color color(rgba) / values]
expected: FAIL expected: FAIL
[min-height percentage(%) / values] [border-left-color color(rgba) / values]
expected: FAIL expected: FAIL
[min-width length(pt) / values] [padding-bottom length(pt) / values]
expected: FAIL expected: FAIL
[min-width length(pc) / values] [padding-bottom length(pc) / values]
expected: FAIL expected: FAIL
[min-width length(px) / values] [padding-bottom length(px) / values]
expected: FAIL expected: FAIL
[min-width length(em) / values] [padding-bottom length(em) / values]
expected: FAIL expected: FAIL
[min-width length(ex) / values] [padding-bottom length(ex) / values]
expected: FAIL expected: FAIL
[min-width length(mm) / values] [padding-bottom length(mm) / values]
expected: FAIL expected: FAIL
[min-width length(cm) / values] [padding-bottom length(cm) / values]
expected: FAIL expected: FAIL
[min-width length(in) / values] [padding-bottom length(in) / values]
expected: FAIL expected: FAIL
[min-width percentage(%) / values] [padding-left length(pt) / values]
expected: FAIL expected: FAIL
[max-height length(pt) / values] [padding-left length(pc) / values]
expected: FAIL expected: FAIL
[max-height length(pc) / values] [padding-left length(px) / values]
expected: FAIL expected: FAIL
[max-height length(px) / values] [padding-left length(em) / values]
expected: FAIL expected: FAIL
[max-height length(em) / values] [padding-left length(ex) / values]
expected: FAIL
[padding-left length(mm) / values]
expected: FAIL
[padding-left length(cm) / values]
expected: FAIL
[padding-left length(in) / values]
expected: FAIL
[padding-right length(pt) / values]
expected: FAIL
[padding-right length(pc) / values]
expected: FAIL
[padding-right length(px) / values]
expected: FAIL
[padding-right length(em) / values]
expected: FAIL
[padding-right length(ex) / values]
expected: FAIL
[padding-right length(mm) / values]
expected: FAIL
[padding-right length(cm) / values]
expected: FAIL
[padding-right length(in) / values]
expected: FAIL
[padding-top length(pt) / values]
expected: FAIL
[padding-top length(pc) / values]
expected: FAIL
[padding-top length(px) / values]
expected: FAIL
[padding-top length(em) / values]
expected: FAIL
[padding-top length(ex) / values]
expected: FAIL
[padding-top length(mm) / values]
expected: FAIL
[padding-top length(cm) / values]
expected: FAIL
[padding-top length(in) / values]
expected: FAIL
[margin-bottom length(pt) / values]
expected: FAIL
[margin-bottom length(pc) / values]
expected: FAIL
[margin-bottom length(px) / values]
expected: FAIL
[margin-bottom length(em) / values]
expected: FAIL
[margin-bottom length(ex) / values]
expected: FAIL
[margin-bottom length(mm) / values]
expected: FAIL
[margin-bottom length(cm) / values]
expected: FAIL
[margin-bottom length(in) / values]
expected: FAIL
[margin-left length(pt) / values]
expected: FAIL
[margin-left length(pc) / values]
expected: FAIL
[margin-left length(px) / values]
expected: FAIL
[margin-left length(em) / values]
expected: FAIL
[margin-left length(ex) / values]
expected: FAIL
[margin-left length(mm) / values]
expected: FAIL
[margin-left length(cm) / values]
expected: FAIL
[margin-left length(in) / values]
expected: FAIL
[margin-right length(pt) / values]
expected: FAIL
[margin-right length(pc) / values]
expected: FAIL
[margin-right length(px) / values]
expected: FAIL
[margin-right length(em) / values]
expected: FAIL
[margin-right length(ex) / values]
expected: FAIL
[margin-right length(mm) / values]
expected: FAIL
[color color(rgba) / values]
expected: FAIL
[font-size length(pt) / values]
expected: FAIL
[font-size length(pc) / values]
expected: FAIL
[font-size length(px) / values]
expected: FAIL
[font-size length(em) / values]
expected: FAIL
[font-size length(ex) / values]
expected: FAIL
[font-size length(mm) / values]
expected: FAIL
[font-size length(cm) / values]
expected: FAIL
[font-size length(in) / values]
expected: FAIL
[font-size percentage(%) / values]
expected: FAIL
[font-weight font-weight(keyword) / values]
expected: FAIL
[font-weight font-weight(numeric) / values]
expected: FAIL
[line-height number(integer) / values]
expected: FAIL
[line-height number(decimal) / values]
expected: FAIL
[line-height length(pt) / values]
expected: FAIL
[line-height length(pc) / values]
expected: FAIL
[line-height length(px) / values]
expected: FAIL
[line-height length(em) / values]
expected: FAIL
[line-height length(ex) / values]
expected: FAIL
[line-height length(mm) / values]
expected: FAIL
[line-height length(cm) / values]
expected: FAIL
[line-height length(in) / values]
expected: FAIL
[line-height percentage(%) / values]
expected: FAIL
[letter-spacing length(pt) / values]
expected: FAIL
[letter-spacing length(pc) / values]
expected: FAIL
[letter-spacing length(px) / values]
expected: FAIL
[letter-spacing length(em) / values]
expected: FAIL
[letter-spacing length(ex) / values]
expected: FAIL
[letter-spacing length(mm) / values]
expected: FAIL
[letter-spacing length(cm) / values]
expected: FAIL
[letter-spacing length(in) / values]
expected: FAIL
[word-spacing length(pt) / values]
expected: FAIL
[word-spacing length(pc) / values]
expected: FAIL
[word-spacing length(px) / values]
expected: FAIL
[word-spacing length(em) / values]
expected: FAIL
[word-spacing length(ex) / values]
expected: FAIL
[word-spacing length(mm) / values]
expected: FAIL
[word-spacing length(cm) / values]
expected: FAIL
[word-spacing length(in) / values]
expected: FAIL
[word-spacing percentage(%) / values]
expected: FAIL
[text-indent length(pt) / values]
expected: FAIL
[text-indent length(pc) / values]
expected: FAIL
[text-indent length(px) / values]
expected: FAIL
[text-indent length(em) / values]
expected: FAIL
[text-indent length(ex) / values]
expected: FAIL
[text-indent length(mm) / values]
expected: FAIL
[text-indent length(cm) / values]
expected: FAIL
[text-indent length(in) / values]
expected: FAIL
[text-indent percentage(%) / values]
expected: FAIL
[text-shadow shadow(shadow) / values]
expected: FAIL expected: FAIL

View file

@ -55,3 +55,726 @@
[background-position length(px) / events] [background-position length(px) / events]
expected: FAIL expected: FAIL
[background-color color(rgba) / events]
expected: FAIL
[border-top-width length(pt) / events]
expected: FAIL
[border-top-width length(pc) / events]
expected: FAIL
[border-top-width length(px) / events]
expected: FAIL
[border-top-width length(em) / events]
expected: FAIL
[border-top-width length(ex) / events]
expected: FAIL
[border-top-width length(mm) / events]
expected: FAIL
[border-top-width length(cm) / events]
expected: FAIL
[border-top-width length(in) / events]
expected: FAIL
[border-right-width length(pt) / events]
expected: FAIL
[border-right-width length(pc) / events]
expected: FAIL
[border-right-width length(px) / events]
expected: FAIL
[border-right-width length(em) / events]
expected: FAIL
[border-right-width length(ex) / events]
expected: FAIL
[border-right-width length(mm) / events]
expected: FAIL
[border-right-width length(cm) / events]
expected: FAIL
[border-right-width length(in) / events]
expected: FAIL
[border-bottom-width length(pt) / events]
expected: FAIL
[border-bottom-width length(pc) / events]
expected: FAIL
[border-bottom-width length(px) / events]
expected: FAIL
[border-bottom-width length(em) / events]
expected: FAIL
[border-bottom-width length(ex) / events]
expected: FAIL
[border-bottom-width length(mm) / events]
expected: FAIL
[border-bottom-width length(cm) / events]
expected: FAIL
[border-bottom-width length(in) / events]
expected: FAIL
[border-left-width length(pt) / events]
expected: FAIL
[border-left-width length(pc) / events]
expected: FAIL
[border-left-width length(px) / events]
expected: FAIL
[border-left-width length(em) / events]
expected: FAIL
[border-left-width length(ex) / events]
expected: FAIL
[border-left-width length(mm) / events]
expected: FAIL
[border-left-width length(cm) / events]
expected: FAIL
[border-left-width length(in) / events]
expected: FAIL
[border-top-color color(rgba) / events]
expected: FAIL
[border-right-color color(rgba) / events]
expected: FAIL
[border-bottom-color color(rgba) / events]
expected: FAIL
[border-left-color color(rgba) / events]
expected: FAIL
[padding-bottom length(pt) / events]
expected: FAIL
[padding-bottom length(pc) / events]
expected: FAIL
[padding-bottom length(px) / events]
expected: FAIL
[padding-bottom length(em) / events]
expected: FAIL
[padding-bottom length(ex) / events]
expected: FAIL
[padding-bottom length(mm) / events]
expected: FAIL
[padding-bottom length(cm) / events]
expected: FAIL
[padding-bottom length(in) / events]
expected: FAIL
[padding-left length(pt) / events]
expected: FAIL
[padding-left length(pc) / events]
expected: FAIL
[padding-left length(px) / events]
expected: FAIL
[padding-left length(em) / events]
expected: FAIL
[padding-left length(ex) / events]
expected: FAIL
[padding-left length(mm) / events]
expected: FAIL
[padding-left length(cm) / events]
expected: FAIL
[padding-left length(in) / events]
expected: FAIL
[padding-right length(pt) / events]
expected: FAIL
[padding-right length(pc) / events]
expected: FAIL
[padding-right length(px) / events]
expected: FAIL
[padding-right length(em) / events]
expected: FAIL
[padding-right length(ex) / events]
expected: FAIL
[padding-right length(mm) / events]
expected: FAIL
[padding-right length(cm) / events]
expected: FAIL
[padding-right length(in) / events]
expected: FAIL
[padding-top length(pt) / events]
expected: FAIL
[padding-top length(pc) / events]
expected: FAIL
[padding-top length(px) / events]
expected: FAIL
[padding-top length(em) / events]
expected: FAIL
[padding-top length(ex) / events]
expected: FAIL
[padding-top length(mm) / events]
expected: FAIL
[padding-top length(cm) / events]
expected: FAIL
[padding-top length(in) / events]
expected: FAIL
[margin-bottom length(pt) / events]
expected: FAIL
[margin-bottom length(pc) / events]
expected: FAIL
[margin-bottom length(px) / events]
expected: FAIL
[margin-bottom length(em) / events]
expected: FAIL
[margin-bottom length(ex) / events]
expected: FAIL
[margin-bottom length(mm) / events]
expected: FAIL
[margin-bottom length(cm) / events]
expected: FAIL
[margin-bottom length(in) / events]
expected: FAIL
[margin-left length(pt) / events]
expected: FAIL
[margin-left length(pc) / events]
expected: FAIL
[margin-left length(px) / events]
expected: FAIL
[margin-left length(em) / events]
expected: FAIL
[margin-left length(ex) / events]
expected: FAIL
[margin-left length(mm) / events]
expected: FAIL
[margin-left length(cm) / events]
expected: FAIL
[margin-left length(in) / events]
expected: FAIL
[margin-right length(pt) / events]
expected: FAIL
[margin-right length(pc) / events]
expected: FAIL
[margin-right length(px) / events]
expected: FAIL
[margin-right length(em) / events]
expected: FAIL
[margin-right length(ex) / events]
expected: FAIL
[margin-right length(mm) / events]
expected: FAIL
[margin-right length(cm) / events]
expected: FAIL
[margin-right length(in) / events]
expected: FAIL
[margin-top length(pt) / events]
expected: FAIL
[margin-top length(pc) / events]
expected: FAIL
[margin-top length(px) / events]
expected: FAIL
[margin-top length(em) / events]
expected: FAIL
[margin-top length(ex) / events]
expected: FAIL
[margin-top length(mm) / events]
expected: FAIL
[margin-top length(cm) / events]
expected: FAIL
[margin-top length(in) / events]
expected: FAIL
[height length(pt) / events]
expected: FAIL
[height length(pc) / events]
expected: FAIL
[height length(px) / events]
expected: FAIL
[height length(em) / events]
expected: FAIL
[height length(ex) / events]
expected: FAIL
[height length(mm) / events]
expected: FAIL
[height length(cm) / events]
expected: FAIL
[height length(in) / events]
expected: FAIL
[height percentage(%) / events]
expected: FAIL
[width length(pt) / events]
expected: FAIL
[width length(pc) / events]
expected: FAIL
[width length(px) / events]
expected: FAIL
[width length(em) / events]
expected: FAIL
[width length(ex) / events]
expected: FAIL
[width length(mm) / events]
expected: FAIL
[width length(cm) / events]
expected: FAIL
[width length(in) / events]
expected: FAIL
[width percentage(%) / events]
expected: FAIL
[min-height length(pt) / events]
expected: FAIL
[min-height length(pc) / events]
expected: FAIL
[min-height length(px) / events]
expected: FAIL
[min-height length(em) / events]
expected: FAIL
[min-height length(ex) / events]
expected: FAIL
[min-height length(mm) / events]
expected: FAIL
[min-height length(cm) / events]
expected: FAIL
[min-height length(in) / events]
expected: FAIL
[min-height percentage(%) / events]
expected: FAIL
[min-width length(pt) / events]
expected: FAIL
[min-width length(pc) / events]
expected: FAIL
[min-width length(px) / events]
expected: FAIL
[min-width length(em) / events]
expected: FAIL
[min-width length(ex) / events]
expected: FAIL
[min-width length(mm) / events]
expected: FAIL
[min-width length(cm) / events]
expected: FAIL
[min-width length(in) / events]
expected: FAIL
[min-width percentage(%) / events]
expected: FAIL
[max-height length(pt) / events]
expected: FAIL
[max-height length(pc) / events]
expected: FAIL
[max-height length(px) / events]
expected: FAIL
[max-height length(em) / events]
expected: FAIL
[max-height length(ex) / events]
expected: FAIL
[max-height length(mm) / events]
expected: FAIL
[max-height length(cm) / events]
expected: FAIL
[max-height length(in) / events]
expected: FAIL
[max-height percentage(%) / events]
expected: FAIL
[max-width length(pt) / events]
expected: FAIL
[max-width length(pc) / events]
expected: FAIL
[max-width length(px) / events]
expected: FAIL
[max-width length(em) / events]
expected: FAIL
[max-width length(ex) / events]
expected: FAIL
[max-width length(mm) / events]
expected: FAIL
[max-width length(cm) / events]
expected: FAIL
[max-width length(in) / events]
expected: FAIL
[max-width percentage(%) / events]
expected: FAIL
[top length(pt) / events]
expected: FAIL
[top length(pc) / events]
expected: FAIL
[top length(px) / events]
expected: FAIL
[top length(em) / events]
expected: FAIL
[top length(ex) / events]
expected: FAIL
[top length(mm) / events]
expected: FAIL
[top length(cm) / events]
expected: FAIL
[top length(in) / events]
expected: FAIL
[top percentage(%) / events]
expected: FAIL
[right length(pt) / events]
expected: FAIL
[right length(pc) / events]
expected: FAIL
[right length(px) / events]
expected: FAIL
[right length(em) / events]
expected: FAIL
[right length(ex) / events]
expected: FAIL
[right length(mm) / events]
expected: FAIL
[right length(cm) / events]
expected: FAIL
[right length(in) / events]
expected: FAIL
[right percentage(%) / events]
expected: FAIL
[bottom length(pt) / events]
expected: FAIL
[bottom length(pc) / events]
expected: FAIL
[bottom length(px) / events]
expected: FAIL
[bottom length(em) / events]
expected: FAIL
[bottom length(ex) / events]
expected: FAIL
[bottom length(mm) / events]
expected: FAIL
[bottom length(cm) / events]
expected: FAIL
[bottom length(in) / events]
expected: FAIL
[bottom percentage(%) / events]
expected: FAIL
[left length(pt) / events]
expected: FAIL
[left length(pc) / events]
expected: FAIL
[left length(px) / events]
expected: FAIL
[left length(em) / events]
expected: FAIL
[left length(ex) / events]
expected: FAIL
[left length(mm) / events]
expected: FAIL
[left length(cm) / events]
expected: FAIL
[left length(in) / events]
expected: FAIL
[left percentage(%) / events]
expected: FAIL
[color color(rgba) / events]
expected: FAIL
[font-size length(pt) / events]
expected: FAIL
[font-size length(pc) / events]
expected: FAIL
[font-size length(px) / events]
expected: FAIL
[font-size length(em) / events]
expected: FAIL
[font-size length(ex) / events]
expected: FAIL
[font-size length(mm) / events]
expected: FAIL
[font-size length(cm) / events]
expected: FAIL
[font-size length(in) / events]
expected: FAIL
[font-size percentage(%) / events]
expected: FAIL
[font-weight font-weight(keyword) / events]
expected: FAIL
[font-weight font-weight(numeric) / events]
expected: FAIL
[line-height number(integer) / events]
expected: FAIL
[line-height number(decimal) / events]
expected: FAIL
[line-height length(pt) / events]
expected: FAIL
[line-height length(pc) / events]
expected: FAIL
[line-height length(px) / events]
expected: FAIL
[line-height length(em) / events]
expected: FAIL
[line-height length(ex) / events]
expected: FAIL
[line-height length(mm) / events]
expected: FAIL
[line-height length(cm) / events]
expected: FAIL
[line-height length(in) / events]
expected: FAIL
[line-height percentage(%) / events]
expected: FAIL
[letter-spacing length(pt) / events]
expected: FAIL
[letter-spacing length(pc) / events]
expected: FAIL
[letter-spacing length(px) / events]
expected: FAIL
[letter-spacing length(em) / events]
expected: FAIL
[letter-spacing length(ex) / events]
expected: FAIL
[letter-spacing length(mm) / events]
expected: FAIL
[letter-spacing length(cm) / events]
expected: FAIL
[letter-spacing length(in) / events]
expected: FAIL
[word-spacing length(pt) / events]
expected: FAIL
[word-spacing length(pc) / events]
expected: FAIL
[word-spacing length(px) / events]
expected: FAIL
[word-spacing length(em) / events]
expected: FAIL
[word-spacing length(ex) / events]
expected: FAIL
[word-spacing length(mm) / events]
expected: FAIL
[word-spacing length(cm) / events]
expected: FAIL
[word-spacing length(in) / events]
expected: FAIL
[word-spacing percentage(%) / events]
expected: FAIL
[text-indent length(pt) / events]
expected: FAIL
[text-indent length(pc) / events]
expected: FAIL
[text-indent length(px) / events]
expected: FAIL
[text-indent length(em) / events]
expected: FAIL
[text-indent length(ex) / events]
expected: FAIL
[text-indent length(mm) / events]
expected: FAIL
[text-indent length(cm) / events]
expected: FAIL
[text-indent length(in) / events]
expected: FAIL
[text-indent percentage(%) / events]
expected: FAIL
[text-shadow shadow(shadow) / events]
expected: FAIL

View file

@ -52,153 +52,3 @@
[background-position length(px) / events] [background-position length(px) / events]
expected: FAIL expected: FAIL
[color color(rgba) / values]
expected: FAIL
[font-size length(pt) / values]
expected: FAIL
[font-size length(pc) / values]
expected: FAIL
[font-size length(px) / values]
expected: FAIL
[font-size length(em) / values]
expected: FAIL
[font-size length(ex) / values]
expected: FAIL
[font-size length(mm) / values]
expected: FAIL
[font-size length(cm) / values]
expected: FAIL
[font-size length(in) / values]
expected: FAIL
[font-size percentage(%) / values]
expected: FAIL
[font-weight font-weight(keyword) / values]
expected: FAIL
[font-weight font-weight(numeric) / values]
expected: FAIL
[line-height number(integer) / values]
expected: FAIL
[line-height number(decimal) / values]
expected: FAIL
[line-height length(pt) / values]
expected: FAIL
[line-height length(pc) / values]
expected: FAIL
[line-height length(px) / values]
expected: FAIL
[line-height length(em) / values]
expected: FAIL
[line-height length(ex) / values]
expected: FAIL
[line-height length(mm) / values]
expected: FAIL
[line-height length(cm) / values]
expected: FAIL
[line-height length(in) / values]
expected: FAIL
[line-height percentage(%) / values]
expected: FAIL
[letter-spacing length(pt) / values]
expected: FAIL
[letter-spacing length(pc) / values]
expected: FAIL
[letter-spacing length(px) / values]
expected: FAIL
[letter-spacing length(em) / values]
expected: FAIL
[letter-spacing length(ex) / values]
expected: FAIL
[letter-spacing length(mm) / values]
expected: FAIL
[letter-spacing length(cm) / values]
expected: FAIL
[letter-spacing length(in) / values]
expected: FAIL
[word-spacing length(pt) / values]
expected: FAIL
[word-spacing length(pc) / values]
expected: FAIL
[word-spacing length(px) / values]
expected: FAIL
[word-spacing length(em) / values]
expected: FAIL
[word-spacing length(ex) / values]
expected: FAIL
[word-spacing length(mm) / values]
expected: FAIL
[word-spacing length(cm) / values]
expected: FAIL
[word-spacing length(in) / values]
expected: FAIL
[word-spacing percentage(%) / values]
expected: FAIL
[text-indent length(pt) / values]
expected: FAIL
[text-indent length(pc) / values]
expected: FAIL
[text-indent length(px) / values]
expected: FAIL
[text-indent length(em) / values]
expected: FAIL
[text-indent length(ex) / values]
expected: FAIL
[text-indent length(mm) / values]
expected: FAIL
[text-indent length(cm) / values]
expected: FAIL
[text-indent length(in) / values]
expected: FAIL
[text-indent percentage(%) / values]
expected: FAIL
[text-shadow shadow(shadow) / values]
expected: FAIL

View file

@ -0,0 +1,3 @@
[CaretPosition-001.html]
[Element at (400, 100)]
expected: FAIL

View file

@ -1,6 +1,3 @@
[MediaQueryList-extends-EventTarget-interop.html] [MediaQueryList-extends-EventTarget-interop.html]
[listeners are called in order they were added, ignoring capture parameter] [listeners are called in order they were added, ignoring capture parameter]
expected: FAIL expected: FAIL
[listener added with addListener and addEventListener (capture) is called twice]
expected: FAIL

View file

@ -13,3 +13,9 @@
[<li>Outside 3</li>] [<li>Outside 3</li>]
expected: FAIL expected: FAIL
[<li>Inside 2</li>]
expected: FAIL
[<li>Image Inside 1</li>]
expected: FAIL

View file

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

View file

@ -0,0 +1,18 @@
[match-media-parsing.html]
[Test parsing '(color)' with matchMedia]
expected: FAIL
[Test parsing '(color' with matchMedia]
expected: FAIL
[Test parsing ' (color)' with matchMedia]
expected: FAIL
[Test parsing ' ( color ) ' with matchMedia]
expected: FAIL
[Test parsing ' ( color ' with matchMedia]
expected: FAIL
[Test parsing ' color ), ( color' with matchMedia]
expected: FAIL

View file

@ -15,3 +15,8 @@
[Adding/removing disabled content attribute] [Adding/removing disabled content attribute]
expected: FAIL expected: FAIL
[Toggling "disabled" attribute on a custom element inside disabled <fieldset> does not trigger a callback]
expected: FAIL
[Toggling "disabled" attribute on a <fieldset> does not trigger a callback on disabled custom element descendant]
expected: FAIL

View file

@ -76,3 +76,6 @@
[Input: "Content-Length: ". Expected: 42.] [Input: "Content-Length: ". Expected: 42.]
expected: FAIL expected: FAIL
[Input: "Content-Length: 42\\r\\nContent-Length: 42". Expected: 42.]
expected: FAIL

View file

@ -147,8 +147,8 @@
[list-style-image sec-fetch-site - HTTPS downgrade-upgrade] [list-style-image sec-fetch-site - HTTPS downgrade-upgrade]
expected: FAIL expected: FAIL
[background-image sec-fetch-site - HTTPS downgrade (header not sent)]
expected: TIMEOUT
[border-image sec-fetch-site - HTTPS downgrade (header not sent)] [border-image sec-fetch-site - HTTPS downgrade (header not sent)]
expected: FAIL expected: FAIL
[background-image sec-fetch-site - Not sent to non-trustworthy same-site destination]
expected: TIMEOUT

View file

@ -7,3 +7,9 @@
[X-Content-Type-Options%3A%20nosniff%0C] [X-Content-Type-Options%3A%20nosniff%0C]
expected: FAIL expected: FAIL
[X-Content-Type-Options%3A%20no%0D%0AX-Content-Type-Options%3A%20nosniff]
expected: FAIL
[X-Content-Type-Options%3A%20%22nosniFF%22]
expected: FAIL

View file

@ -1,9 +1,10 @@
[iframe-src-aboutblank-navigate-immediately.html] [iframe-src-aboutblank-navigate-immediately.html]
expected: TIMEOUT
[Navigating to a different document with window.open] [Navigating to a different document with window.open]
expected: FAIL expected: FAIL
[Navigating to a different document with form submission] [Navigating to a different document with form submission]
expected: FAIL expected: TIMEOUT
[Navigating to a different document with link click] [Navigating to a different document with link click]
expected: FAIL expected: FAIL

View file

@ -1,10 +1,6 @@
[javascript-url-referrer.window.html] [javascript-url-referrer.window.html]
expected: TIMEOUT
[unsafe-url referrer policy used to create the starting page] [unsafe-url referrer policy used to create the starting page]
expected: FAIL expected: FAIL
[origin referrer policy used to create the starting page] [origin referrer policy used to create the starting page]
expected: FAIL expected: FAIL
[no-referrer referrer policy used to create the starting page]
expected: TIMEOUT

View file

@ -1,3 +0,0 @@
[navigation-unload-cross-origin.sub.window.html]
[Cross-origin navigation started from unload handler must be ignored]
expected: FAIL

View file

@ -0,0 +1,3 @@
[navigation-unload-same-origin.window.html]
[Same-origin navigation started from unload handler must be ignored]
expected: FAIL

View file

@ -0,0 +1,3 @@
[a-click.html]
[aElement.click() before the load event must NOT replace]
expected: FAIL

View file

@ -0,0 +1,4 @@
[traverse-during-unload.html]
expected: TIMEOUT
[Traversing the history during unload]
expected: TIMEOUT

View file

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

View file

@ -1,3 +0,0 @@
[creating_browsing_context_test_01.html]
[first argument: absolute url]
expected: FAIL

View file

@ -1,2 +1,2 @@
[canvas.2d.disconnected.html] [canvas.2d.disconnected.html]
expected: TIMEOUT expected: FAIL

View file

@ -1,7 +1,6 @@
[autofocus-dialog.html] [autofocus-dialog.html]
expected: TIMEOUT
[<dialog> can contain autofocus, without stopping page autofocus content from working] [<dialog> can contain autofocus, without stopping page autofocus content from working]
expected: FAIL expected: FAIL
[<dialog>-contained autofocus element gets focused when the dialog is shown] [<dialog>-contained autofocus element gets focused when the dialog is shown]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,4 @@
[supported-elements.html] [supported-elements.html]
expected: TIMEOUT
[Contenteditable element should support autofocus] [Contenteditable element should support autofocus]
expected: FAIL expected: FAIL
@ -10,7 +9,7 @@
expected: FAIL expected: FAIL
[Area element should support autofocus] [Area element should support autofocus]
expected: TIMEOUT expected: FAIL
[Host element with delegatesFocus should support autofocus] [Host element with delegatesFocus should support autofocus]
expected: FAIL expected: FAIL

View file

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

View file

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

View file

@ -14,9 +14,6 @@
[multipart/form-data: 0x00 in name (formdata event)] [multipart/form-data: 0x00 in name (formdata event)]
expected: FAIL expected: FAIL
[multipart/form-data: 0x00 in value (normal form)]
expected: FAIL
[multipart/form-data: 0x00 in value (formdata event)] [multipart/form-data: 0x00 in value (formdata event)]
expected: FAIL expected: FAIL

View file

@ -11,9 +11,6 @@
[text/plain: 0x00 in name (normal form)] [text/plain: 0x00 in name (normal form)]
expected: FAIL expected: FAIL
[text/plain: 0x00 in name (formdata event)]
expected: FAIL
[text/plain: 0x00 in value (normal form)] [text/plain: 0x00 in value (normal form)]
expected: FAIL expected: FAIL
@ -167,9 +164,6 @@
[text/plain: character not in encoding in filename (formdata event)] [text/plain: character not in encoding in filename (formdata event)]
expected: FAIL expected: FAIL
[text/plain: Basic test (formdata event)]
expected: FAIL
[text/plain: 0x00 in filename (formdata event)] [text/plain: 0x00 in filename (formdata event)]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,3 @@
[historical.html]
[<input name=isindex> should not be supported]
expected: FAIL

View file

@ -0,0 +1,18 @@
[popover-target-element-disabled.tentative.html]
[Disabled popover*target buttons should not affect the popover heirarchy.]
expected: FAIL
[Disabling popover*target buttons when popovers are open should still cause all popovers to be closed when the formerly outer popover is closed.]
expected: FAIL
[Disabling popover*target buttons when popovers are open should still cause all popovers to be closed when the formerly inner popover is closed.]
expected: FAIL
[Setting the form attribute on popover*target buttons when popovers are open should close all popovers.]
expected: FAIL
[Changing the input type on a popover*target button when popovers are open should close all popovers.]
expected: FAIL
[Disconnecting popover*target buttons when popovers are open should close all popovers.]
expected: FAIL

View file

@ -1,3 +0,0 @@
[module-delayed.html]
[async document.write in a module]
expected: FAIL

View file

@ -0,0 +1,3 @@
[module-static-import-delayed.html]
[document.write in an imported module]
expected: FAIL

View file

@ -1,10 +1,9 @@
[promise-job-entry-different-function-realm.html] [promise-job-entry-different-function-realm.html]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise] [Fulfillment handler on fulfilled promise]
expected: FAIL expected: FAIL
[Rejection handler on pending-then-rejected promise] [Rejection handler on pending-then-rejected promise]
expected: TIMEOUT expected: FAIL
[Thenable resolution] [Thenable resolution]
expected: FAIL expected: FAIL
@ -13,4 +12,4 @@
expected: FAIL expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise] [Fulfillment handler on pending-then-fulfilled promise]
expected: TIMEOUT expected: FAIL

View file

@ -1,5 +1,4 @@
[promise-job-entry.html] [promise-job-entry.html]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise] [Fulfillment handler on fulfilled promise]
expected: FAIL expected: FAIL
@ -7,7 +6,7 @@
expected: FAIL expected: FAIL
[Sanity check: this all works as expected with no promises involved] [Sanity check: this all works as expected with no promises involved]
expected: TIMEOUT expected: FAIL
[Thenable resolution] [Thenable resolution]
expected: FAIL expected: FAIL

View file

@ -7,13 +7,13 @@
expected: FAIL expected: FAIL
[content-type 2 : text/html,text/plain] [content-type 2 : text/html,text/plain]
expected: TIMEOUT expected: FAIL
[content-type 3 : text/plain;charset=gbk,text/html] [content-type 3 : text/plain;charset=gbk,text/html]
expected: NOTRUN expected: FAIL
[content-type 4 : text/plain;charset=gbk,text/html;charset=windows-1254] [content-type 4 : text/plain;charset=gbk,text/html;charset=windows-1254]
expected: NOTRUN expected: TIMEOUT
[content-type 5 : text/plain;charset=gbk,text/plain] [content-type 5 : text/plain;charset=gbk,text/plain]
expected: NOTRUN expected: NOTRUN

View file

@ -1,5 +1,4 @@
[nextHopProtocol-is-tao-protected.https.html] [nextHopProtocol-is-tao-protected.https.html]
expected: TIMEOUT
[Add TAO-less iframe from remote origin. Make sure nextHopProtocol is the empty string] [Add TAO-less iframe from remote origin. Make sure nextHopProtocol is the empty string]
expected: TIMEOUT expected: TIMEOUT
@ -25,28 +24,16 @@
expected: FAIL expected: FAIL
[Fetch TAO'd object from remote origin. Make sure nextHopProtocol is not the empty string.] [Fetch TAO'd object from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: TIMEOUT expected: FAIL
[Fetch TAO-less script from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
[Fetch TAO'd script from remote origin. Make sure nextHopProtocol is not the empty string.] [Fetch TAO'd script from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN expected: FAIL
[Fetch TAO-less stylesheet from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
[Fetch TAO'd stylesheet from remote origin. Make sure nextHopProtocol is not the empty string.] [Fetch TAO'd stylesheet from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN expected: FAIL
[Fetch TAO-less synchronous xhr from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
[Fetch TAO'd synchronous xhr from remote origin. Make sure nextHopProtocol is not the empty string.] [Fetch TAO'd synchronous xhr from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN expected: FAIL
[Fetch TAO-less asynchronous xhr from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
[Fetch TAO'd asynchronous xhr from remote origin. Make sure nextHopProtocol is not the empty string.] [Fetch TAO'd asynchronous xhr from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN expected: FAIL

View file

@ -1,5 +1,4 @@
[object-not-found-adds-entry.html] [object-not-found-adds-entry.html]
expected: TIMEOUT
[Test that an navigation object with a 200 response displays an entry] [Test that an navigation object with a 200 response displays an entry]
expected: FAIL expected: FAIL
@ -16,4 +15,4 @@
expected: FAIL expected: FAIL
[Verify that a 404 img-typed object emits an entry.] [Verify that a 404 img-typed object emits an entry.]
expected: TIMEOUT expected: FAIL

View file

@ -238,37 +238,37 @@
expected: FAIL expected: FAIL
[This test validates the response status of resources. 79] [This test validates the response status of resources. 79]
expected: TIMEOUT expected: FAIL
[This test validates the response status of resources. 80] [This test validates the response status of resources. 80]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 81] [This test validates the response status of resources. 81]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 82] [This test validates the response status of resources. 82]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 83] [This test validates the response status of resources. 83]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 84] [This test validates the response status of resources. 84]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 85] [This test validates the response status of resources. 85]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 86] [This test validates the response status of resources. 86]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 87] [This test validates the response status of resources. 87]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 88] [This test validates the response status of resources. 88]
expected: NOTRUN expected: FAIL
[This test validates the response status of resources. 89] [This test validates the response status of resources. 89]
expected: NOTRUN expected: TIMEOUT
[This test validates the response status of resources. 90] [This test validates the response status of resources. 90]
expected: NOTRUN expected: NOTRUN
@ -899,3 +899,153 @@
[This test validates the response status of resources. 299] [This test validates the response status of resources. 299]
expected: NOTRUN expected: NOTRUN
[This test validates the response status of resources. 300]
expected: NOTRUN
[This test validates the response status of resources. 301]
expected: NOTRUN
[This test validates the response status of resources. 302]
expected: NOTRUN
[This test validates the response status of resources. 303]
expected: NOTRUN
[This test validates the response status of resources. 304]
expected: NOTRUN
[This test validates the response status of resources. 305]
expected: NOTRUN
[This test validates the response status of resources. 306]
expected: NOTRUN
[This test validates the response status of resources. 307]
expected: NOTRUN
[This test validates the response status of resources. 308]
expected: NOTRUN
[This test validates the response status of resources. 309]
expected: NOTRUN
[This test validates the response status of resources. 310]
expected: NOTRUN
[This test validates the response status of resources. 311]
expected: NOTRUN
[This test validates the response status of resources. 312]
expected: NOTRUN
[This test validates the response status of resources. 313]
expected: NOTRUN
[This test validates the response status of resources. 314]
expected: NOTRUN
[This test validates the response status of resources. 315]
expected: NOTRUN
[This test validates the response status of resources. 316]
expected: NOTRUN
[This test validates the response status of resources. 317]
expected: NOTRUN
[This test validates the response status of resources. 318]
expected: NOTRUN
[This test validates the response status of resources. 319]
expected: NOTRUN
[This test validates the response status of resources. 320]
expected: NOTRUN
[This test validates the response status of resources. 321]
expected: NOTRUN
[This test validates the response status of resources. 322]
expected: NOTRUN
[This test validates the response status of resources. 323]
expected: NOTRUN
[This test validates the response status of resources. 324]
expected: NOTRUN
[This test validates the response status of resources. 325]
expected: NOTRUN
[This test validates the response status of resources. 326]
expected: NOTRUN
[This test validates the response status of resources. 327]
expected: NOTRUN
[This test validates the response status of resources. 328]
expected: NOTRUN
[This test validates the response status of resources. 329]
expected: NOTRUN
[This test validates the response status of resources. 330]
expected: NOTRUN
[This test validates the response status of resources. 331]
expected: NOTRUN
[This test validates the response status of resources. 332]
expected: NOTRUN
[This test validates the response status of resources. 333]
expected: NOTRUN
[This test validates the response status of resources. 334]
expected: NOTRUN
[This test validates the response status of resources. 335]
expected: NOTRUN
[This test validates the response status of resources. 336]
expected: NOTRUN
[This test validates the response status of resources. 337]
expected: NOTRUN
[This test validates the response status of resources. 338]
expected: NOTRUN
[This test validates the response status of resources. 339]
expected: NOTRUN
[This test validates the response status of resources. 340]
expected: NOTRUN
[This test validates the response status of resources. 341]
expected: NOTRUN
[This test validates the response status of resources. 342]
expected: NOTRUN
[This test validates the response status of resources. 343]
expected: NOTRUN
[This test validates the response status of resources. 344]
expected: NOTRUN
[This test validates the response status of resources. 345]
expected: NOTRUN
[This test validates the response status of resources. 346]
expected: NOTRUN
[This test validates the response status of resources. 347]
expected: NOTRUN
[This test validates the response status of resources. 348]
expected: NOTRUN
[This test validates the response status of resources. 349]
expected: NOTRUN

View file

@ -1,5 +1,4 @@
[audiocontext-not-fully-active.html] [audiocontext-not-fully-active.html]
expected: TIMEOUT
[frame in navigated remote-site frame] [frame in navigated remote-site frame]
expected: FAIL expected: FAIL

View file

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

View file

@ -0,0 +1,3 @@
[scrollBy.html]
[Ensure that the window.scrollBy function affects scroll position as expected]
expected: FAIL

View file

@ -0,0 +1,78 @@
<!DOCTYPE html>
<title>Tests CSS transition of anchor() and anchor-size() functions</title>
<link rel="help" href="https://drafts4.csswg.org/css-anchor-1/">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/8180"></script>
<link rel="author" href="mailto:xiaochengh@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
#anchor1 {
margin-left: 0px;
margin-top: 0px;
width: 200px;
height: 100px;
background: orange;
anchor-name: --a1;
}
#anchor2 {
margin-left: 400px;
margin-top: 200px;
width: 100px;
height: 200px;
background: orange;
anchor-name: --a2;
}
#target {
position: fixed;
width: 100px;
height: 100px;
background-color: lime;
transition: all 10s -5s linear;
}
#target.before {
top: anchor(--a1 top);
left: anchor(--a1 right);
width: anchor-size(--a1 width);
height: anchor-size(--a1 height);
}
#target.after {
top: anchor(--a2 bottom);
left: anchor(--a2 left);
width: anchor-size(--a2 width);
height: anchor-size(--a2 height);
}
</style>
<div id="anchor1"></div>
<div id="anchor2"></div>
<div id="target" class="before"></div>
<script>
setup(() => {
// Forces layout
target.offsetLeft;
// Triggers transition starting at 50% immediately
target.classList.remove('before');
target.classList.add('after');
});
test(() => {
assert_equals(target.offsetLeft, 300);
assert_equals(target.offsetTop, 250);
}, 'Transition of anchor() when changing target anchor element name');
test(() => {
assert_equals(target.offsetWidth, 150);
assert_equals(target.offsetHeight, 150);
}, 'Transition of anchor-size() when changing target anchor element name');
</script>

View file

@ -0,0 +1,70 @@
<!DOCTYPE html>
<title>Tests CSS transition of anchor() across tree scopes</title>
<link rel="help" href="https://drafts4.csswg.org/css-anchor-1/">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/8180"></script>
<link rel="author" href="mailto:xiaochengh@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
#anchor1 {
width: 100px;
height: 100px;
background: orange;
anchor-name: --a;
}
#anchor2 {
width: 100px;
height: 100px;
margin-top: 200px;
margin-left: 300px;
background: orange;
}
#anchor2.after::part(target) {
top: anchor(--a top);
left: anchor(--a right);
}
</style>
<div id="anchor1"></div>
<div id="anchor2"></div>
<script>
setup(() => {
let shadow = anchor2.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>
:host { anchor-name: --a; }
#target {
position: fixed;
width: 100px;
height: 100px;
background: lime;
top: anchor(--a top);
left: anchor(--a right);
transition: all 10s -5s linear;
}
</style>
<div id="target" part="target"></div>
`;
});
test(() => {
let target = anchor2.shadowRoot.getElementById('target');
// Forces layout
target.offsetLeft;
// Triggers a transition from using #anchor2 to using #anchor1,
// starting immediately at 50% progress.
anchor2.classList.add('after');
assert_equals(target.offsetLeft, 250);
assert_equals(target.offsetTop, 150);
}, 'Transition with anchor names defined in different tree scopes');
</script>

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<title>Tests CSS transition of anchor() across three tree scopes</title>
<link rel="help" href="https://drafts4.csswg.org/css-anchor-1/">
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/8180"></script>
<link rel="author" href="mailto:xiaochengh@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
body {
margin: 0;
}
#anchor1 {
width: 100px;
height: 100px;
background: orange;
anchor-name: --a;
}
#host.after::part(target) {
left: anchor(--a left);
}
</style>
<div id="anchor1"></div>
<div id="host"></div>
<script>
setup(() => {
let shadow = host.attachShadow({mode: 'open'});
shadow.innerHTML = `
<style>
div {
width: 100px;
height: 100px;
background: orange;
}
#anchor2 {
margin-left: 200px;
anchor-name: --a;
}
#anchor3 {
margin-left: 400px;
}
#target {
position: fixed;
background: lime;
top: 300px;
transition: left 10s -5s linear;
}
#target.after {
left: anchor(--a left);
}
</style>
<div id="anchor2"></div>
<div id="anchor3">
<div id="target" part="target"></div>
</div>
`;
let anchor3 = shadow.getElementById('anchor3');
let innerShadow = anchor3.attachShadow({mode: 'open'});
innerShadow.innerHTML = `
<style>
:host { anchor-name: --a; }
::slotted(*) { left: anchor(--a left); }
</style>
<slot></slot>
`;
});
test(() => {
let target = host.shadowRoot.getElementById('target');
// Forces layout
target.offsetLeft;
// Triggers a transition from using #anchor3 to using #anchor2,
// starting immediately at 50% progress
target.classList.add('after');
assert_equals(target.offsetLeft, 300);
// Triggers another transition to using #anchor1 while the previous
// transition is still in progress.
host.classList.add('after');
assert_equals(target.offsetLeft, 150);
}, 'Transition with anchor names defined in three different tree scopes');
</script>

View file

@ -25,7 +25,6 @@
`.foo {\n .bar > & { color: green; }\n}`, `.foo {\n .bar > & { color: green; }\n}`,
`.foo, .bar {\n & + .baz, &.qux { color: green; }\n}`, `.foo, .bar {\n & + .baz, &.qux { color: green; }\n}`,
`.foo {\n & .bar & .baz & .qux { color: green; }\n}`, `.foo {\n & .bar & .baz & .qux { color: green; }\n}`,
`.foo {\n @media (min-width: 50px) {\n & { color: green; }\n}\n}`,
`.foo {\n @media (min-width: 50px) { color: green; }\n}`, `.foo {\n @media (min-width: 50px) { color: green; }\n}`,
`main {\n & > section, & > article {\n & > header { color: green; }\n}\n}`, `main {\n & > section, & > article {\n & > header { color: green; }\n}\n}`,
] ]

View file

@ -148,6 +148,11 @@ test_not_applied('gandalf', 'grey', false);
test_not_applied('<color>', 'notacolor', false); test_not_applied('<color>', 'notacolor', false);
test_not_applied('<length>', '10em', false); test_not_applied('<length>', '10em', false);
test_not_applied('<transform-function>', 'translateX(1em)', false);
test_not_applied('<transform-function>', 'translateY(1lh)', false);
test_not_applied('<transform-list>', 'rotate(10deg) translateX(1em)', false);
test_not_applied('<transform-list>', 'rotate(10deg) translateY(1lh)', false);
// Inheritance // Inheritance
test_with_at_property({ test_with_at_property({

View file

@ -0,0 +1,42 @@
<!DOCTYPE html>
<title>Tests animation with tree-scoped names and references</title>
<meta name="assert" content="Custom counter style references should work in keyframes">
<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
<link rel="author" href="mailto:xiaochengh@chromium.org">
<link rel="match" href="scoped-reference-animation-ref.html">
<style>
/* Overrides predefined lower-roman counter-style */
@counter-style lower-roman {
system: cyclic;
symbols: 'X';
}
/* Overrides predefined upper-roman counter-style */
@counter-style upper-roman {
system: cyclic;
symbols: 'O';
}
/* Should resolve to the custom counter styles, not the predefined ones */
@keyframes list-style-type-anim {
from { list-style-type: lower-roman; }
to { list-style-type: upper-roman; }
}
#target1 {
animation: list-style-type-anim 2s -0.9s linear paused;
}
#target2 {
animation: list-style-type-anim 2s -1s linear paused;
}
</style>
<ul id="target1">
<li>List marker should be X
</ul>
<ul id="target2">
<li>List marker should be O
</ul>

View file

@ -0,0 +1,55 @@
<!DOCTYPE html>
<title>Tests animation with tree-scoped names and references</title>
<meta name="assert" content="Custom counter style references should work in shadow DOM keyframes">
<link rel="help" href="https://drafts.csswg.org/css-scoping/#shadow-names">
<link rel="author" href="mailto:xiaochengh@chromium.org">
<link rel="match" href="scoped-reference-animation-ref.html">
<style>
@counter-style lower-roman { system: extends disc; }
@counter-style upper-roman { system: extends disc; }
</style>
<div id="host">
</div>
<script>
host.attachShadow({mode: 'open'}).innerHTML = `
<style>
/* Overrides predefined and outer tree scope's custom lower-roman counter-style */
@counter-style lower-roman {
system: cyclic;
symbols: 'X';
}
/* Overrides predefined and outer tree scope's upper-roman counter-style */
@counter-style upper-roman {
system: cyclic;
symbols: 'O';
}
/* Should resolve to the custom counter styles, not the predefined or the outer
tree scope's ones */
@keyframes list-style-type-anim {
from { list-style-type: lower-roman; }
to { list-style-type: upper-roman; }
}
#target1 {
animation: list-style-type-anim 2s -0.9s linear paused;
}
#target2 {
animation: list-style-type-anim 2s -1s linear paused;
}
</style>
<ul id="target1">
<li>List marker should be X
</ul>
<ul id="target2">
<li>List marker should be O
</ul>
`;
</script>

View file

@ -0,0 +1,30 @@
<!DOCTYPE html>
<title>Tests animation with tree-scoped names and references</title>
<style>
@counter-style from-counter-style {
system: cyclic;
symbols: 'X';
}
@counter-style to-counter-style {
system: cyclic;
symbols: 'O';
}
#target1 {
list-style-type: from-counter-style;
}
#target2 {
list-style-type: to-counter-style;
}
</style>
<ul id="target1">
<li>List marker should be X
</ul>
<ul id="target2">
<li>List marker should be O
</ul>

View file

@ -0,0 +1,51 @@
<!doctype html>
<title>Resnap to focused element after relayout</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#snapper {
width: 100px;
height: 200px;
overflow-x: scroll;
scroll-snap-type: x mandatory;
color: white;
background-color: oldlace;
display: flex;
align-items: center;
}
.child {
margin-right: 0.5rem;
height: 90%;
scroll-snap-align: start;
padding: 1rem;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
width: 100px;
height: 100px;
background-color: indigo;
}
</style>
<link rel="help" href="https://drafts.csswg.org/css-scroll-snap/#re-snap">
<div id=snapper>
<div class="child no-snap" tabindex=-1></div>
<div class=child></div>
<div class="child" id ="focus" tabindex=-1></div>
<div class="child" tabindex=-1></div>
<div class=child></div>
<div class=child></div>
</div>
<script>
test(t => {
document.getElementById("focus").focus();
const element = document.getElementById("snapper");
element.style.width = "101px";
assert_equals(element.scrollLeft, 0);
});
</script>

View file

@ -50,7 +50,7 @@
<span>サンプルサンプル文<span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル文<span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
</div> </div>
<div class="wrapper"> <div class="wrapper">
@ -59,7 +59,7 @@
<span>サンプルサンプル文<span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル文<span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
</div> </div>
</body> </body>

View file

@ -50,7 +50,7 @@
<span>サンプルサンプル文<span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル文<span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
</div> </div>
<div class="wrapper"> <div class="wrapper">
@ -59,7 +59,7 @@
<span>サンプルサンプル文<span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル文<span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
</div> </div>
</body> </body>

View file

@ -41,19 +41,19 @@
<div class="wrapper"> <div class="wrapper">
<!-- inseparable characters TWO DOT LEADER --> <!-- inseparable characters TWO DOT LEADER -->
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
</div> </div>
<div class="wrapper"> <div class="wrapper">
<!-- inseparable characters HORIZONTAL ELLIPSIS --> <!-- inseparable characters HORIZONTAL ELLIPSIS -->
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
</div> </div>
</body> </body>

View file

@ -41,19 +41,19 @@
<div class="wrapper"> <div class="wrapper">
<!-- inseparable characters TWO DOT LEADER --> <!-- inseparable characters TWO DOT LEADER -->
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p> </p>
</div> </div>
<div class="wrapper"> <div class="wrapper">
<!-- inseparable characters HORIZONTAL ELLIPSIS --> <!-- inseparable characters HORIZONTAL ELLIPSIS -->
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
<p class="control" lang="ja"> <p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span> <span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p> </p>
</div> </div>
</body> </body>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: line breaking with white-space: break-spaces and element boundaries</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com" />
<link rel="help" title="3. White Space and Wrapping: the white-space property" href="https://drafts.csswg.org/css-text-3/#white-space-property">
<link rel="help" title="5.1. Line Breaking Details" href="https://drafts.csswg.org/css-text-3/#line-break-details">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-break-spaces">
<meta name="flags" content="ahem">
<link rel="match" href="reference/white-space-break-spaces-005-ref.html">
<meta name="assert" content="An element boundary doesn't allow breaking if white-space is set to break-spaces at both sides of the boundary">
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
<style>
div {
font: 25px/1 Ahem;
}
.fail {
position: absolute;
color: red;
z-index: -1;
}
.fail span { color: green; }
.test {
color: green;
width: 4ch;
white-space: break-spaces;
}
</style>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div class="fail">XXXX<br>X<span>X</span>X<span>X</span><br>XX<span>XX</span><br>X<span>X</span>X<span>X</span></div>
<div class="test"><span>XXXX</span> X X XX<span> </span><span> </span>X X</div>

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class=reftest-wait> <html class="reftest-wait foo">
<title>View transitions: ensure :only-child is supported on view-transition-group</title> <title>View transitions: ensure :only-child is supported on view-transition-group</title>
<link rel="help" href="https://github.com/WICG/view-transitions"> <link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org"> <link rel="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<style> <style>
::view-transition {
background-color: black;
}
html:only-child {
background-color: black;
}
:root:only-child {
background-color: black;
}
:only-child {
background-color: black;
}
.foo:only-child {
background-color: black;
}
::view-transition-group(root) { ::view-transition-group(root) {
background-color: blue; background-color: blue;
} }

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class=reftest-wait> <html class="reftest-wait foo">
<title>View transitions: ensure :only-child is supported on view-transition-image-pair</title> <title>View transitions: ensure :only-child is supported on view-transition-image-pair</title>
<link rel="help" href="https://github.com/WICG/view-transitions"> <link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org"> <link rel="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<style> <style>
::view-transition {
background-color: black;
}
html:only-child {
background-color: black;
}
:root:only-child {
background-color: black;
}
:only-child {
background-color: black;
}
.foo:only-child {
background-color: black;
}
::view-transition-image-pair(root):only-child { ::view-transition-image-pair(root):only-child {
background-color: red; background-color: red;
} }

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class=reftest-wait> <html class="reftest-wait foo">
<title>View transitions: ensure :only-child is supported on view-transition-new</title> <title>View transitions: ensure :only-child is supported on view-transition-new</title>
<link rel="help" href="https://github.com/WICG/view-transitions"> <link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org"> <link rel="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<style> <style>
::view-transition {
background-color: black;
}
html:only-child {
background-color: black;
}
:root:only-child {
background-color: black;
}
:only-child {
background-color: black;
}
.foo:only-child {
background-color: black;
}
::view-transition-new(root) { ::view-transition-new(root) {
background-color: blue; background-color: blue;
} }

View file

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html class=reftest-wait> <html class="reftest-wait foo">
<title>View transitions: ensure :only-child is supported on view-transition-old</title> <title>View transitions: ensure :only-child is supported on view-transition-old</title>
<link rel="help" href="https://github.com/WICG/view-transitions"> <link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org"> <link rel="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<style> <style>
::view-transition {
background-color: black;
}
html:only-child {
background-color: black;
}
:root:only-child {
background-color: black;
}
:only-child {
background-color: black;
}
.foo:only-child {
background-color: black;
}
::view-transition-old(root) { ::view-transition-old(root) {
background-color: blue; background-color: blue;
} }

View file

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html class="reftest-wait foo">
<title>View transitions: ensure :only-child is supported on view-transition</title>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
::view-transition {
background-color: red;
}
html:only-child {
background-color: blue;
}
:root:only-child {
background-color: blue;
}
:only-child {
background-color: blue;
}
.foo:only-child {
background-color: blue;
}
</style>
<script>
promise_test(() => {
return new Promise(async (resolve, reject) => {
let transition = document.startViewTransition();
transition.ready.then(() => {
let style = getComputedStyle(
document.documentElement, ":view-transition");
if (style.backgroundColor == "rgb(255, 0, 0)")
resolve();
else
reject(style.backgroundColor);
});
});
}, ":only-child is not supported on view-transition");
</script>

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-syntax-3/#parse-comma-separated-list-of-component-values">
<script type="text/javascript" src="/resources/testharness.js"></script>
<script type="text/javascript" src="/resources/testharnessreport.js"></script>
<script>
function test_parsing(query, expected) {
test(() => {
const match = window.matchMedia(query);
assert_equals(match.media, expected)
}, "Test parsing '" + query + "' with matchMedia");
}
test_parsing("", "");
test_parsing(" ", "");
test_parsing("all", "all");
test_parsing(" all", "all");
test_parsing(" all ", "all");
test_parsing("all,all", "all, all");
test_parsing(" all , all ", "all, all");
test_parsing("(color)", "(color)");
test_parsing("(color", "(color)");
test_parsing(" (color)", "(color)");
test_parsing(" ( color ) ", "(color)");
test_parsing(" ( color ", "(color)");
test_parsing("color)", "not all");
test_parsing(" color)", "not all");
test_parsing(" color ), ( color", "not all, (color)");
test_parsing(" foo ", "foo");
test_parsing(",", "not all, not all");
test_parsing(" , ", "not all, not all");
test_parsing(",,", "not all, not all, not all");
test_parsing(" , , ", "not all, not all, not all");
test_parsing(" foo,", "foo, not all");
</script>

View file

@ -110,5 +110,27 @@ test(() => {
container.innerHTML = '<fieldset disabled><my-control>'; container.innerHTML = '<fieldset disabled><my-control>';
assert_array_equals(container.querySelector('my-control').disabledHistory(), [true]); assert_array_equals(container.querySelector('my-control').disabledHistory(), [true]);
}, 'Upgrading an element with disabled content attribute'); }, 'Upgrading an element with disabled content attribute');
test(() => {
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = '<fieldset disabled><my-control></my-control></fieldset>';
const control = container.querySelector('my-control');
control.setAttribute('disabled', '');
control.removeAttribute('disabled');
assert_array_equals(control.disabledHistory(), [true]);
}, 'Toggling "disabled" attribute on a custom element inside disabled <fieldset> does not trigger a callback');
test(() => {
const container = document.createElement('div');
document.body.appendChild(container);
container.innerHTML = '<fieldset><my-control disabled></my-control></fieldset>';
const fieldset = container.firstElementChild;
fieldset.disabled = true;
fieldset.disabled = false;
assert_array_equals(container.querySelector('my-control').disabledHistory(), [true]);
}, 'Toggling "disabled" attribute on a <fieldset> does not trigger a callback on disabled custom element descendant');
</script> </script>
</body> </body>

View file

@ -0,0 +1,22 @@
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Presubmit script for t/b/web_tests/external/wpt/html/canvas/tools.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""
USE_PYTHON3 = True
def CommonChecks(input_api, output_api):
return input_api.canned_checks.RunPylint(input_api, output_api)
def CheckChangeOnUpload(input_api, output_api):
return CommonChecks(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return CommonChecks(input_api, output_api)

View file

@ -1,6 +1,8 @@
from gentestutils import genTestUtils from gentestutils import genTestUtils
from gentestutilsunion import genTestUtils_union from gentestutilsunion import genTestUtils_union
genTestUtils('../element', '../element', 'templates.yaml', 'name2dir-canvas.yaml', False) genTestUtils('../element', '../element', 'templates.yaml',
genTestUtils('../offscreen', '../offscreen', 'templates.yaml', 'name2dir-offscreen.yaml', True) 'name2dir-canvas.yaml', False)
genTestUtils('../offscreen', '../offscreen', 'templates.yaml',
'name2dir-offscreen.yaml', True)
genTestUtils_union('templates-new.yaml', 'name2dir.yaml') genTestUtils_union('templates-new.yaml', 'name2dir.yaml')

View file

@ -6,19 +6,20 @@
# It has been adapted for use with the Web Platform Test Suite suite at # It has been adapted for use with the Web Platform Test Suite suite at
# https://github.com/web-platform-tests/wpt/ # https://github.com/web-platform-tests/wpt/
# #
# The original version had a number of now-removed features (multiple versions of # The original version had a number of now-removed features (multiple versions
# each test case of varying verbosity, Mozilla mochitests, semi-automated test # of each test case of varying verbosity, Mozilla mochitests, semi-automated
# harness). It also had a different directory structure. # test harness). It also had a different directory structure.
# To update or add test cases: # To update or add test cases:
# #
# * Modify the tests*.yaml files. # * Modify the tests*.yaml files.
# 'name' is an arbitrary hierarchical name to help categorise tests. # - 'name' is an arbitrary hierarchical name to help categorise tests.
# 'desc' is a rough description of what behaviour the test aims to test. # - 'desc' is a rough description of what behaviour the test aims to test.
# 'code' is JavaScript code to execute, with some special commands starting with '@' # - 'code' is JavaScript code to execute, with some special commands starting
# 'expected' is what the final canvas output should be: a string 'green' or 'clear' # with '@'
# (100x50 images in both cases), or a string 'size 100 50' (or any other size) # - 'expected' is what the final canvas output should be: a string 'green' or
# followed by Python code using Pycairo to generate the image. # 'clear' (100x50 images in both cases), or a string 'size 100 50' (or any
# other size) followed by Python code using Pycairo to generate the image.
# #
# * Run "./build.sh". # * Run "./build.sh".
# This requires a few Python modules which might not be ubiquitous. # This requires a few Python modules which might not be ubiquitous.
@ -27,43 +28,49 @@
# #
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc. # * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
from __future__ import print_function from typing import List, Optional
import re import re
import codecs import codecs
import time import importlib
import os import os
import shutil
import sys import sys
import xml.dom.minidom
from xml.dom.minidom import Node
try: try:
import cairocffi as cairo import cairocffi as cairo # type: ignore
except ImportError: except ImportError:
import cairo import cairo
try: try:
import syck as yaml # compatible and lots faster # Compatible and lots faster.
import syck as yaml # type: ignore
except ImportError: except ImportError:
import yaml import yaml
def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOFFSCREENCANVAS):
class Error(Exception):
"""Base class for all exceptions raised by this module"""
class InvalidTestDefinitionError(Error):
"""Raised on invalid test definition."""
def genTestUtils(TESTOUTPUTDIR: str, IMAGEOUTPUTDIR: str, TEMPLATEFILE: str,
NAME2DIRFILE: str, ISOFFSCREENCANVAS: bool) -> None:
MISCOUTPUTDIR = './output' MISCOUTPUTDIR = './output'
def simpleEscapeJS(str): def simpleEscapeJS(string: str) -> str:
return str.replace('\\', '\\\\').replace('"', '\\"') return string.replace('\\', '\\\\').replace('"', '\\"')
def escapeJS(str): def escapeJS(string: str) -> str:
str = simpleEscapeJS(str) string = simpleEscapeJS(string)
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output # Kind of an ugly hack, for nicer failure-message output.
return str string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
return string
def escapeHTML(str): def expand_nonfinite(method: str, argstr: str, tail: str) -> str:
return str.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
def expand_nonfinite(method, argstr, tail):
""" """
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';') >>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
f(a, 0); f(a, 0);
@ -80,14 +87,18 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
f(0, b, d); f(0, b, d);
""" """
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually # argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
# 'invalid' is Infinity/-Infinity/NaN) # 'invalid' is Infinity/-Infinity/NaN).
args = [] args = []
for arg in argstr.split(', '): for arg in argstr.split(', '):
a = re.match('<(.*)>', arg).group(1) match = re.match('<(.*)>', arg)
if match is None:
raise InvalidTestDefinitionError(
f"Expected arg to match format '<(.*)>', but was: {arg}")
a = match.group(1)
args.append(a.split(' ')) args.append(a.split(' '))
calls = [] calls = []
# Start with the valid argument list # Start with the valid argument list.
call = [ args[j][0] for j in range(len(args)) ] call = [args[j][0] for j in range(len(args))]
# For each argument alone, try setting it to all its invalid values: # For each argument alone, try setting it to all its invalid values:
for i in range(len(args)): for i in range(len(args)):
for a in args[i][1:]: for a in args[i][1:]:
@ -97,39 +108,45 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
# For all combinations of >= 2 arguments, try setting them to their # For all combinations of >= 2 arguments, try setting them to their
# first invalid values. (Don't do all invalid values, because the # first invalid values. (Don't do all invalid values, because the
# number of combinations explodes.) # number of combinations explodes.)
def f(c, start, depth): def f(c: List[str], start: int, depth: int) -> None:
for i in range(start, len(args)): for i in range(start, len(args)):
if len(args[i]) > 1: if len(args[i]) > 1:
a = args[i][1] a = args[i][1]
c2 = c[:] c2 = c[:]
c2[i] = a c2[i] = a
if depth > 0: calls.append(c2) if depth > 0:
f(c2, i+1, depth+1) calls.append(c2)
f(c2, i + 1, depth + 1)
f(call, 0, 0) f(call, 0, 0)
return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls) return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail)
for c in calls)
# Run with --test argument to run unit tests # Run with --test argument to run unit tests
if len(sys.argv) > 1 and sys.argv[1] == '--test': if len(sys.argv) > 1 and sys.argv[1] == '--test':
import doctest doctest = importlib.import_module('doctest')
doctest.testmod() doctest.testmod()
sys.exit() sys.exit()
templates = yaml.safe_load(open(TEMPLATEFILE, "r").read()) templates = yaml.safe_load(open(TEMPLATEFILE, 'r').read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, "r").read()) name_mapping = yaml.safe_load(open(NAME2DIRFILE, 'r').read())
tests = [] tests = []
test_yaml_directory = "yaml/element" test_yaml_directory = 'yaml/element'
if ISOFFSCREENCANVAS: if ISOFFSCREENCANVAS:
test_yaml_directory = "yaml/offscreen" test_yaml_directory = 'yaml/offscreen'
TESTSFILES = [ TESTSFILES = [
os.path.join(test_yaml_directory, f) for f in os.listdir(test_yaml_directory) os.path.join(test_yaml_directory, f)
if f.endswith(".yaml")] for f in os.listdir(test_yaml_directory) if f.endswith('.yaml')
for t in sum([ yaml.safe_load(open(f, "r").read()) for f in TESTSFILES], []): ]
for t in sum([yaml.safe_load(open(f, 'r').read()) for f in TESTSFILES],
[]):
if 'DISABLED' in t: if 'DISABLED' in t:
continue continue
if 'meta' in t: if 'meta' in t:
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests}) eval(compile(t['meta'], '<meta test>', 'exec'), {},
{'tests': tests})
else: else:
tests.append(t) tests.append(t)
@ -137,98 +154,85 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
category_contents_direct = {} category_contents_direct = {}
category_contents_all = {} category_contents_all = {}
def backref_html(name): def backref_html(name: str) -> str:
backrefs = [] backrefs = []
c = '' c = ''
for p in name.split('.')[:-1]: for p in name.split('.')[:-1]:
c += '.'+p c += '.' + p
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p)) backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
backrefs.append(name.split('.')[-1]) backrefs.append(name.split('.')[-1])
return ''.join(backrefs) return ''.join(backrefs)
def make_flat_image(filename, w, h, r,g,b,a): # Ensure the test output directories exist.
if os.path.exists('%s/%s' % (IMAGEOUTPUTDIR, filename)):
return filename
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
cr = cairo.Context(surface)
cr.set_source_rgba(r, g, b, a)
cr.rectangle(0, 0, w, h)
cr.fill()
surface.write_to_png('%s/%s' % (IMAGEOUTPUTDIR, filename))
return filename
# Ensure the test output directories exist
testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR] testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR]
for map_dir in set(name_mapping.values()): for map_dir in set(name_mapping.values()):
testdirs.append("%s/%s" % (TESTOUTPUTDIR, map_dir)) testdirs.append('%s/%s' % (TESTOUTPUTDIR, map_dir))
for d in testdirs: for d in testdirs:
try: os.mkdir(d) try:
except: pass # ignore if it already exists os.mkdir(d)
except FileExistsError:
pass # Ignore if it already exists.
used_images = {} used_images = {}
def map_name(name): def map_name(name: str) -> Optional[str]:
mapped_name = None mapped_name = None
for mn in sorted(name_mapping.keys(), key=len, reverse=True): for mn in sorted(name_mapping.keys(), key=len, reverse=True):
if name.startswith(mn): if name.startswith(mn):
mapped_name = "%s/%s" % (name_mapping[mn], name) mapped_name = '%s/%s' % (name_mapping[mn], name)
break break
if not mapped_name: if not mapped_name:
print("LIKELY ERROR: %s has no defined target directory mapping" % name) print('LIKELY ERROR: %s has no defined target directory mapping' %
name)
return None
if 'manual' in test: if 'manual' in test:
mapped_name += "-manual" mapped_name += '-manual'
return mapped_name return mapped_name
def expand_test_code(code): def expand_test_code(code: str) -> str:
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws' code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m:
expand_nonfinite(m.group(1), m.group(2), m.group(3)),
code) # Must come before '@assert throws'.
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);', code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
r'_assertPixel(canvas, \1, \2);', r'_assertPixel(canvas, \1, \2);', code)
code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);', code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
r'_assertPixelApprox(canvas, \1, \2, 2);', r'_assertPixelApprox(canvas, \1, \2, 2);', code)
code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', code = re.sub(
r'_assertPixelApprox(canvas, \1, \2, \3);', r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
code) r'_assertPixelApprox(canvas, \1, \2, \3);', code)
code = re.sub(r'@assert throws (\S+_ERR) (.*);', code = re.sub(r'@assert throws (\S+_ERR) (.*);',
r'assert_throws_dom("\1", function() { \2; });', r'assert_throws_dom("\1", function() { \2; });', code)
code)
code = re.sub(r'@assert throws (\S+Error) (.*);', code = re.sub(r'@assert throws (\S+Error) (.*);',
r'assert_throws_js(\1, function() { \2; });', r'assert_throws_js(\1, function() { \2; });', code)
code)
code = re.sub(r'@assert (.*) === (.*);', code = re.sub(
lambda m: '_assertSame(%s, %s, "%s", "%s");' r'@assert (.*) === (.*);', lambda m:
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) '_assertSame(%s, %s, "%s", "%s");' % (m.group(1), m.group(
, code) 2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) !== (.*);', code = re.sub(
lambda m: '_assertDifferent(%s, %s, "%s", "%s");' r'@assert (.*) !== (.*);', lambda m:
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) '_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
, code) 2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) =~ (.*);', code = re.sub(
lambda m: 'assert_regexp_match(%s, %s);' r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2)) % (m.group(1), m.group(2)), code)
, code)
code = re.sub(r'@assert (.*);', code = re.sub(
lambda m: '_assert(%s, "%s");' r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
% (m.group(1), escapeJS(m.group(1))) 1), escapeJS(m.group(1))), code)
, code)
code = re.sub(r' @moz-todo', '', code) code = re.sub(r' @moz-todo', '', code)
code = re.sub(r'@moz-UniversalBrowserRead;', code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
""
, code)
assert('@' not in code) assert ('@' not in code)
return code return code
@ -237,29 +241,29 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
test = tests[i] test = tests[i]
name = test['name'] name = test['name']
print("\r(%s)" % name, " "*32, "\t") print('\r(%s)' % name, ' ' * 32, '\t')
if name in used_tests: if name in used_tests:
print("Test %s is defined twice" % name) print('Test %s is defined twice' % name)
used_tests[name] = 1 used_tests[name] = 1
mapped_name = map_name(name) mapped_name = map_name(name)
if not mapped_name: if not mapped_name:
if ISOFFSCREENCANVAS: if ISOFFSCREENCANVAS:
continue continue
else:
mapped_name = name mapped_name = name
cat_total = '' cat_total = ''
for cat_part in [''] + name.split('.')[:-1]: for cat_part in [''] + name.split('.')[:-1]:
cat_total += cat_part+'.' cat_total += cat_part + '.'
if not cat_total in category_names: category_names.append(cat_total) if not cat_total in category_names:
category_names.append(cat_total)
category_contents_all.setdefault(cat_total, []).append(name) category_contents_all.setdefault(cat_total, []).append(name)
category_contents_direct.setdefault(cat_total, []).append(name) category_contents_direct.setdefault(cat_total, []).append(name)
if test.get('expected', '') == 'green' and re.search(r'@assert pixel .* 0,0,0,0;', test['code']): if test.get('expected', '') == 'green' and re.search(
print("Probable incorrect pixel test in %s" % name) r'@assert pixel .* 0,0,0,0;', test['code']):
print('Probable incorrect pixel test in %s' % name)
code = expand_test_code(test['code']) code = expand_test_code(test['code'])
@ -268,74 +272,86 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
expected = test['expected'] expected = test['expected']
expected_img = None expected_img = None
if expected == 'green': if expected == 'green':
expected_img = "/images/green-100x50.png" expected_img = '/images/green-100x50.png'
elif expected == 'clear': elif expected == 'clear':
expected_img = "/images/clear-100x50.png" expected_img = '/images/clear-100x50.png'
else: else:
if ';' in expected: if ';' in expected:
print("Found semicolon in %s" % name) print('Found semicolon in %s' % name)
expected = re.sub(r'^size (\d+) (\d+)', expected = re.sub(
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)', r'^size (\d+) (\d+)',
expected) r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
r'\ncr = cairo.Context(surface)', expected)
if mapped_name.endswith("-manual"): if mapped_name.endswith('-manual'):
png_name = mapped_name[:-len("-manual")] png_name = mapped_name[:-len('-manual')]
else: else:
png_name = mapped_name png_name = mapped_name
expected += "\nsurface.write_to_png('%s/%s.png')\n" % (IMAGEOUTPUTDIR, png_name) expected += "\nsurface.write_to_png('%s/%s.png')\n" % (
eval(compile(expected, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo}) IMAGEOUTPUTDIR, png_name)
expected_img = "%s.png" % name eval(compile(expected, '<test %s>' % test['name'], 'exec'), {},
{'cairo': cairo})
expected_img = '%s.png' % name
if expected_img: if expected_img:
expectation_html = ('<p class="output expectedtext">Expected output:' + expectation_html = (
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img)) '<p class="output expectedtext">Expected output:<p>'
'<img src="%s" class="output expected" id="expected" '
'alt="">' % expected_img)
canvas = test.get('canvas', 'width="100" height="50"') canvas = test.get('canvas', 'width="100" height="50"')
prev = tests[i-1]['name'] if i != 0 else 'index' prev_test = tests[i - 1]['name'] if i != 0 else 'index'
next = tests[i+1]['name'] if i != len(tests)-1 else 'index' next_test = tests[i + 1]['name'] if i != len(tests) - 1 else 'index'
name_wrapped = name.replace('.', '.&#8203;') name_wrapped = name.replace('.', '.&#8203;')
notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else '' notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else ''
timeout = '\n<meta name="timeout" content="%s">' % test['timeout'] if 'timeout' in test else '' timeout = ('\n<meta name="timeout" content="%s">' %
test['timeout'] if 'timeout' in test else '')
scripts = '' scripts = ''
for s in test.get('scripts', []): for s in test.get('scripts', []):
scripts += '<script src="%s"></script>\n' % (s) scripts += '<script src="%s"></script>\n' % (s)
variants = test.get('script-variants', {}) variants = test.get('script-variants', {})
script_variants = [(v, '<script src="%s"></script>\n' % (s)) for (v, s) in variants.items()] script_variants = [(v, '<script src="%s"></script>\n' % (s))
for (v, s) in variants.items()]
if not script_variants: if not script_variants:
script_variants = [('', '')] script_variants = [('', '')]
images = '' images = ''
for i in test.get('images', []): for src in test.get('images', []):
id = i.split('/')[-1] img_id = src.split('/')[-1]
if '/' not in i: if '/' not in src:
used_images[i] = 1 used_images[src] = 1
i = '../images/%s' % i src = '../images/%s' % src
images += '<img src="%s" id="%s" class="resource">\n' % (i,id) images += '<img src="%s" id="%s" class="resource">\n' % (src,
for i in test.get('svgimages', []): img_id)
id = i.split('/')[-1] for src in test.get('svgimages', []):
if '/' not in i: img_id = src.split('/')[-1]
used_images[i] = 1 if '/' not in src:
i = '../images/%s' % i used_images[src] = 1
images += '<svg><image xlink:href="%s" id="%s" class="resource"></svg>\n' % (i,id) src = '../images/%s' % src
images = images.replace("../images/", "/images/") images += ('<svg><image xlink:href="%s" id="%s" class="resource">'
'</svg>\n' % (src, img_id))
images = images.replace('../images/', '/images/')
fonts = '' fonts = ''
fonthack = '' fonthack = ''
for i in test.get('fonts', []): for font in test.get('fonts', []):
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i) fonts += ('@font-face {\n font-family: %s;\n'
# Browsers require the font to actually be used in the page ' src: url("/fonts/%s.ttf");\n}\n' % (font, font))
# Browsers require the font to actually be used in the page.
if test.get('fonthack', 1): if test.get('fonthack', 1):
fonthack += '<span style="font-family: %s; position: absolute; visibility: hidden">A</span>\n' % i fonthack += ('<span style="font-family: %s; position: '
'absolute; visibility: hidden">A</span>\n' % font)
if fonts: if fonts:
fonts = '<style>\n%s</style>\n' % fonts fonts = '<style>\n%s</style>\n' % fonts
fallback = test.get('fallback', '<p class="fallback">FAIL (fallback content)</p>') fallback = test.get('fallback',
'<p class="fallback">FAIL (fallback content)</p>')
desc = test.get('desc', '') desc = test.get('desc', '')
escaped_desc = simpleEscapeJS(desc) escaped_desc = simpleEscapeJS(desc)
@ -351,26 +367,43 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
name_variant = '' if not variant else '.' + variant name_variant = '' if not variant else '.' + variant
template_params = { template_params = {
'name':name + name_variant, 'name': name + name_variant,
'name_wrapped':name_wrapped, 'backrefs':backref_html(name), 'name_wrapped': name_wrapped,
'mapped_name':mapped_name, 'backrefs': backref_html(name),
'desc':desc, 'escaped_desc':escaped_desc, 'mapped_name': mapped_name,
'prev':prev, 'next':next, 'notes':notes, 'images':images, 'desc': desc,
'fonts':fonts, 'fonthack':fonthack, 'timeout': timeout, 'escaped_desc': escaped_desc,
'canvas':canvas, 'expected':expectation_html, 'code':code, 'prev': prev_test,
'scripts':scripts + extra_script, 'next': next_test,
'fallback':fallback, 'attributes':attributes, 'notes': notes,
'images': images,
'fonts': fonts,
'fonthack': fonthack,
'timeout': timeout,
'canvas': canvas,
'expected': expectation_html,
'code': code,
'scripts': scripts + extra_script,
'fallback': fallback,
'attributes': attributes,
'context_args': context_args 'context_args': context_args
} }
if ISOFFSCREENCANVAS: if ISOFFSCREENCANVAS:
f = codecs.open('%s/%s%s.html' % (TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') f = codecs.open(
'%s/%s%s.html' %
(TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
f.write(templates['w3coffscreencanvas'] % template_params) f.write(templates['w3coffscreencanvas'] % template_params)
timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else '' timeout = ('// META: timeout=%s\n' %
test['timeout'] if 'timeout' in test else '')
template_params['timeout'] = timeout template_params['timeout'] = timeout
f = codecs.open('%s/%s%s.worker.js' % (TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') f = codecs.open(
'%s/%s%s.worker.js' %
(TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
f.write(templates['w3cworker'] % template_params) f.write(templates['w3cworker'] % template_params)
else: else:
f = codecs.open('%s/%s%s.html' % (TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') f = codecs.open(
'%s/%s%s.html' %
(TESTOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
f.write(templates['w3ccanvas'] % template_params) f.write(templates['w3ccanvas'] % template_params)
print() print()

View file

@ -6,19 +6,20 @@
# It has been adapted for use with the Web Platform Test Suite suite at # It has been adapted for use with the Web Platform Test Suite suite at
# https://github.com/web-platform-tests/wpt/ # https://github.com/web-platform-tests/wpt/
# #
# The original version had a number of now-removed features (multiple versions of # The original version had a number of now-removed features (multiple versions
# each test case of varying verbosity, Mozilla mochitests, semi-automated test # of each test case of varying verbosity, Mozilla mochitests, semi-automated
# harness). It also had a different directory structure. # test harness). It also had a different directory structure.
# To update or add test cases: # To update or add test cases:
# #
# * Modify the tests*.yaml files. # * Modify the tests*.yaml files.
# 'name' is an arbitrary hierarchical name to help categorise tests. # - 'name' is an arbitrary hierarchical name to help categorise tests.
# 'desc' is a rough description of what behaviour the test aims to test. # - 'desc' is a rough description of what behaviour the test aims to test.
# 'code' is JavaScript code to execute, with some special commands starting with '@' # - 'code' is JavaScript code to execute, with some special commands starting
# 'expected' is what the final canvas output should be: a string 'green' or 'clear' # with '@'.
# (100x50 images in both cases), or a string 'size 100 50' (or any other size) # - 'expected' is what the final canvas output should be: a string 'green' or
# followed by Python code using Pycairo to generate the image. # 'clear' (100x50 images in both cases), or a string 'size 100 50' (or any
# other size) followed by Python code using Pycairo to generate the image.
# #
# * Run "./build.sh". # * Run "./build.sh".
# This requires a few Python modules which might not be ubiquitous. # This requires a few Python modules which might not be ubiquitous.
@ -27,46 +28,51 @@
# #
# * Test the tests, add new ones to Git, remove deleted ones from Git, etc. # * Test the tests, add new ones to Git, remove deleted ones from Git, etc.
from __future__ import print_function from typing import List
import re import re
import codecs import codecs
import time import importlib
import os import os
import shutil
import sys import sys
import xml.dom.minidom
from xml.dom.minidom import Node
try: try:
import cairocffi as cairo import cairocffi as cairo # type: ignore
except ImportError: except ImportError:
import cairo import cairo
try: try:
import syck as yaml # compatible and lots faster # Compatible and lots faster.
import syck as yaml # type: ignore
except ImportError: except ImportError:
import yaml import yaml
def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
class Error(Exception):
"""Base class for all exceptions raised by this module"""
class InvalidTestDefinitionError(Error):
"""Raised on invalid test definition."""
def genTestUtils_union(TEMPLATEFILE: str, NAME2DIRFILE: str) -> None:
CANVASOUTPUTDIR = '../element' CANVASOUTPUTDIR = '../element'
CANVASIMAGEOUTPUTDIR = '../element' CANVASIMAGEOUTPUTDIR = '../element'
OFFSCREENCANVASOUTPUTDIR = '../offscreen' OFFSCREENCANVASOUTPUTDIR = '../offscreen'
OFFSCREENCANVASIMAGEOUTPUTDIR = '../offscreen' OFFSCREENCANVASIMAGEOUTPUTDIR = '../offscreen'
MISCOUTPUTDIR = './output' MISCOUTPUTDIR = './output'
def simpleEscapeJS(str): def simpleEscapeJS(string: str) -> str:
return str.replace('\\', '\\\\').replace('"', '\\"') return string.replace('\\', '\\\\').replace('"', '\\"')
def escapeJS(str): def escapeJS(string: str) -> str:
str = simpleEscapeJS(str) string = simpleEscapeJS(string)
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output # Kind of an ugly hack, for nicer failure-message output.
return str string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
return string
def escapeHTML(str): def expand_nonfinite(method: str, argstr: str, tail: str) -> str:
return str.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
def expand_nonfinite(method, argstr, tail):
""" """
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';') >>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
f(a, 0); f(a, 0);
@ -83,14 +89,18 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
f(0, b, d); f(0, b, d);
""" """
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually # argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
# 'invalid' is Infinity/-Infinity/NaN) # 'invalid' is Infinity/-Infinity/NaN).
args = [] args = []
for arg in argstr.split(', '): for arg in argstr.split(', '):
a = re.match('<(.*)>', arg).group(1) match = re.match('<(.*)>', arg)
if match is None:
raise InvalidTestDefinitionError(
f"Expected arg to match format '<(.*)>', but was: {arg}")
a = match.group(1)
args.append(a.split(' ')) args.append(a.split(' '))
calls = [] calls = []
# Start with the valid argument list # Start with the valid argument list.
call = [ args[j][0] for j in range(len(args)) ] call = [args[j][0] for j in range(len(args))]
# For each argument alone, try setting it to all its invalid values: # For each argument alone, try setting it to all its invalid values:
for i in range(len(args)): for i in range(len(args)):
for a in args[i][1:]: for a in args[i][1:]:
@ -100,37 +110,43 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
# For all combinations of >= 2 arguments, try setting them to their # For all combinations of >= 2 arguments, try setting them to their
# first invalid values. (Don't do all invalid values, because the # first invalid values. (Don't do all invalid values, because the
# number of combinations explodes.) # number of combinations explodes.)
def f(c, start, depth): def f(c: List[str], start: int, depth: int) -> None:
for i in range(start, len(args)): for i in range(start, len(args)):
if len(args[i]) > 1: if len(args[i]) > 1:
a = args[i][1] a = args[i][1]
c2 = c[:] c2 = c[:]
c2[i] = a c2[i] = a
if depth > 0: calls.append(c2) if depth > 0:
f(c2, i+1, depth+1) calls.append(c2)
f(c2, i + 1, depth + 1)
f(call, 0, 0) f(call, 0, 0)
return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail) for c in calls) return '\n'.join('%s(%s)%s' % (method, ', '.join(c), tail)
for c in calls)
# Run with --test argument to run unit tests # Run with --test argument to run unit tests.
if len(sys.argv) > 1 and sys.argv[1] == '--test': if len(sys.argv) > 1 and sys.argv[1] == '--test':
import doctest doctest = importlib.import_module('doctest')
doctest.testmod() doctest.testmod()
sys.exit() sys.exit()
templates = yaml.safe_load(open(TEMPLATEFILE, "r").read()) templates = yaml.safe_load(open(TEMPLATEFILE, 'r').read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, "r").read()) name_mapping = yaml.safe_load(open(NAME2DIRFILE, 'r').read())
tests = [] tests = []
test_yaml_directory = "yaml-new" test_yaml_directory = 'yaml-new'
TESTSFILES = [ TESTSFILES = [
os.path.join(test_yaml_directory, f) for f in os.listdir(test_yaml_directory) os.path.join(test_yaml_directory, f)
if f.endswith(".yaml")] for f in os.listdir(test_yaml_directory) if f.endswith('.yaml')
for t in sum([ yaml.safe_load(open(f, "r").read()) for f in TESTSFILES], []): ]
for t in sum([yaml.safe_load(open(f, 'r').read()) for f in TESTSFILES],
[]):
if 'DISABLED' in t: if 'DISABLED' in t:
continue continue
if 'meta' in t: if 'meta' in t:
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests}) eval(compile(t['meta'], '<meta test>', 'exec'), {},
{'tests': tests})
else: else:
tests.append(t) tests.append(t)
@ -138,88 +154,89 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
category_contents_direct = {} category_contents_direct = {}
category_contents_all = {} category_contents_all = {}
def backref_html(name): def backref_html(name: str) -> str:
backrefs = [] backrefs = []
c = '' c = ''
for p in name.split('.')[:-1]: for p in name.split('.')[:-1]:
c += '.'+p c += '.' + p
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p)) backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
backrefs.append(name.split('.')[-1]) backrefs.append(name.split('.')[-1])
return ''.join(backrefs) return ''.join(backrefs)
# Ensure the test output directories exist # Ensure the test output directories exist.
testdirs = [CANVASOUTPUTDIR, OFFSCREENCANVASOUTPUTDIR, CANVASIMAGEOUTPUTDIR, OFFSCREENCANVASIMAGEOUTPUTDIR, MISCOUTPUTDIR] testdirs = [
CANVASOUTPUTDIR, OFFSCREENCANVASOUTPUTDIR, CANVASIMAGEOUTPUTDIR,
OFFSCREENCANVASIMAGEOUTPUTDIR, MISCOUTPUTDIR
]
for map_dir in set(name_mapping.values()): for map_dir in set(name_mapping.values()):
testdirs.append("%s/%s" % (CANVASOUTPUTDIR, map_dir)) testdirs.append('%s/%s' % (CANVASOUTPUTDIR, map_dir))
testdirs.append("%s/%s" % (OFFSCREENCANVASOUTPUTDIR, map_dir)) testdirs.append('%s/%s' % (OFFSCREENCANVASOUTPUTDIR, map_dir))
for d in testdirs: for d in testdirs:
try: os.mkdir(d) try:
except: pass # ignore if it already exists os.mkdir(d)
except FileExistsError:
pass # Ignore if it already exists,
used_images = {} used_images = {}
def map_name(name): def map_name(name: str) -> str:
mapped_name = None mapped_name = None
for mn in sorted(name_mapping.keys(), key=len, reverse=True): for mn in sorted(name_mapping.keys(), key=len, reverse=True):
if name.startswith(mn): if name.startswith(mn):
mapped_name = "%s/%s" % (name_mapping[mn], name) mapped_name = '%s/%s' % (name_mapping[mn], name)
break break
if not mapped_name: if not mapped_name:
print("LIKELY ERROR: %s has no defined target directory mapping" % name) print('LIKELY ERROR: %s has no defined target directory mapping' %
name)
return name
if 'manual' in test: if 'manual' in test:
mapped_name += "-manual" mapped_name += '-manual'
return mapped_name return mapped_name
def expand_test_code(code): def expand_test_code(code: str) -> str:
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws' code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m:
expand_nonfinite(m.group(1), m.group(2), m.group(3)),
code) # Must come before '@assert throws'.
code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);', code = re.sub(r'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
r'_assertPixel(canvas, \1, \2);', r'_assertPixel(canvas, \1, \2);', code)
code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);', code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
r'_assertPixelApprox(canvas, \1, \2, 2);', r'_assertPixelApprox(canvas, \1, \2, 2);', code)
code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);', code = re.sub(
r'_assertPixelApprox(canvas, \1, \2, \3);', r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
code) r'_assertPixelApprox(canvas, \1, \2, \3);', code)
code = re.sub(r'@assert throws (\S+_ERR) (.*);', code = re.sub(r'@assert throws (\S+_ERR) (.*);',
r'assert_throws_dom("\1", function() { \2; });', r'assert_throws_dom("\1", function() { \2; });', code)
code)
code = re.sub(r'@assert throws (\S+Error) (.*);', code = re.sub(r'@assert throws (\S+Error) (.*);',
r'assert_throws_js(\1, function() { \2; });', r'assert_throws_js(\1, function() { \2; });', code)
code)
code = re.sub(r'@assert (.*) === (.*);', code = re.sub(
lambda m: '_assertSame(%s, %s, "%s", "%s");' r'@assert (.*) === (.*);', lambda m:
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) '_assertSame(%s, %s, "%s", "%s");' % (m.group(1), m.group(
, code) 2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) !== (.*);', code = re.sub(
lambda m: '_assertDifferent(%s, %s, "%s", "%s");' r'@assert (.*) !== (.*);', lambda m:
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2))) '_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
, code) 2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) =~ (.*);', code = re.sub(
lambda m: 'assert_regexp_match(%s, %s);' r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2)) % (m.group(1), m.group(2)), code)
, code)
code = re.sub(r'@assert (.*);', code = re.sub(
lambda m: '_assert(%s, "%s");' r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
% (m.group(1), escapeJS(m.group(1))) 1), escapeJS(m.group(1))), code)
, code)
code = re.sub(r' @moz-todo', '', code) code = re.sub(r' @moz-todo', '', code)
code = re.sub(r'@moz-UniversalBrowserRead;', code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
""
, code)
assert('@' not in code) assert ('@' not in code)
return code return code
@ -231,33 +248,32 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
if test.get('canvasType', []): if test.get('canvasType', []):
HTMLCanvas_test = False HTMLCanvas_test = False
OffscreenCanvas_test = False OffscreenCanvas_test = False
for type in test.get('canvasType'): for canvas_type in test.get('canvasType'):
if type.lower() == 'htmlcanvas': if canvas_type.lower() == 'htmlcanvas':
HTMLCanvas_test = True HTMLCanvas_test = True
elif type.lower() == 'offscreencanvas': elif canvas_type.lower() == 'offscreencanvas':
OffscreenCanvas_test = True OffscreenCanvas_test = True
name = test['name'] name = test['name']
print("\r(%s)" % name, " "*32, "\t") print('\r(%s)' % name, ' ' * 32, '\t')
if name in used_tests: if name in used_tests:
print("Test %s is defined twice" % name) print('Test %s is defined twice' % name)
used_tests[name] = 1 used_tests[name] = 1
mapped_name = map_name(name) mapped_name = map_name(name)
if not mapped_name:
mapped_name = name
cat_total = '' cat_total = ''
for cat_part in [''] + name.split('.')[:-1]: for cat_part in [''] + name.split('.')[:-1]:
cat_total += cat_part+'.' cat_total += cat_part + '.'
if not cat_total in category_names: category_names.append(cat_total) if not cat_total in category_names:
category_names.append(cat_total)
category_contents_all.setdefault(cat_total, []).append(name) category_contents_all.setdefault(cat_total, []).append(name)
category_contents_direct.setdefault(cat_total, []).append(name) category_contents_direct.setdefault(cat_total, []).append(name)
if test.get('expected', '') == 'green' and re.search(r'@assert pixel .* 0,0,0,0;', test['code']): if test.get('expected', '') == 'green' and re.search(
print("Probable incorrect pixel test in %s" % name) r'@assert pixel .* 0,0,0,0;', test['code']):
print('Probable incorrect pixel test in %s' % name)
code_canvas = expand_test_code(test['code']).strip() code_canvas = expand_test_code(test['code']).strip()
@ -266,78 +282,97 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
expected = test['expected'] expected = test['expected']
expected_img = None expected_img = None
if expected == 'green': if expected == 'green':
expected_img = "/images/green-100x50.png" expected_img = '/images/green-100x50.png'
elif expected == 'clear': elif expected == 'clear':
expected_img = "/images/clear-100x50.png" expected_img = '/images/clear-100x50.png'
else: else:
if ';' in expected: if ';' in expected:
print("Found semicolon in %s" % name) print('Found semicolon in %s' % name)
expected = re.sub(r'^size (\d+) (\d+)', expected = re.sub(
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)', r'^size (\d+) (\d+)',
expected) r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
r'\ncr = cairo.Context(surface)', expected)
if mapped_name.endswith("-manual"): if mapped_name.endswith('-manual'):
png_name = mapped_name[:-len("-manual")] png_name = mapped_name[:-len('-manual')]
else: else:
png_name = mapped_name png_name = mapped_name
expected_canvas = expected + "\nsurface.write_to_png('%s/%s.png')\n" % (CANVASIMAGEOUTPUTDIR, png_name) expected_canvas = (expected +
eval(compile(expected_canvas, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo}) "\nsurface.write_to_png('%s/%s.png')\n" %
(CANVASIMAGEOUTPUTDIR, png_name))
eval(
compile(expected_canvas, '<test %s>' % test['name'],
'exec'), {}, {'cairo': cairo})
expected_offscreencanvas = expected + "\nsurface.write_to_png('%s/%s.png')\n" % (OFFSCREENCANVASIMAGEOUTPUTDIR, png_name) expected_offscreencanvas = (
eval(compile(expected_offscreencanvas, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo}) expected + "\nsurface.write_to_png('%s/%s.png')\n" %
(OFFSCREENCANVASIMAGEOUTPUTDIR, png_name))
eval(
compile(expected_offscreencanvas,
'<test %s>' % test['name'], 'exec'), {},
{'cairo': cairo})
expected_img = "%s.png" % name expected_img = '%s.png' % name
if expected_img: if expected_img:
expectation_html = ('<p class="output expectedtext">Expected output:' + expectation_html = (
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img)) '<p class="output expectedtext">Expected output:<p>'
'<img src="%s" class="output expected" id="expected" '
'alt="">' % expected_img)
canvas = test.get('canvas', 'width="100" height="50"') canvas = test.get('canvas', 'width="100" height="50"')
prev = tests[i-1]['name'] if i != 0 else 'index' prev_test = tests[i - 1]['name'] if i != 0 else 'index'
next = tests[i+1]['name'] if i != len(tests)-1 else 'index' next_test = tests[i + 1]['name'] if i != len(tests) - 1 else 'index'
name_wrapped = name.replace('.', '.&#8203;') name_wrapped = name.replace('.', '.&#8203;')
notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else '' notes = '<p class="notes">%s' % test['notes'] if 'notes' in test else ''
timeout = '\n<meta name="timeout" content="%s">' % test['timeout'] if 'timeout' in test else '' timeout = ('\n<meta name="timeout" content="%s">' %
test['timeout'] if 'timeout' in test else '')
scripts = '' scripts = ''
for s in test.get('scripts', []): for s in test.get('scripts', []):
scripts += '<script src="%s"></script>\n' % (s) scripts += '<script src="%s"></script>\n' % (s)
variants = test.get('script-variants', {}) variants = test.get('script-variants', {})
script_variants = [(v, '<script src="%s"></script>\n' % (s)) for (v, s) in variants.items()] script_variants = [(v, '<script src="%s"></script>\n' % (s))
for (v, s) in variants.items()]
if not script_variants: if not script_variants:
script_variants = [('', '')] script_variants = [('', '')]
images = '' images = ''
for i in test.get('images', []): for src in test.get('images', []):
id = i.split('/')[-1] img_id = src.split('/')[-1]
if '/' not in i: if '/' not in src:
used_images[i] = 1 used_images[src] = 1
i = '../images/%s' % i src = '../images/%s' % src
images += '<img src="%s" id="%s" class="resource">\n' % (i,id) images += '<img src="%s" id="%s" class="resource">\n' % (src,
for i in test.get('svgimages', []): img_id)
id = i.split('/')[-1] for src in test.get('svgimages', []):
if '/' not in i: img_id = src.split('/')[-1]
used_images[i] = 1 if '/' not in src:
i = '../images/%s' % i used_images[src] = 1
images += '<svg><image xlink:href="%s" id="%s" class="resource"></svg>\n' % (i,id) src = '../images/%s' % src
images = images.replace("../images/", "/images/") images += ('<svg><image xlink:href="%s" id="%s" class="resource">'
'</svg>\n' % (src, img_id))
images = images.replace('../images/', '/images/')
fonts = '' fonts = ''
fonthack = '' fonthack = ''
for i in test.get('fonts', []): for font in test.get('fonts', []):
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i) fonts += ('@font-face {\n font-family: %s;\n'
# Browsers require the font to actually be used in the page ' src: url("/fonts/%s.ttf");\n}\n' % (font, font))
# Browsers require the font to actually be used in the page.
if test.get('fonthack', 1): if test.get('fonthack', 1):
fonthack += '<span style="font-family: %s; position: absolute; visibility: hidden">A</span>\n' % i fonthack += ('<span style="font-family: %s; position: '
'absolute; visibility: hidden">A</span>\n' % font)
if fonts: if fonts:
fonts = '<style>\n%s</style>\n' % fonts fonts = '<style>\n%s</style>\n' % fonts
fallback = test.get('fallback', '<p class="fallback">FAIL (fallback content)</p>') fallback = test.get('fallback',
'<p class="fallback">FAIL (fallback content)</p>')
desc = test.get('desc', '') desc = test.get('desc', '')
escaped_desc = simpleEscapeJS(desc) escaped_desc = simpleEscapeJS(desc)
@ -353,35 +388,58 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
name_variant = '' if not variant else '.' + variant name_variant = '' if not variant else '.' + variant
template_params = { template_params = {
'name':name + name_variant, 'name': name + name_variant,
'name_wrapped':name_wrapped, 'backrefs':backref_html(name), 'name_wrapped': name_wrapped,
'mapped_name':mapped_name, 'backrefs': backref_html(name),
'desc':desc, 'escaped_desc':escaped_desc, 'mapped_name': mapped_name,
'prev':prev, 'next':next, 'notes':notes, 'images':images, 'desc': desc,
'fonts':fonts, 'fonthack':fonthack, 'timeout': timeout, 'escaped_desc': escaped_desc,
'canvas':canvas, 'expected':expectation_html, 'code':code_canvas, 'prev': prev_test,
'scripts':scripts + extra_script, 'next': next_test,
'fallback':fallback, 'attributes':attributes, 'notes': notes,
'images': images,
'fonts': fonts,
'fonthack': fonthack,
'timeout': timeout,
'canvas': canvas,
'expected': expectation_html,
'code': code_canvas,
'scripts': scripts + extra_script,
'fallback': fallback,
'attributes': attributes,
'context_args': context_args 'context_args': context_args
} }
# Create test cases for canvas and offscreencanvas. # Create test cases for canvas and offscreencanvas.
if HTMLCanvas_test: if HTMLCanvas_test:
f = codecs.open('%s/%s%s.html' % (CANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') f = codecs.open(
'%s/%s%s.html' %
(CANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
f.write(templates['w3ccanvas'] % template_params) f.write(templates['w3ccanvas'] % template_params)
if OffscreenCanvas_test: if OffscreenCanvas_test:
f_html = codecs.open('%s/%s%s.html' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') f_html = codecs.open(
f_worker = codecs.open('%s/%s%s.worker.js' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8') '%s/%s%s.html' %
if ("then(t_pass, t_fail);" in code_canvas): (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w',
temp_offscreen = templates['w3coffscreencanvas'].replace("t.done();\n", "") 'utf-8')
temp_worker = templates['w3cworker'].replace("t.done();\n", "") f_worker = codecs.open(
'%s/%s%s.worker.js' %
(OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w',
'utf-8')
if ('then(t_pass, t_fail);' in code_canvas):
temp_offscreen = templates['w3coffscreencanvas'].replace(
't.done();\n', '')
temp_worker = templates['w3cworker'].replace(
't.done();\n', '')
f_html.write(temp_offscreen % template_params) f_html.write(temp_offscreen % template_params)
timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else '' timeout = ('// META: timeout=%s\n' %
test['timeout'] if 'timeout' in test else '')
template_params['timeout'] = timeout template_params['timeout'] = timeout
f_worker.write(temp_worker % template_params) f_worker.write(temp_worker % template_params)
else: else:
f_html.write(templates['w3coffscreencanvas'] % template_params) f_html.write(templates['w3coffscreencanvas'] %
timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else '' template_params)
timeout = ('// META: timeout=%s\n' %
test['timeout'] if 'timeout' in test else '')
template_params['timeout'] = timeout template_params['timeout'] = timeout
f_worker.write(templates['w3cworker'] % template_params) f_worker.write(templates['w3cworker'] % template_params)
print() print()

View file

@ -20,25 +20,26 @@
// This document has COOP: restrict-properties. The popup has COOP: // This document has COOP: restrict-properties. The popup has COOP:
// restrict-properties. Opening from an iframe should not be different from // restrict-properties. Opening from an iframe should not be different from
// opening from the main frame and the opener should be severed. // opening from the main frame and the opener should be restricted if
// cross-origin.
[ [
{ {
"title": "same origin iframe, same origin popup", "title": "same origin iframe, same origin popup",
"iframeOrigin": SAME_ORIGIN, "iframeOrigin": SAME_ORIGIN,
"popupOrigin": SAME_ORIGIN, "popupOrigin": SAME_ORIGIN,
"opener": "restricted" "opener": "preserved"
}, },
{ {
"title": "same site iframe, same origin popup", "title": "same site iframe, same origin popup",
"iframeOrigin": SAME_SITE, "iframeOrigin": SAME_SITE,
"popupOrigin": SAME_ORIGIN, "popupOrigin": SAME_ORIGIN,
"opener": "restricted" "opener": "preserved"
}, },
{ {
"title": "cross origin iframe, same origin popup", "title": "cross origin iframe, same origin popup",
"iframeOrigin": CROSS_ORIGIN, "iframeOrigin": CROSS_ORIGIN,
"popupOrigin": SAME_ORIGIN, "popupOrigin": SAME_ORIGIN,
"opener": "restricted" "opener": "preserved"
}, },
{ {
"title": "same origin iframe, same site popup", "title": "same origin iframe, same site popup",

View file

@ -34,7 +34,7 @@
{ {
"title": "popup with coop restrict-properties", "title": "popup with coop restrict-properties",
"coop": "restrict-properties", "coop": "restrict-properties",
"opener": "restricted" "opener": "preserved"
} }
].forEach(variant => { ].forEach(variant => {
popup_test(`Same-origin ${variant.title}`, SAME_ORIGIN, popup_test(`Same-origin ${variant.title}`, SAME_ORIGIN,

View file

@ -0,0 +1,126 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=help href="https://github.com/whatwg/html/pull/8221#discussion_r1049379113">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=outerpopover popover=auto>
<button popovertoggletarget=innerpopover disabled>toggle popover</button>
</div>
<div id=innerpopover popover=auto>popover</div>
<script>
test(() => {
outerpopover.showPopover();
innerpopover.showPopover();
assert_true(innerpopover.matches(':open'),
'The inner popover should be able to open successfully.');
assert_false(outerpopover.matches(':open'),
'The outer popover should be closed by opening the inner one.');
}, 'Disabled popover*target buttons should not affect the popover heirarchy.');
</script>
<div id=outerpopover2 popover=auto>
<button id=togglebutton2 popovertoggletarget=innerpopover2>toggle popover</button>
</div>
<div id=innerpopover2 popover=auto>popover</div>
<script>
test(() => {
outerpopover2.showPopover();
innerpopover2.showPopover();
assert_true(innerpopover2.matches(':open'),
'The inner popover should be able to open successfully.');
assert_true(outerpopover2.matches(':open'),
'The outer popover should stay open when opening the inner one.');
togglebutton2.disabled = true;
assert_false(innerpopover2.matches(':open'),
'The inner popover should be closed when the hierarchy is broken.');
assert_false(outerpopover2.matches(':open'),
'The outer popover should be closed when the hierarchy is broken.');
}, 'Disabling popover*target buttons when popovers are open should still cause all popovers to be closed when the formerly outer popover is closed.');
</script>
<div id=outerpopover3 popover=auto>
<button id=togglebutton3 popovertoggletarget=innerpopover3>toggle popover</button>
</div>
<div id=innerpopover3 popover=auto>popover</div>
<script>
test(() => {
outerpopover3.showPopover();
innerpopover3.showPopover();
assert_true(innerpopover3.matches(':open'),
'The inner popover should be able to open successfully.');
assert_true(outerpopover3.matches(':open'),
'The outer popover should stay open when opening the inner one.');
togglebutton3.disabled = true;
assert_false(innerpopover3.matches(':open'),
'The inner popover be should be closed when the hierarchy is broken.');
assert_false(outerpopover3.matches(':open'),
'The outer popover be should be closed when the hierarchy is broken.');
}, 'Disabling popover*target buttons when popovers are open should still cause all popovers to be closed when the formerly inner popover is closed.');
</script>
<div id=outerpopover4 popover=auto>
<button id=togglebutton4 popovertoggletarget=innerpopover4>toggle popover</button>
</div>
<div id=innerpopover4 popover=auto>popover</div>
<form id=submitform>form</form>
<script>
test(() => {
outerpopover4.showPopover();
innerpopover4.showPopover();
assert_true(innerpopover4.matches(':open'),
'The inner popover should be able to open successfully.');
assert_true(outerpopover4.matches(':open'),
'The outer popover should stay open when opening the inner one.');
togglebutton4.setAttribute('form', 'submitform');
assert_false(innerpopover4.matches(':open'),
'The inner popover be should be closed when the hierarchy is broken.');
assert_false(outerpopover4.matches(':open'),
'The outer popover be should be closed when the hierarchy is broken.');
}, 'Setting the form attribute on popover*target buttons when popovers are open should close all popovers.');
</script>
<div id=outerpopover5 popover=auto>
<input type=button id=togglebutton5 popovertoggletarget=innerpopover5>toggle popover</button>
</div>
<div id=innerpopover5 popover=auto>popover</div>
<script>
test(() => {
outerpopover5.showPopover();
innerpopover5.showPopover();
assert_true(innerpopover5.matches(':open'),
'The inner popover should be able to open successfully.');
assert_true(outerpopover5.matches(':open'),
'The outer popover should stay open when opening the inner one.');
togglebutton5.setAttribute('type', 'text');
assert_false(innerpopover5.matches(':open'),
'The inner popover be should be closed when the hierarchy is broken.');
assert_false(outerpopover5.matches(':open'),
'The outer popover be should be closed when the hierarchy is broken.');
}, 'Changing the input type on a popover*target button when popovers are open should close all popovers.');
</script>
<div id=outerpopover6 popover=auto>
<button id=togglebutton6 popovertoggletarget=innerpopover6>toggle popover</button>
</div>
<div id=innerpopover6 popover=auto>popover</div>
<script>
test(() => {
outerpopover6.showPopover();
innerpopover6.showPopover();
assert_true(innerpopover6.matches(':open'),
'The inner popover should be able to open successfully.');
assert_true(outerpopover6.matches(':open'),
'The outer popover should stay open when opening the inner one.');
togglebutton6.remove();
assert_false(innerpopover6.matches(':open'),
'The inner popover be should be closed when the hierarchy is broken.');
assert_false(outerpopover6.matches(':open'),
'The outer popover be should be closed when the hierarchy is broken.');
}, 'Disconnecting popover*target buttons when popovers are open should close all popovers.');
</script>

View file

@ -1,7 +1,3 @@
[context.any.worker-module.html]
expected:
if product == "firefox": [TIMEOUT, OK] # https://bugzilla.mozilla.org/show_bug.cgi?id=1247687
[context.any.sharedworker-module.html] [context.any.sharedworker-module.html]
expected: expected:
if product == "firefox": TIMEOUT # https://bugzilla.mozilla.org/show_bug.cgi?id=1247687 if product == "firefox": TIMEOUT # https://bugzilla.mozilla.org/show_bug.cgi?id=1247687

View file

@ -9,7 +9,6 @@ partial interface ServiceWorkerRegistration {
[SecureContext, Exposed=(Window,Worker)] [SecureContext, Exposed=(Window,Worker)]
interface PaymentManager { interface PaymentManager {
[SameObject] readonly attribute PaymentInstruments instruments;
attribute DOMString userHint; attribute DOMString userHint;
Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations); Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
}; };
@ -21,28 +20,6 @@ enum PaymentDelegation {
"payerEmail" "payerEmail"
}; };
[SecureContext, Exposed=(Window,Worker)]
interface PaymentInstruments {
Promise<boolean> delete(DOMString instrumentKey);
Promise<any> get(DOMString instrumentKey);
Promise<sequence<DOMString>> keys();
Promise<boolean> has(DOMString instrumentKey);
Promise<undefined> set(DOMString instrumentKey, PaymentInstrument details);
Promise<undefined> clear();
};
dictionary PaymentInstrument {
required DOMString name;
sequence<ImageObject> icons;
DOMString method;
};
dictionary ImageObject {
required USVString src;
DOMString sizes;
DOMString type;
};
partial interface ServiceWorkerGlobalScope { partial interface ServiceWorkerGlobalScope {
attribute EventHandler oncanmakepayment; attribute EventHandler oncanmakepayment;
}; };

View file

@ -29,15 +29,18 @@
applyStyle(image, imageStyle); applyStyle(image, imageStyle);
applyStyle(container, containerStyle); applyStyle(container, containerStyle);
image.id = token(); image.id = token();
container.id = token();
const entryReported = new Promise(resolve => new popup.PerformanceObserver(entryList => { const entryReported = new Promise(resolve => new popup.PerformanceObserver(entryList => {
entryList.getEntries().forEach(entry => { entryList.getEntries().forEach(entry => {
if (entry.id === image.id) if (entry.id === image.id || entry.id === container.id)
resolve(entry.size); resolve(entry.size);
}); });
}).observe({type: 'largest-contentful-paint'})); }).observe({type: 'largest-contentful-paint'}));
popup.document.body.appendChild(container); popup.document.body.appendChild(container);
const timeout = new Promise(resolve => t.step_timeout(() => resolve('not reported'), 1000)); return {
return {lcpSize: (await Promise.any([entryReported, timeout])), naturalSize}; lcpSize: (await await_with_timeout(1000, 'not reported', entryReported)),
naturalSize
};
} }
// We set the image to display: none when testing background, so that only the background is reported // We set the image to display: none when testing background, so that only the background is reported

View file

@ -1,6 +1,22 @@
const image_delay = 1000; const image_delay = 1000;
const delay_pipe_value = image_delay / 1000; const delay_pipe_value = image_delay / 1000;
const await_with_timeout = async (delay, message, promise, cleanup = ()=>{}) => {
let timeout_id;
const timeout = new Promise((_, reject) => {
timeout_id = step_timeout(() =>
reject(new DOMException(message, "TimeoutError")), delay)
});
let result = null;
try {
result = await Promise.race([promise, timeout]);
clearTimeout(timeout_id);
} finally {
cleanup();
}
return result;
};
// Receives an image LargestContentfulPaint |entry| and checks |entry|'s attribute values. // Receives an image LargestContentfulPaint |entry| and checks |entry|'s attribute values.
// The |timeLowerBound| parameter is a lower bound on the loadTime value of the entry. // The |timeLowerBound| parameter is a lower bound on the loadTime value of the entry.
// The |options| parameter may contain some string values specifying the following: // The |options| parameter may contain some string values specifying the following:

View file

@ -116,8 +116,6 @@ CONSOLE: service-workers/service-worker/navigation-redirect.https.html
CONSOLE: service-workers/service-worker/resources/clients-get-other-origin.html CONSOLE: service-workers/service-worker/resources/clients-get-other-origin.html
CONSOLE: webrtc/tools/* CONSOLE: webrtc/tools/*
CONSOLE: webaudio/resources/audit.js:41 CONSOLE: webaudio/resources/audit.js:41
CONSOLE: resource-timing/resources/resource-loaders.js
CONSOLE: resource-timing/resources/entry-invariants.js
# use of console in a public library - annotation-model ensures # use of console in a public library - annotation-model ensures
# it is not actually used # it is not actually used

View file

@ -20,7 +20,6 @@ idl_test(
idl_array.add_objects({ idl_array.add_objects({
ServiceWorkerRegistration: ['registration'], ServiceWorkerRegistration: ['registration'],
PaymentManager: ['paymentManager'], PaymentManager: ['paymentManager'],
PaymentInstruments: ['instruments'],
}); });
} }
if (isServiceWorker) { if (isServiceWorker) {
@ -41,7 +40,6 @@ idl_test(
} }
if (hasRegistration) { if (hasRegistration) {
self.paymentManager = self.registration.paymentManager; self.paymentManager = self.registration.paymentManager;
self.instruments = self.paymentManager.instruments;
} }
} }
); );

View file

@ -1,379 +0,0 @@
<!doctype html>
<meta charset="utf-8">
<title>Tests for PaymentInstruments interface</title>
<link rel="help" href="https://w3c.github.io/payment-handler/#paymentinstruments-interface">
<link rel="manifest" href="manifest.json">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="register-and-activate-service-worker.js"></script>
<script>
function runTests(registration) {
const methodName = window.location.origin + '/payment-handler/payment-app/';
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set('instrument-key-1', {
name: 'Instrument Name 1',
});
await registration.paymentManager.instruments.set('instrument-key-2', {
name: 'Instrument Name 2',
});
await registration.paymentManager.instruments.delete('instrument-key-1');
await registration.paymentManager.instruments.set('instrument-key-1', {
name: 'Instrument Name 1',
});
const keys = await registration.paymentManager.instruments.keys();
assert_array_equals(keys, ['instrument-key-2', 'instrument-key-1']);
}, 'Instrument keys are returned in the original insertion order');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name',
},
);
const result = await registration.paymentManager.instruments.delete(
'existing-instrument-key',
);
assert_true(result);
}, 'Deleting an existing instrument returns true');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name',
},
);
await registration.paymentManager.instruments.delete(
'existing-instrument-key',
);
const result = await registration.paymentManager.instruments.delete(
'existing-instrument-key',
);
assert_false(result);
}, 'Deleting an existing instrument the second time returns false');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const result = await registration.paymentManager.instruments.delete(
'non-existing-instrument-key',
);
assert_false(result);
}, 'Deleting a non-existing instrument returns false');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/png',
},
],
method: methodName,
},
);
const result = await registration.paymentManager.instruments.get(
'existing-instrument-key',
);
assert_equals(result.name, 'Instrument Name');
}, 'Getting an existing instrument returns the instrument');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const result = await registration.paymentManager.instruments.get(
'non-existing-instrument-key',
);
assert_equals(result, undefined);
}, 'Getting a non-existing instrument returns undefined');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name v1',
icons: [
{src: '/images/green-16x16.png', sizes: '16x16', type: 'image/png'},
],
method: methodName,
},
);
let result = await registration.paymentManager.instruments.get(
'existing-instrument-key',
);
assert_equals(result.name, 'Instrument Name v1');
assert_equals(result.icons.length, 1);
assert_equals(
result.icons[0].src,
new URL('/images/green-16x16.png', window.location.href).href,
);
assert_equals(result.icons[0].sizes, '16x16');
assert_equals(result.icons[0].type, 'image/png');
assert_equals(result.method, methodName);
assert_array_equals(result.capabilities.supportedNetworks, ['mir']);
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name v2',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/png',
},
],
method: methodName,
},
);
result = await registration.paymentManager.instruments.get(
'existing-instrument-key',
);
assert_equals(result.name, 'Instrument Name v2');
assert_equals(result.icons.length, 1);
assert_equals(
result.icons[0].src,
new URL('/images/rgrg-256x256.png', window.location.href).href,
);
assert_equals(result.icons[0].sizes, '256x256');
assert_equals(result.icons[0].type, 'image/png');
assert_equals(result.method, methodName);
}, 'Resetting an existing instrument updates the instrument');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(
'existing-instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/png',
},
],
method: methodName,
},
);
await registration.paymentManager.instruments.clear();
const result = await registration.paymentManager.instruments.get(
'existing-instrument-key',
);
assert_equals(result, undefined);
}, 'Clearing the instruments');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/jif',
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, 'Cannot register instruments with invalid icon media type image/jif');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/pn' + 'g'.repeat(100000),
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, "Don't crash when registering instruments with very long icon media type image/pngggggg...");
promise_test(async t => {
await registration.paymentManager.instruments.clear();
return registration.paymentManager.instruments.set('instrument-key', {
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '8'.repeat(100000) + 'x' + '8'.repeat(100000),
type: 'image/png',
},
],
method: methodName,
});
}, "Don't crash when registering an instrument with a very long icon size 888...x888...");
promise_test(async t => {
await registration.paymentManager.instruments.clear();
return registration.paymentManager.instruments.set('instrument-key', {
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
type: 'image/png',
},
],
method: methodName,
});
}, "Don't crash when 'sizes' missing from icon definition");
promise_test(async t => {
await registration.paymentManager.instruments.clear();
return registration.paymentManager.instruments.set('instrument-key', {
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256x256',
},
],
method: methodName,
});
}, "Don't crash when 'type' missing from icon definition");
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rgrg-256x256.png',
sizes: '256 256',
type: 'image/png',
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, 'Cannot register instruments with invalid icon size "256 256" (missing "x")');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: '/images/rg\0rg-256x256.png',
sizes: '256x256',
type: 'image/png',
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, 'Cannot register instruments with invalid icon URL (has a null character)');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src: 'http://test.example/images/rgrg-256x256.png',
sizes: '256x256',
type: 'image/png',
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, 'Cannot register instruments with non-existing non-https icon URL');
promise_test(async t => {
await registration.paymentManager.instruments.clear();
const setPromise = registration.paymentManager.instruments.set(
'instrument-key',
{
name: 'Instrument Name',
icons: [
{
src:
'http://www.chromium.org/_/rsrc/1438879449147/config/customLogo.gif',
sizes: '48x48',
type: 'image/gif',
},
],
method: methodName,
},
);
return promise_rejects_js(t, TypeError, setPromise);
}, 'Cannot register instruments with an existing non-https icon URL');
async function testUnusualStrings(existingKey, nonExistingKey) {
await registration.paymentManager.instruments.clear();
await registration.paymentManager.instruments.set(existingKey, {
name: existingKey,
icons: [
{src: '/images/rgrg-256x256.png', sizes: '256x256', type: 'image/png'},
],
method: existingKey,
capabilities: {aCapabilityName: existingKey},
});
const hasExistingInstrument = await registration.paymentManager.instruments.has(
existingKey,
);
assert_true(hasExistingInstrument);
const hasNonExistingInstrument = await registration.paymentManager.instruments.has(
nonExistingKey,
);
assert_false(hasNonExistingInstrument);
const existingInstrument = await registration.paymentManager.instruments.get(
existingKey,
);
assert_equals(existingInstrument.name, existingKey);
const nonExistingInstrument = await registration.paymentManager.instruments.get(
nonExistingKey,
);
assert_equals(nonExistingInstrument, undefined);
const deletedExistingInstrument = await registration.paymentManager.instruments.delete(
existingKey,
);
assert_true(deletedExistingInstrument);
const deletedNonExistingInstrument = await registration.paymentManager.instruments.delete(
nonExistingKey,
);
assert_false(deletedNonExistingInstrument);
}
promise_test(async t => {
const length = 100000;
await testUnusualStrings('0'.repeat(length), '1'.repeat(length));
}, "Don't crash on very long key, name, method, and capability strings.");
promise_test(async t => {
await testUnusualStrings('foo\0bar', 'foo\0baz');
}, "Don't crash on null characters in key, name, method, and capability strings.");
}
registerAndActiveServiceWorker('app-simple.js', 'payment-app/', runTests);
</script>

View file

@ -1,28 +0,0 @@
async function registerAndActiveServiceWorker(script, scope, callback) {
const registration = await navigator.serviceWorker.register(script, {scope});
const serviceWorker =
registration.installing || registration.waiting || registration.active;
if (serviceWorker) {
waitForServiceWorkerActivation(scope, callback);
return;
}
registration.addEventListener('updatefound', event => {
waitForServiceWorkerActivation(scope, callback);
});
}
async function waitForServiceWorkerActivation(scope, callback) {
const registration = await navigator.serviceWorker.getRegistration(scope);
if (registration.active) {
callback(registration);
return;
}
const serviceWorker = registration.installing || registration.waiting;
serviceWorker.addEventListener('statechange', event => {
if (event.target.state == 'activated') {
callback(registration);
}
});
}

View file

@ -13,7 +13,6 @@ promise_test(async t => {
await wait_for_state(t, registration.installing, 'activated'); await wait_for_state(t, registration.installing, 'activated');
assert_equals(registration.paymentManager, registration.paymentManager); assert_equals(registration.paymentManager, registration.paymentManager);
assert_equals(registration.paymentManager.instruments, registration.paymentManager.instruments);
}); });
</script> </script>

View file

@ -19,13 +19,19 @@ const delay = 2
const blank_page = `/resource-timing/resources/blank_page_green.htm`; const blank_page = `/resource-timing/resources/blank_page_green.htm`;
const destUrl = `/common/slow-redirect.py?delay=${delay}&location=${REMOTE_ORIGIN}/${blank_page}`; const destUrl = `/common/slow-redirect.py?delay=${delay}&location=${REMOTE_ORIGIN}/${blank_page}`;
const timeBefore = performance.now() const timeBefore = performance.now();
attribute_test(load.iframe, destUrl, entry => { (async () => {
// Wait 10 ms, to ensure the difference between startTime and timeBefore is
// larger than 1 ms, to avoid flakiness in browsers that clamp timestamps to
// 1 ms.
await new Promise(r => step_timeout(r, 10));
attribute_test(load.iframe, destUrl, entry => {
assert_equals(entry.startTime, entry.fetchStart, 'startTime and fetchStart should be equal'); assert_equals(entry.startTime, entry.fetchStart, 'startTime and fetchStart should be equal');
assert_greater_than(entry.startTime, timeBefore, 'startTime and fetchStart should be greater than the time before fetching'); assert_greater_than(entry.startTime, timeBefore, 'startTime and fetchStart should be greater than the time before fetching');
// See https://github.com/w3c/resource-timing/issues/264 // See https://github.com/w3c/resource-timing/issues/264
assert_less_than(Math.round(entry.startTime - timeBefore), delay * 1000, 'startTime should not expose redirect delays'); assert_less_than(Math.round(entry.startTime - timeBefore), delay * 1000, 'startTime should not expose redirect delays');
}, "Verify that cross-origin resources don't implicitly expose their redirect timings") }, "Verify that cross-origin resources don't implicitly expose their redirect timings")
})();
</script> </script>
</body> </body>

View file

@ -23,13 +23,19 @@ const load_null_object = async path => {
} }
const destUrl = `/common/slow-redirect.py?delay=${delay}&location=${REMOTE_ORIGIN}${not_found_page}`; const destUrl = `/common/slow-redirect.py?delay=${delay}&location=${REMOTE_ORIGIN}${not_found_page}`;
const timeBefore = performance.now() const timeBefore = performance.now();
attribute_test(load_null_object, destUrl, entry => { (async () => {
// Wait 10 ms, to ensure the difference between startTime and timeBefore is
// larger than 1 ms, to avoid flakiness in browsers that clamp timestamps to
// 1 ms.
await new Promise(r => step_timeout(r, 10));
attribute_test(load_null_object, destUrl, entry => {
assert_equals(entry.startTime, entry.fetchStart, 'startTime and fetchStart should be equal'); assert_equals(entry.startTime, entry.fetchStart, 'startTime and fetchStart should be equal');
assert_greater_than(entry.startTime, timeBefore, 'startTime and fetchStart should be greater than the time before fetching'); assert_greater_than(entry.startTime, timeBefore, 'startTime and fetchStart should be greater than the time before fetching');
// See https://github.com/w3c/resource-timing/issues/264 // See https://github.com/w3c/resource-timing/issues/264
assert_less_than(Math.round(entry.startTime - timeBefore), delay * 1000, 'startTime should not expose redirect delays'); assert_less_than(Math.round(entry.startTime - timeBefore), delay * 1000, 'startTime should not expose redirect delays');
}, "Verify that cross-origin object resources don't implicitly expose their redirect timings") }, "Verify that cross-origin object resources don't implicitly expose their redirect timings")
})();
</script> </script>
</body> </body>

View file

@ -1,3 +1,19 @@
const await_with_timeout = async (delay, message, promise, cleanup = ()=>{}) => {
let timeout_id;
const timeout = new Promise((_, reject) => {
timeout_id = step_timeout(() =>
reject(new DOMException(message, "TimeoutError")), delay)
});
let result = null;
try {
result = await Promise.race([promise, timeout]);
clearTimeout(timeout_id);
} finally {
cleanup();
}
return result;
};
// Asserts that the given attributes are present in 'entry' and hold equal // Asserts that the given attributes are present in 'entry' and hold equal
// values. // values.
const assert_all_equal_ = (entry, attributes) => { const assert_all_equal_ = (entry, attributes) => {
@ -451,12 +467,10 @@ const attribute_test_internal = (loader, path, validator, run_test, test_label)
}); });
await loader(path, validator); await loader(path, validator);
const timeout = new Promise(r => step_timeout(() => { const entry = await await_with_timeout(2000,
console.log("Timeout was reached before entry fired"); "Timeout was reached before entry fired",
r(null); loaded_entry);
}, 2000)); assert_not_equals(entry, null, 'No entry was received');
const entry = await Promise.race([loaded_entry, timeout]);
assert_not_equals(entry, null, 'No entry was recieved');
run_test(entry); run_test(entry);
}, test_label); }, test_label);
}; };

View file

@ -135,7 +135,7 @@ const load = {
// object. // object.
object: async (path, type) => { object: async (path, type) => {
const object = document.createElement("object"); const object = document.createElement("object");
const loaded = new Promise(resolve => { const object_load_settled = new Promise(resolve => {
object.onload = object.onerror = resolve; object.onload = object.onerror = resolve;
}); });
object.data = load.cache_bust(path); object.data = load.cache_bust(path);
@ -143,12 +143,11 @@ const load = {
object.type = type; object.type = type;
} }
document.body.appendChild(object); document.body.appendChild(object);
const timeout = new Promise(r => step_timeout(() => { await await_with_timeout(2000,
console.log("Timeout was reached before load or error events fired"); "Timeout was reached before load or error events fired",
r(); object_load_settled,
}, 2000)); () => { document.body.removeChild(object) }
await Promise.race([loaded, timeout]); );
document.body.removeChild(object);
}, },
// Returns a promise that settles once the given path has been fetched // Returns a promise that settles once the given path has been fetched

View file

@ -24,6 +24,10 @@ const load_image_object = async path => {
return load.object(path, "image/png"); return load.object(path, "image/png");
} }
const load_frame_object = async path => {
return load.object(path, "text/html");
}
const load_null_object = async path => { const load_null_object = async path => {
return load.object(path, null); return load.object(path, null);
} }
@ -38,6 +42,7 @@ for(const loader of [
load.xhr_async, load.xhr_async,
load.iframe, load.iframe,
load_image_object, load_image_object,
load_frame_object,
load_null_object load_null_object
]) { ]) {
for(const status of status_codes) { for(const status of status_codes) {
@ -88,6 +93,7 @@ for(const loader of [
load.stylesheet, load.stylesheet,
load.iframe, load.iframe,
load_image_object, load_image_object,
load_frame_object,
load_null_object load_null_object
]) { ]) {
for(const tao of [false, true]) { for(const tao of [false, true]) {
@ -113,6 +119,7 @@ for(const loader of [
// Same-Origin => Cross-Origin => Same-Origin => Same-Origin redirect chain // Same-Origin => Cross-Origin => Same-Origin => Same-Origin redirect chain
for(const loader of [ for(const loader of [
load.iframe, load.iframe,
load_frame_object,
load_null_object load_null_object
]) { ]) {
for(const status of status_codes) { for(const status of status_codes) {
@ -136,6 +143,7 @@ for(const loader of [
// Response status for iframes is exposed for same origin redirects // Response status for iframes is exposed for same origin redirects
for(const loader of [ for(const loader of [
load.iframe, load.iframe,
load_frame_object,
load_null_object load_null_object
]) { ]) {
for(const status of status_codes) { for(const status of status_codes) {

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
test(() => {
const host = document.createElement('div');
document.body.appendChild(host);
const shadowRoot = host.attachShadow({mode: 'open', delegatesFocus: true});
const shadowInput = document.createElement('input');
shadowRoot.appendChild(shadowInput);
host.focus();
assert_equals(document.activeElement, host, 'The shadow host should be focused.');
host.setAttribute('tabindex', '0');
assert_equals(document.activeElement, host, 'The shadow host should remain focused after changing tabindex.');
}, 'Setting tabindex on the shadow host of a focused element with delegatesFocus should not change focus.');
</script>

View file

@ -7,6 +7,7 @@ import pytest
from tools.wpt import wpt from tools.wpt import wpt
from tools.wptrunner.wptrunner import manifestexpected from tools.wptrunner.wptrunner import manifestexpected
from tools.wptrunner.wptrunner.manifestupdate import get_test_name
from localpaths import repo_root from localpaths import repo_root
@pytest.fixture @pytest.fixture
@ -118,11 +119,11 @@ def test_update(tmp_path, metadata_file):
run_info_firefox) run_info_firefox)
# Default expected isn't stored # Default expected isn't stored
with pytest.raises(KeyError): with pytest.raises(KeyError):
assert firefox_expected.get_test(test_id.rpartition('/')[-1]).get("expected") assert firefox_expected.get_test(get_test_name(test_id)).get("expected")
assert firefox_expected.get_test(test_id.rpartition('/')[-1]).get_subtest(subtest_name).expected == "FAIL" assert firefox_expected.get_test(get_test_name(test_id)).get_subtest(subtest_name).expected == "FAIL"
chrome_expected = manifestexpected.get_manifest(metadata_path, chrome_expected = manifestexpected.get_manifest(metadata_path,
test_path, test_path,
run_info_chrome) run_info_chrome)
assert chrome_expected.get_test(test_id.rpartition('/')[-1]).expected == "ERROR" assert chrome_expected.get_test(get_test_name(test_id)).expected == "ERROR"
assert chrome_expected.get_test(test_id.rpartition('/')[-1]).get_subtest(subtest_name).expected == "NOTRUN" assert chrome_expected.get_test(get_test_name(test_id)).get_subtest(subtest_name).expected == "NOTRUN"

View file

@ -60,6 +60,10 @@ def data_cls_getter(output_node, visited_node):
else: else:
raise ValueError raise ValueError
def get_test_name(test_id):
# test name is base name of test path + query string + frament
return test_id[len(urlsplit(test_id).path.rsplit("/", 1)[0]) + 1:]
class UpdateProperties: class UpdateProperties:
def __init__(self, manifest, **kwargs): def __init__(self, manifest, **kwargs):
@ -218,7 +222,7 @@ class TestNode(ManifestItem):
:param test_type: The type of the test :param test_type: The type of the test
:param test_id: The id of the test""" :param test_id: The id of the test"""
name = test_id[len(urlsplit(test_id).path.rsplit("/", 1)[0]) + 1:] name = get_test_name(test_id)
node = DataNode(name) node = DataNode(name)
self = cls(node) self = cls(node)

View file

@ -11,6 +11,7 @@ from collections import defaultdict, deque, namedtuple
from . import manifestinclude from . import manifestinclude
from . import manifestexpected from . import manifestexpected
from . import manifestupdate
from . import mpcontext from . import mpcontext
from . import wpttest from . import wpttest
from mozlog import structured from mozlog import structured
@ -267,7 +268,7 @@ class TestLoader:
def get_test(self, manifest_file, manifest_test, inherit_metadata, test_metadata): def get_test(self, manifest_file, manifest_test, inherit_metadata, test_metadata):
if test_metadata is not None: if test_metadata is not None:
inherit_metadata.append(test_metadata) inherit_metadata.append(test_metadata)
test_metadata = test_metadata.get_test(manifest_test.id.rpartition('/')[-1]) test_metadata = test_metadata.get_test(manifestupdate.get_test_name(manifest_test.id))
return wpttest.from_manifest(manifest_file, manifest_test, inherit_metadata, test_metadata) return wpttest.from_manifest(manifest_file, manifest_test, inherit_metadata, test_metadata)

View file

@ -7,7 +7,7 @@ from manifest import manifest as wptmanifest
from manifest.item import TestharnessTest, RefTest from manifest.item import TestharnessTest, RefTest
from manifest.utils import to_os_path from manifest.utils import to_os_path
from . test_update import tree_and_sourcefile_mocks from . test_update import tree_and_sourcefile_mocks
from .. import manifestexpected, wpttest from .. import manifestexpected, manifestupdate, wpttest
dir_ini_0 = b"""\ dir_ini_0 = b"""\
@ -111,7 +111,8 @@ def make_test_object(test_name,
test_path=test_path) test_path=test_path)
test = next(iter(tests[index][2])) if iterate else tests[index][2].pop() test = next(iter(tests[index][2])) if iterate else tests[index][2].pop()
return wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id.rpartition('/')[-1])) return wpttest.from_manifest(tests, test, inherit_metadata,
test_metadata.get_test(manifestupdate.get_test_name(test.id)))
def test_run_info(): def test_run_info():
@ -224,7 +225,8 @@ def test_metadata_fuzzy():
test_path="a/fuzzy.html") test_path="a/fuzzy.html")
test = next(manifest.iterpath(to_os_path("a/fuzzy.html"))) test = next(manifest.iterpath(to_os_path("a/fuzzy.html")))
test_obj = wpttest.from_manifest(manifest, test, [], test_metadata.get_test(test.id.rpartition('/')[-1])) test_obj = wpttest.from_manifest(manifest, test, [],
test_metadata.get_test(manifestupdate.get_test_name(test.id)))
assert test_obj.fuzzy == {('/a/fuzzy.html', '/a/fuzzy-ref.html', '=='): [[2, 3], [10, 15]]} assert test_obj.fuzzy == {('/a/fuzzy.html', '/a/fuzzy-ref.html', '=='): [[2, 3], [10, 15]]}
assert test_obj.fuzzy_override == {'/a/fuzzy-ref.html': ((1, 1), (200, 200))} assert test_obj.fuzzy_override == {'/a/fuzzy-ref.html': ((1, 1), (200, 200))}

View file

@ -131,7 +131,7 @@ standardSetup(async function(authenticator) {
first: new Uint8Array([1,2,3,4]).buffer, first: new Uint8Array([1,2,3,4]).buffer,
}; };
return promise_rejects_dom( return promise_rejects_dom(
t, "NotSupportedError", assert(id, {evalByCredential: byCred })); t, "SyntaxError", assert(id, {evalByCredential: byCred }));
}, "navigator.credentials.get() using invalid base64url credential ID"); }, "navigator.credentials.get() using invalid base64url credential ID");
promise_test(async t => { promise_test(async t => {