Auto merge of #29300 - servo:wpt_update_26-01-2023, r=jdm

Sync WPT with upstream (26-01-2023)

Automated downstream sync of changes from upstream as of 26-01-2023
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2023-01-26 17:14:46 +01:00 committed by GitHub
commit 9dfae50c5e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
98 changed files with 2782 additions and 1163 deletions

View file

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

View file

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

View file

@ -1,6 +1,3 @@
[block-in-inline-hittest-002.html]
[elementsFromPoint]
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']
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]
expected: FAIL
[margin-right length(cm) / values]
[background-color color(rgba) / values]
expected: FAIL
[margin-right length(in) / values]
[border-top-width length(pt) / values]
expected: FAIL
[margin-top length(pt) / values]
[border-top-width length(pc) / values]
expected: FAIL
[margin-top length(pc) / values]
[border-top-width length(px) / values]
expected: FAIL
[margin-top length(px) / values]
[border-top-width length(em) / values]
expected: FAIL
[margin-top length(em) / values]
[border-top-width length(ex) / values]
expected: FAIL
[margin-top length(ex) / values]
[border-top-width length(mm) / values]
expected: FAIL
[margin-top length(mm) / values]
[border-top-width length(cm) / values]
expected: FAIL
[margin-top length(cm) / values]
[border-top-width length(in) / values]
expected: FAIL
[margin-top length(in) / values]
[border-right-width length(pt) / values]
expected: FAIL
[height length(pt) / values]
[border-right-width length(pc) / values]
expected: FAIL
[height length(pc) / values]
[border-right-width length(px) / values]
expected: FAIL
[height length(px) / values]
[border-right-width length(em) / values]
expected: FAIL
[height length(em) / values]
[border-right-width length(ex) / values]
expected: FAIL
[height length(ex) / values]
[border-right-width length(mm) / values]
expected: FAIL
[height length(mm) / values]
[border-right-width length(cm) / values]
expected: FAIL
[height length(cm) / values]
[border-right-width length(in) / values]
expected: FAIL
[height length(in) / values]
[border-bottom-width length(pt) / values]
expected: FAIL
[height percentage(%) / values]
[border-bottom-width length(pc) / values]
expected: FAIL
[width length(pt) / values]
[border-bottom-width length(px) / values]
expected: FAIL
[width length(pc) / values]
[border-bottom-width length(em) / values]
expected: FAIL
[width length(px) / values]
[border-bottom-width length(ex) / values]
expected: FAIL
[width length(em) / values]
[border-bottom-width length(mm) / values]
expected: FAIL
[width length(ex) / values]
[border-bottom-width length(cm) / values]
expected: FAIL
[width length(mm) / values]
[border-bottom-width length(in) / values]
expected: FAIL
[width length(cm) / values]
[border-left-width length(pt) / values]
expected: FAIL
[width length(in) / values]
[border-left-width length(pc) / values]
expected: FAIL
[width percentage(%) / values]
[border-left-width length(px) / values]
expected: FAIL
[min-height length(pt) / values]
[border-left-width length(em) / values]
expected: FAIL
[min-height length(pc) / values]
[border-left-width length(ex) / values]
expected: FAIL
[min-height length(px) / values]
[border-left-width length(mm) / values]
expected: FAIL
[min-height length(em) / values]
[border-left-width length(cm) / values]
expected: FAIL
[min-height length(ex) / values]
[border-left-width length(in) / values]
expected: FAIL
[min-height length(mm) / values]
[border-top-color color(rgba) / values]
expected: FAIL
[min-height length(cm) / values]
[border-right-color color(rgba) / values]
expected: FAIL
[min-height length(in) / values]
[border-bottom-color color(rgba) / values]
expected: FAIL
[min-height percentage(%) / values]
[border-left-color color(rgba) / values]
expected: FAIL
[min-width length(pt) / values]
[padding-bottom length(pt) / values]
expected: FAIL
[min-width length(pc) / values]
[padding-bottom length(pc) / values]
expected: FAIL
[min-width length(px) / values]
[padding-bottom length(px) / values]
expected: FAIL
[min-width length(em) / values]
[padding-bottom length(em) / values]
expected: FAIL
[min-width length(ex) / values]
[padding-bottom length(ex) / values]
expected: FAIL
[min-width length(mm) / values]
[padding-bottom length(mm) / values]
expected: FAIL
[min-width length(cm) / values]
[padding-bottom length(cm) / values]
expected: FAIL
[min-width length(in) / values]
[padding-bottom length(in) / values]
expected: FAIL
[min-width percentage(%) / values]
[padding-left length(pt) / values]
expected: FAIL
[max-height length(pt) / values]
[padding-left length(pc) / values]
expected: FAIL
[max-height length(pc) / values]
[padding-left length(px) / values]
expected: FAIL
[max-height length(px) / values]
[padding-left length(em) / values]
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

View file

@ -55,3 +55,726 @@
[background-position length(px) / events]
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]
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]
[listeners are called in order they were added, ignoring capture parameter]
expected: FAIL
[listener added with addListener and addEventListener (capture) is called twice]
expected: FAIL

View file

@ -13,3 +13,9 @@
[<li>Outside 3</li>]
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]
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]
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.]
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]
expected: FAIL
[background-image sec-fetch-site - HTTPS downgrade (header not sent)]
expected: TIMEOUT
[border-image sec-fetch-site - HTTPS downgrade (header not sent)]
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]
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]
expected: TIMEOUT
[Navigating to a different document with window.open]
expected: FAIL
[Navigating to a different document with form submission]
expected: FAIL
expected: TIMEOUT
[Navigating to a different document with link click]
expected: FAIL

View file

@ -1,10 +1,6 @@
[javascript-url-referrer.window.html]
expected: TIMEOUT
[unsafe-url referrer policy used to create the starting page]
expected: FAIL
[origin referrer policy used to create the starting page]
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]
expected: TIMEOUT
expected: FAIL

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,9 +11,6 @@
[text/plain: 0x00 in name (normal form)]
expected: FAIL
[text/plain: 0x00 in name (formdata event)]
expected: FAIL
[text/plain: 0x00 in value (normal form)]
expected: FAIL
@ -167,9 +164,6 @@
[text/plain: character not in encoding in filename (formdata event)]
expected: FAIL
[text/plain: Basic test (formdata event)]
expected: FAIL
[text/plain: 0x00 in filename (formdata event)]
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]
expected: TIMEOUT
[Fulfillment handler on fulfilled promise]
expected: FAIL
[Rejection handler on pending-then-rejected promise]
expected: TIMEOUT
expected: FAIL
[Thenable resolution]
expected: FAIL
@ -13,4 +12,4 @@
expected: FAIL
[Fulfillment handler on pending-then-fulfilled promise]
expected: TIMEOUT
expected: FAIL

View file

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

View file

@ -7,13 +7,13 @@
expected: FAIL
[content-type 2 : text/html,text/plain]
expected: TIMEOUT
expected: FAIL
[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]
expected: NOTRUN
expected: TIMEOUT
[content-type 5 : text/plain;charset=gbk,text/plain]
expected: NOTRUN

View file

@ -1,5 +1,4 @@
[nextHopProtocol-is-tao-protected.https.html]
expected: TIMEOUT
[Add TAO-less iframe from remote origin. Make sure nextHopProtocol is the empty string]
expected: TIMEOUT
@ -25,28 +24,16 @@
expected: FAIL
[Fetch TAO'd object from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: TIMEOUT
[Fetch TAO-less script from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
expected: FAIL
[Fetch TAO'd script from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN
[Fetch TAO-less stylesheet from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
expected: FAIL
[Fetch TAO'd stylesheet from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN
[Fetch TAO-less synchronous xhr from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
expected: FAIL
[Fetch TAO'd synchronous xhr from remote origin. Make sure nextHopProtocol is not the empty string.]
expected: NOTRUN
[Fetch TAO-less asynchronous xhr from remote origin. Make sure nextHopProtocol is the empty string.]
expected: NOTRUN
expected: FAIL
[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]
expected: TIMEOUT
[Test that an navigation object with a 200 response displays an entry]
expected: FAIL
@ -16,4 +15,4 @@
expected: FAIL
[Verify that a 404 img-typed object emits an entry.]
expected: TIMEOUT
expected: FAIL

View file

@ -238,37 +238,37 @@
expected: FAIL
[This test validates the response status of resources. 79]
expected: TIMEOUT
expected: FAIL
[This test validates the response status of resources. 80]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 81]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 82]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 83]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 84]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 85]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 86]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 87]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 88]
expected: NOTRUN
expected: FAIL
[This test validates the response status of resources. 89]
expected: NOTRUN
expected: TIMEOUT
[This test validates the response status of resources. 90]
expected: NOTRUN
@ -899,3 +899,153 @@
[This test validates the response status of resources. 299]
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]
expected: TIMEOUT
[frame in navigated remote-site frame]
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, .bar {\n & + .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}`,
`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('<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
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>
</p>
<p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p>
</div>
<div class="wrapper">
@ -59,7 +59,7 @@
<span>サンプルサンプル文<span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p>
<p class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p>
</div>
</body>

View file

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

View file

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

View file

@ -41,19 +41,19 @@
<div class="wrapper">
<!-- inseparable characters TWO DOT LEADER -->
<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 class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
<span>サンプルサンプル<br /><span class="target">&#x2025;&#x2025;</span>サンプル文</span>
</p>
</div>
<div class="wrapper">
<!-- inseparable characters HORIZONTAL ELLIPSIS -->
<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 class="control" lang="ja">
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
<span>サンプルサンプル<br /><span class="target">&#x2026;&#x2026;</span>サンプル文</span>
</p>
</div>
</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>
<html class=reftest-wait>
<html class="reftest-wait foo">
<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="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script>
<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) {
background-color: blue;
}

View file

@ -1,5 +1,5 @@
<!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>
<link rel="help" href="https://github.com/WICG/view-transitions">
<link rel="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script>
<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 {
background-color: red;
}

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html class=reftest-wait>
<html class="reftest-wait foo">
<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="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script>
<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) {
background-color: blue;
}

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html class=reftest-wait>
<html class="reftest-wait foo">
<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="author" href="mailto:khushalsagar@chromium.org">
@ -8,6 +8,22 @@
<script src="/resources/testharnessreport.js"></script>
<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) {
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>';
assert_array_equals(container.querySelector('my-control').disabledHistory(), [true]);
}, '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>
</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 gentestutilsunion import genTestUtils_union
genTestUtils('../element', '../element', 'templates.yaml', 'name2dir-canvas.yaml', False)
genTestUtils('../offscreen', '../offscreen', 'templates.yaml', 'name2dir-offscreen.yaml', True)
genTestUtils_union('templates-new.yaml', 'name2dir.yaml')
genTestUtils('../element', '../element', 'templates.yaml',
'name2dir-canvas.yaml', False)
genTestUtils('../offscreen', '../offscreen', 'templates.yaml',
'name2dir-offscreen.yaml', True)
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
# https://github.com/web-platform-tests/wpt/
#
# The original version had a number of now-removed features (multiple versions of
# each test case of varying verbosity, Mozilla mochitests, semi-automated test
# harness). It also had a different directory structure.
# The original version had a number of now-removed features (multiple versions
# of each test case of varying verbosity, Mozilla mochitests, semi-automated
# test harness). It also had a different directory structure.
# To update or add test cases:
#
# * Modify the tests*.yaml files.
# 'name' is an arbitrary hierarchical name to help categorise tests.
# '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 '@'
# 'expected' is what the final canvas output should be: a string 'green' or '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.
# - 'name' is an arbitrary hierarchical name to help categorise tests.
# - '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 '@'
# - 'expected' is what the final canvas output should be: a string 'green' or
# '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".
# 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.
from __future__ import print_function
from typing import List, Optional
import re
import codecs
import time
import importlib
import os
import shutil
import sys
import xml.dom.minidom
from xml.dom.minidom import Node
try:
import cairocffi as cairo
import cairocffi as cairo # type: ignore
except ImportError:
import cairo
try:
import syck as yaml # compatible and lots faster
# Compatible and lots faster.
import syck as yaml # type: ignore
except ImportError:
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'
def simpleEscapeJS(str):
return str.replace('\\', '\\\\').replace('"', '\\"')
def simpleEscapeJS(string: str) -> str:
return string.replace('\\', '\\\\').replace('"', '\\"')
def escapeJS(str):
str = simpleEscapeJS(str)
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output
return str
def escapeJS(string: str) -> str:
string = simpleEscapeJS(string)
# Kind of an ugly hack, for nicer failure-message output.
string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
return string
def escapeHTML(str):
return str.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
def expand_nonfinite(method, argstr, tail):
def expand_nonfinite(method: str, argstr: str, tail: str) -> str:
"""
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
f(a, 0);
@ -80,14 +87,18 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
f(0, b, d);
"""
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
# 'invalid' is Infinity/-Infinity/NaN)
# 'invalid' is Infinity/-Infinity/NaN).
args = []
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(' '))
calls = []
# Start with the valid argument list
call = [ args[j][0] for j in range(len(args)) ]
# Start with the valid argument list.
call = [args[j][0] for j in range(len(args))]
# For each argument alone, try setting it to all its invalid values:
for i in range(len(args)):
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
# first invalid values. (Don't do all invalid values, because the
# 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)):
if len(args[i]) > 1:
a = args[i][1]
c2 = c[:]
c2[i] = a
if depth > 0: calls.append(c2)
f(c2, i+1, depth+1)
if depth > 0:
calls.append(c2)
f(c2, i + 1, depth + 1)
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
if len(sys.argv) > 1 and sys.argv[1] == '--test':
import doctest
doctest = importlib.import_module('doctest')
doctest.testmod()
sys.exit()
templates = yaml.safe_load(open(TEMPLATEFILE, "r").read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, "r").read())
templates = yaml.safe_load(open(TEMPLATEFILE, 'r').read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, 'r').read())
tests = []
test_yaml_directory = "yaml/element"
test_yaml_directory = 'yaml/element'
if ISOFFSCREENCANVAS:
test_yaml_directory = "yaml/offscreen"
test_yaml_directory = 'yaml/offscreen'
TESTSFILES = [
os.path.join(test_yaml_directory, f) 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], []):
os.path.join(test_yaml_directory, f)
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],
[]):
if 'DISABLED' in t:
continue
if 'meta' in t:
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests})
eval(compile(t['meta'], '<meta test>', 'exec'), {},
{'tests': tests})
else:
tests.append(t)
@ -137,98 +154,85 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
category_contents_direct = {}
category_contents_all = {}
def backref_html(name):
def backref_html(name: str) -> str:
backrefs = []
c = ''
for p in name.split('.')[:-1]:
c += '.'+p
c += '.' + p
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
backrefs.append(name.split('.')[-1])
return ''.join(backrefs)
def make_flat_image(filename, w, h, r,g,b,a):
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
# Ensure the test output directories exist.
testdirs = [TESTOUTPUTDIR, IMAGEOUTPUTDIR, MISCOUTPUTDIR]
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:
try: os.mkdir(d)
except: pass # ignore if it already exists
try:
os.mkdir(d)
except FileExistsError:
pass # Ignore if it already exists.
used_images = {}
def map_name(name):
def map_name(name: str) -> Optional[str]:
mapped_name = None
for mn in sorted(name_mapping.keys(), key=len, reverse=True):
if name.startswith(mn):
mapped_name = "%s/%s" % (name_mapping[mn], name)
mapped_name = '%s/%s' % (name_mapping[mn], name)
break
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:
mapped_name += "-manual"
mapped_name += '-manual'
return mapped_name
def expand_test_code(code):
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws'
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'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
r'_assertPixel(canvas, \1, \2);',
code)
r'_assertPixel(canvas, \1, \2);', code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
r'_assertPixelApprox(canvas, \1, \2, 2);',
code)
r'_assertPixelApprox(canvas, \1, \2, 2);', code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
r'_assertPixelApprox(canvas, \1, \2, \3);',
code)
code = re.sub(
r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
r'_assertPixelApprox(canvas, \1, \2, \3);', code)
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
r'assert_throws_dom("\1", function() { \2; });',
code)
r'assert_throws_dom("\1", function() { \2; });', code)
code = re.sub(r'@assert throws (\S+Error) (.*);',
r'assert_throws_js(\1, function() { \2; });',
code)
r'assert_throws_js(\1, function() { \2; });', code)
code = re.sub(r'@assert (.*) === (.*);',
lambda m: '_assertSame(%s, %s, "%s", "%s");'
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
, code)
code = re.sub(
r'@assert (.*) === (.*);', lambda m:
'_assertSame(%s, %s, "%s", "%s");' % (m.group(1), m.group(
2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) !== (.*);',
lambda m: '_assertDifferent(%s, %s, "%s", "%s");'
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
, code)
code = re.sub(
r'@assert (.*) !== (.*);', lambda m:
'_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) =~ (.*);',
lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2))
, code)
code = re.sub(
r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2)), code)
code = re.sub(r'@assert (.*);',
lambda m: '_assert(%s, "%s");'
% (m.group(1), escapeJS(m.group(1)))
, code)
code = re.sub(
r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
1), escapeJS(m.group(1))), code)
code = re.sub(r' @moz-todo', '', code)
code = re.sub(r'@moz-UniversalBrowserRead;',
""
, code)
code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
assert('@' not in code)
assert ('@' not in code)
return code
@ -237,29 +241,29 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
test = tests[i]
name = test['name']
print("\r(%s)" % name, " "*32, "\t")
print('\r(%s)' % name, ' ' * 32, '\t')
if name in used_tests:
print("Test %s is defined twice" % name)
print('Test %s is defined twice' % name)
used_tests[name] = 1
mapped_name = map_name(name)
if not mapped_name:
if ISOFFSCREENCANVAS:
continue
else:
mapped_name = name
mapped_name = name
cat_total = ''
for cat_part in [''] + name.split('.')[:-1]:
cat_total += cat_part+'.'
if not cat_total in category_names: category_names.append(cat_total)
cat_total += cat_part + '.'
if not cat_total in category_names:
category_names.append(cat_total)
category_contents_all.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']):
print("Probable incorrect pixel test in %s" % name)
if test.get('expected', '') == 'green' and re.search(
r'@assert pixel .* 0,0,0,0;', test['code']):
print('Probable incorrect pixel test in %s' % name)
code = expand_test_code(test['code'])
@ -268,74 +272,86 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
expected = test['expected']
expected_img = None
if expected == 'green':
expected_img = "/images/green-100x50.png"
expected_img = '/images/green-100x50.png'
elif expected == 'clear':
expected_img = "/images/clear-100x50.png"
expected_img = '/images/clear-100x50.png'
else:
if ';' in expected:
print("Found semicolon in %s" % name)
expected = re.sub(r'^size (\d+) (\d+)',
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)',
expected)
print('Found semicolon in %s' % name)
expected = re.sub(
r'^size (\d+) (\d+)',
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
r'\ncr = cairo.Context(surface)', expected)
if mapped_name.endswith("-manual"):
png_name = mapped_name[:-len("-manual")]
if mapped_name.endswith('-manual'):
png_name = mapped_name[:-len('-manual')]
else:
png_name = mapped_name
expected += "\nsurface.write_to_png('%s/%s.png')\n" % (IMAGEOUTPUTDIR, png_name)
eval(compile(expected, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo})
expected_img = "%s.png" % name
expected += "\nsurface.write_to_png('%s/%s.png')\n" % (
IMAGEOUTPUTDIR, png_name)
eval(compile(expected, '<test %s>' % test['name'], 'exec'), {},
{'cairo': cairo})
expected_img = '%s.png' % name
if expected_img:
expectation_html = ('<p class="output expectedtext">Expected output:' +
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img))
expectation_html = (
'<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"')
prev = tests[i-1]['name'] if i != 0 else 'index'
next = tests[i+1]['name'] if i != len(tests)-1 else 'index'
prev_test = tests[i - 1]['name'] if i != 0 else 'index'
next_test = tests[i + 1]['name'] if i != len(tests) - 1 else 'index'
name_wrapped = name.replace('.', '.&#8203;')
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 = ''
for s in test.get('scripts', []):
scripts += '<script src="%s"></script>\n' % (s)
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:
script_variants = [('', '')]
images = ''
for i in test.get('images', []):
id = i.split('/')[-1]
if '/' not in i:
used_images[i] = 1
i = '../images/%s' % i
images += '<img src="%s" id="%s" class="resource">\n' % (i,id)
for i in test.get('svgimages', []):
id = i.split('/')[-1]
if '/' not in i:
used_images[i] = 1
i = '../images/%s' % i
images += '<svg><image xlink:href="%s" id="%s" class="resource"></svg>\n' % (i,id)
images = images.replace("../images/", "/images/")
for src in test.get('images', []):
img_id = src.split('/')[-1]
if '/' not in src:
used_images[src] = 1
src = '../images/%s' % src
images += '<img src="%s" id="%s" class="resource">\n' % (src,
img_id)
for src in test.get('svgimages', []):
img_id = src.split('/')[-1]
if '/' not in src:
used_images[src] = 1
src = '../images/%s' % src
images += ('<svg><image xlink:href="%s" id="%s" class="resource">'
'</svg>\n' % (src, img_id))
images = images.replace('../images/', '/images/')
fonts = ''
fonthack = ''
for i in test.get('fonts', []):
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i)
# Browsers require the font to actually be used in the page
for font in test.get('fonts', []):
fonts += ('@font-face {\n font-family: %s;\n'
' 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):
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:
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', '')
escaped_desc = simpleEscapeJS(desc)
@ -351,26 +367,43 @@ def genTestUtils(TESTOUTPUTDIR, IMAGEOUTPUTDIR, TEMPLATEFILE, NAME2DIRFILE, ISOF
name_variant = '' if not variant else '.' + variant
template_params = {
'name':name + name_variant,
'name_wrapped':name_wrapped, 'backrefs':backref_html(name),
'mapped_name':mapped_name,
'desc':desc, 'escaped_desc':escaped_desc,
'prev':prev, 'next':next, '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,
'name': name + name_variant,
'name_wrapped': name_wrapped,
'backrefs': backref_html(name),
'mapped_name': mapped_name,
'desc': desc,
'escaped_desc': escaped_desc,
'prev': prev_test,
'next': next_test,
'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
}
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)
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
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)
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)
print()

View file

@ -6,19 +6,20 @@
# It has been adapted for use with the Web Platform Test Suite suite at
# https://github.com/web-platform-tests/wpt/
#
# The original version had a number of now-removed features (multiple versions of
# each test case of varying verbosity, Mozilla mochitests, semi-automated test
# harness). It also had a different directory structure.
# The original version had a number of now-removed features (multiple versions
# of each test case of varying verbosity, Mozilla mochitests, semi-automated
# test harness). It also had a different directory structure.
# To update or add test cases:
#
# * Modify the tests*.yaml files.
# 'name' is an arbitrary hierarchical name to help categorise tests.
# '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 '@'
# 'expected' is what the final canvas output should be: a string 'green' or '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.
# - 'name' is an arbitrary hierarchical name to help categorise tests.
# - '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 '@'.
# - 'expected' is what the final canvas output should be: a string 'green' or
# '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".
# 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.
from __future__ import print_function
from typing import List
import re
import codecs
import time
import importlib
import os
import shutil
import sys
import xml.dom.minidom
from xml.dom.minidom import Node
try:
import cairocffi as cairo
import cairocffi as cairo # type: ignore
except ImportError:
import cairo
try:
import syck as yaml # compatible and lots faster
# Compatible and lots faster.
import syck as yaml # type: ignore
except ImportError:
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'
CANVASIMAGEOUTPUTDIR = '../element'
OFFSCREENCANVASOUTPUTDIR = '../offscreen'
OFFSCREENCANVASIMAGEOUTPUTDIR = '../offscreen'
MISCOUTPUTDIR = './output'
def simpleEscapeJS(str):
return str.replace('\\', '\\\\').replace('"', '\\"')
def simpleEscapeJS(string: str) -> str:
return string.replace('\\', '\\\\').replace('"', '\\"')
def escapeJS(str):
str = simpleEscapeJS(str)
str = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', str) # kind of an ugly hack, for nicer failure-message output
return str
def escapeJS(string: str) -> str:
string = simpleEscapeJS(string)
# Kind of an ugly hack, for nicer failure-message output.
string = re.sub(r'\[(\w+)\]', r'[\\""+(\1)+"\\"]', string)
return string
def escapeHTML(str):
return str.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;')
def expand_nonfinite(method, argstr, tail):
def expand_nonfinite(method: str, argstr: str, tail: str) -> str:
"""
>>> print expand_nonfinite('f', '<0 a>, <0 b>', ';')
f(a, 0);
@ -83,14 +89,18 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
f(0, b, d);
"""
# argstr is "<valid-1 invalid1-1 invalid2-1 ...>, ..." (where usually
# 'invalid' is Infinity/-Infinity/NaN)
# 'invalid' is Infinity/-Infinity/NaN).
args = []
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(' '))
calls = []
# Start with the valid argument list
call = [ args[j][0] for j in range(len(args)) ]
# Start with the valid argument list.
call = [args[j][0] for j in range(len(args))]
# For each argument alone, try setting it to all its invalid values:
for i in range(len(args)):
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
# first invalid values. (Don't do all invalid values, because the
# 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)):
if len(args[i]) > 1:
a = args[i][1]
c2 = c[:]
c2[i] = a
if depth > 0: calls.append(c2)
f(c2, i+1, depth+1)
if depth > 0:
calls.append(c2)
f(c2, i + 1, depth + 1)
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':
import doctest
doctest = importlib.import_module('doctest')
doctest.testmod()
sys.exit()
templates = yaml.safe_load(open(TEMPLATEFILE, "r").read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, "r").read())
templates = yaml.safe_load(open(TEMPLATEFILE, 'r').read())
name_mapping = yaml.safe_load(open(NAME2DIRFILE, 'r').read())
tests = []
test_yaml_directory = "yaml-new"
test_yaml_directory = 'yaml-new'
TESTSFILES = [
os.path.join(test_yaml_directory, f) 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], []):
os.path.join(test_yaml_directory, f)
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],
[]):
if 'DISABLED' in t:
continue
if 'meta' in t:
eval(compile(t['meta'], '<meta test>', 'exec'), {}, {'tests':tests})
eval(compile(t['meta'], '<meta test>', 'exec'), {},
{'tests': tests})
else:
tests.append(t)
@ -138,88 +154,89 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
category_contents_direct = {}
category_contents_all = {}
def backref_html(name):
def backref_html(name: str) -> str:
backrefs = []
c = ''
for p in name.split('.')[:-1]:
c += '.'+p
c += '.' + p
backrefs.append('<a href="index%s.html">%s</a>.' % (c, p))
backrefs.append(name.split('.')[-1])
return ''.join(backrefs)
# Ensure the test output directories exist
testdirs = [CANVASOUTPUTDIR, OFFSCREENCANVASOUTPUTDIR, CANVASIMAGEOUTPUTDIR, OFFSCREENCANVASIMAGEOUTPUTDIR, MISCOUTPUTDIR]
# Ensure the test output directories exist.
testdirs = [
CANVASOUTPUTDIR, OFFSCREENCANVASOUTPUTDIR, CANVASIMAGEOUTPUTDIR,
OFFSCREENCANVASIMAGEOUTPUTDIR, MISCOUTPUTDIR
]
for map_dir in set(name_mapping.values()):
testdirs.append("%s/%s" % (CANVASOUTPUTDIR, map_dir))
testdirs.append("%s/%s" % (OFFSCREENCANVASOUTPUTDIR, map_dir))
testdirs.append('%s/%s' % (CANVASOUTPUTDIR, map_dir))
testdirs.append('%s/%s' % (OFFSCREENCANVASOUTPUTDIR, map_dir))
for d in testdirs:
try: os.mkdir(d)
except: pass # ignore if it already exists
try:
os.mkdir(d)
except FileExistsError:
pass # Ignore if it already exists,
used_images = {}
def map_name(name):
def map_name(name: str) -> str:
mapped_name = None
for mn in sorted(name_mapping.keys(), key=len, reverse=True):
if name.startswith(mn):
mapped_name = "%s/%s" % (name_mapping[mn], name)
mapped_name = '%s/%s' % (name_mapping[mn], name)
break
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:
mapped_name += "-manual"
mapped_name += '-manual'
return mapped_name
def expand_test_code(code):
code = re.sub(r'@nonfinite ([^(]+)\(([^)]+)\)(.*)', lambda m: expand_nonfinite(m.group(1), m.group(2), m.group(3)), code) # must come before '@assert throws'
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'@assert pixel (\d+,\d+) == (\d+,\d+,\d+,\d+);',
r'_assertPixel(canvas, \1, \2);',
code)
r'_assertPixel(canvas, \1, \2);', code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+);',
r'_assertPixelApprox(canvas, \1, \2, 2);',
code)
r'_assertPixelApprox(canvas, \1, \2, 2);', code)
code = re.sub(r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
r'_assertPixelApprox(canvas, \1, \2, \3);',
code)
code = re.sub(
r'@assert pixel (\d+,\d+) ==~ (\d+,\d+,\d+,\d+) \+/- (\d+);',
r'_assertPixelApprox(canvas, \1, \2, \3);', code)
code = re.sub(r'@assert throws (\S+_ERR) (.*);',
r'assert_throws_dom("\1", function() { \2; });',
code)
r'assert_throws_dom("\1", function() { \2; });', code)
code = re.sub(r'@assert throws (\S+Error) (.*);',
r'assert_throws_js(\1, function() { \2; });',
code)
r'assert_throws_js(\1, function() { \2; });', code)
code = re.sub(r'@assert (.*) === (.*);',
lambda m: '_assertSame(%s, %s, "%s", "%s");'
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
, code)
code = re.sub(
r'@assert (.*) === (.*);', lambda m:
'_assertSame(%s, %s, "%s", "%s");' % (m.group(1), m.group(
2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) !== (.*);',
lambda m: '_assertDifferent(%s, %s, "%s", "%s");'
% (m.group(1), m.group(2), escapeJS(m.group(1)), escapeJS(m.group(2)))
, code)
code = re.sub(
r'@assert (.*) !== (.*);', lambda m:
'_assertDifferent(%s, %s, "%s", "%s");' % (m.group(1), m.group(
2), escapeJS(m.group(1)), escapeJS(m.group(2))), code)
code = re.sub(r'@assert (.*) =~ (.*);',
lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2))
, code)
code = re.sub(
r'@assert (.*) =~ (.*);', lambda m: 'assert_regexp_match(%s, %s);'
% (m.group(1), m.group(2)), code)
code = re.sub(r'@assert (.*);',
lambda m: '_assert(%s, "%s");'
% (m.group(1), escapeJS(m.group(1)))
, code)
code = re.sub(
r'@assert (.*);', lambda m: '_assert(%s, "%s");' % (m.group(
1), escapeJS(m.group(1))), code)
code = re.sub(r' @moz-todo', '', code)
code = re.sub(r'@moz-UniversalBrowserRead;',
""
, code)
code = re.sub(r'@moz-UniversalBrowserRead;', '', code)
assert('@' not in code)
assert ('@' not in code)
return code
@ -231,33 +248,32 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
if test.get('canvasType', []):
HTMLCanvas_test = False
OffscreenCanvas_test = False
for type in test.get('canvasType'):
if type.lower() == 'htmlcanvas':
for canvas_type in test.get('canvasType'):
if canvas_type.lower() == 'htmlcanvas':
HTMLCanvas_test = True
elif type.lower() == 'offscreencanvas':
elif canvas_type.lower() == 'offscreencanvas':
OffscreenCanvas_test = True
name = test['name']
print("\r(%s)" % name, " "*32, "\t")
print('\r(%s)' % name, ' ' * 32, '\t')
if name in used_tests:
print("Test %s is defined twice" % name)
print('Test %s is defined twice' % name)
used_tests[name] = 1
mapped_name = map_name(name)
if not mapped_name:
mapped_name = name
cat_total = ''
for cat_part in [''] + name.split('.')[:-1]:
cat_total += cat_part+'.'
if not cat_total in category_names: category_names.append(cat_total)
cat_total += cat_part + '.'
if not cat_total in category_names:
category_names.append(cat_total)
category_contents_all.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']):
print("Probable incorrect pixel test in %s" % name)
if test.get('expected', '') == 'green' and re.search(
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()
@ -266,78 +282,97 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
expected = test['expected']
expected_img = None
if expected == 'green':
expected_img = "/images/green-100x50.png"
expected_img = '/images/green-100x50.png'
elif expected == 'clear':
expected_img = "/images/clear-100x50.png"
expected_img = '/images/clear-100x50.png'
else:
if ';' in expected:
print("Found semicolon in %s" % name)
expected = re.sub(r'^size (\d+) (\d+)',
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)\ncr = cairo.Context(surface)',
expected)
print('Found semicolon in %s' % name)
expected = re.sub(
r'^size (\d+) (\d+)',
r'surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \1, \2)'
r'\ncr = cairo.Context(surface)', expected)
if mapped_name.endswith("-manual"):
png_name = mapped_name[:-len("-manual")]
if mapped_name.endswith('-manual'):
png_name = mapped_name[:-len('-manual')]
else:
png_name = mapped_name
expected_canvas = expected + "\nsurface.write_to_png('%s/%s.png')\n" % (CANVASIMAGEOUTPUTDIR, png_name)
eval(compile(expected_canvas, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo})
expected_canvas = (expected +
"\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)
eval(compile(expected_offscreencanvas, '<test %s>' % test['name'], 'exec'), {}, {'cairo':cairo})
expected_offscreencanvas = (
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:
expectation_html = ('<p class="output expectedtext">Expected output:' +
'<p><img src="%s" class="output expected" id="expected" alt="">' % (expected_img))
expectation_html = (
'<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"')
prev = tests[i-1]['name'] if i != 0 else 'index'
next = tests[i+1]['name'] if i != len(tests)-1 else 'index'
prev_test = tests[i - 1]['name'] if i != 0 else 'index'
next_test = tests[i + 1]['name'] if i != len(tests) - 1 else 'index'
name_wrapped = name.replace('.', '.&#8203;')
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 = ''
for s in test.get('scripts', []):
scripts += '<script src="%s"></script>\n' % (s)
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:
script_variants = [('', '')]
images = ''
for i in test.get('images', []):
id = i.split('/')[-1]
if '/' not in i:
used_images[i] = 1
i = '../images/%s' % i
images += '<img src="%s" id="%s" class="resource">\n' % (i,id)
for i in test.get('svgimages', []):
id = i.split('/')[-1]
if '/' not in i:
used_images[i] = 1
i = '../images/%s' % i
images += '<svg><image xlink:href="%s" id="%s" class="resource"></svg>\n' % (i,id)
images = images.replace("../images/", "/images/")
for src in test.get('images', []):
img_id = src.split('/')[-1]
if '/' not in src:
used_images[src] = 1
src = '../images/%s' % src
images += '<img src="%s" id="%s" class="resource">\n' % (src,
img_id)
for src in test.get('svgimages', []):
img_id = src.split('/')[-1]
if '/' not in src:
used_images[src] = 1
src = '../images/%s' % src
images += ('<svg><image xlink:href="%s" id="%s" class="resource">'
'</svg>\n' % (src, img_id))
images = images.replace('../images/', '/images/')
fonts = ''
fonthack = ''
for i in test.get('fonts', []):
fonts += '@font-face {\n font-family: %s;\n src: url("/fonts/%s.ttf");\n}\n' % (i, i)
# Browsers require the font to actually be used in the page
for font in test.get('fonts', []):
fonts += ('@font-face {\n font-family: %s;\n'
' 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):
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:
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', '')
escaped_desc = simpleEscapeJS(desc)
@ -353,35 +388,58 @@ def genTestUtils_union(TEMPLATEFILE, NAME2DIRFILE):
name_variant = '' if not variant else '.' + variant
template_params = {
'name':name + name_variant,
'name_wrapped':name_wrapped, 'backrefs':backref_html(name),
'mapped_name':mapped_name,
'desc':desc, 'escaped_desc':escaped_desc,
'prev':prev, 'next':next, '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,
'name': name + name_variant,
'name_wrapped': name_wrapped,
'backrefs': backref_html(name),
'mapped_name': mapped_name,
'desc': desc,
'escaped_desc': escaped_desc,
'prev': prev_test,
'next': next_test,
'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
}
# Create test cases for canvas and offscreencanvas.
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)
if OffscreenCanvas_test:
f_html = codecs.open('%s/%s%s.html' % (OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w', 'utf-8')
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 = codecs.open(
'%s/%s%s.html' %
(OFFSCREENCANVASOUTPUTDIR, mapped_name, name_variant), 'w',
'utf-8')
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)
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
f_worker.write(temp_worker % template_params)
else:
f_html.write(templates['w3coffscreencanvas'] % template_params)
timeout = '// META: timeout=%s\n' % test['timeout'] if 'timeout' in test else ''
f_html.write(templates['w3coffscreencanvas'] %
template_params)
timeout = ('// META: timeout=%s\n' %
test['timeout'] if 'timeout' in test else '')
template_params['timeout'] = timeout
f_worker.write(templates['w3cworker'] % template_params)
print()

View file

@ -20,25 +20,26 @@
// This document has COOP: restrict-properties. The popup has COOP:
// 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",
"iframeOrigin": SAME_ORIGIN,
"popupOrigin": SAME_ORIGIN,
"opener": "restricted"
"opener": "preserved"
},
{
"title": "same site iframe, same origin popup",
"iframeOrigin": SAME_SITE,
"popupOrigin": SAME_ORIGIN,
"opener": "restricted"
"opener": "preserved"
},
{
"title": "cross origin iframe, same origin popup",
"iframeOrigin": CROSS_ORIGIN,
"popupOrigin": SAME_ORIGIN,
"opener": "restricted"
"opener": "preserved"
},
{
"title": "same origin iframe, same site popup",

View file

@ -34,7 +34,7 @@
{
"title": "popup with coop restrict-properties",
"coop": "restrict-properties",
"opener": "restricted"
"opener": "preserved"
}
].forEach(variant => {
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]
expected:
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)]
interface PaymentManager {
[SameObject] readonly attribute PaymentInstruments instruments;
attribute DOMString userHint;
Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
};
@ -21,28 +20,6 @@ enum PaymentDelegation {
"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 {
attribute EventHandler oncanmakepayment;
};

View file

@ -29,15 +29,18 @@
applyStyle(image, imageStyle);
applyStyle(container, containerStyle);
image.id = token();
container.id = token();
const entryReported = new Promise(resolve => new popup.PerformanceObserver(entryList => {
entryList.getEntries().forEach(entry => {
if (entry.id === image.id)
if (entry.id === image.id || entry.id === container.id)
resolve(entry.size);
});
}).observe({type: 'largest-contentful-paint'}));
popup.document.body.appendChild(container);
const timeout = new Promise(resolve => t.step_timeout(() => resolve('not reported'), 1000));
return {lcpSize: (await Promise.any([entryReported, timeout])), naturalSize};
return {
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

View file

@ -1,6 +1,22 @@
const 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.
// 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:

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: webrtc/tools/*
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
# it is not actually used

View file

@ -20,7 +20,6 @@ idl_test(
idl_array.add_objects({
ServiceWorkerRegistration: ['registration'],
PaymentManager: ['paymentManager'],
PaymentInstruments: ['instruments'],
});
}
if (isServiceWorker) {
@ -41,7 +40,6 @@ idl_test(
}
if (hasRegistration) {
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');
assert_equals(registration.paymentManager, registration.paymentManager);
assert_equals(registration.paymentManager.instruments, registration.paymentManager.instruments);
});
</script>

View file

@ -19,13 +19,19 @@ const delay = 2
const blank_page = `/resource-timing/resources/blank_page_green.htm`;
const destUrl = `/common/slow-redirect.py?delay=${delay}&location=${REMOTE_ORIGIN}/${blank_page}`;
const timeBefore = performance.now()
attribute_test(load.iframe, destUrl, entry => {
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');
// 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');
}, "Verify that cross-origin resources don't implicitly expose their redirect timings")
const timeBefore = performance.now();
(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_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
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")
})();
</script>
</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 timeBefore = performance.now()
attribute_test(load_null_object, destUrl, entry => {
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');
// 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');
}, "Verify that cross-origin object resources don't implicitly expose their redirect timings")
const timeBefore = performance.now();
(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_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
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")
})();
</script>
</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
// values.
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);
const timeout = new Promise(r => step_timeout(() => {
console.log("Timeout was reached before entry fired");
r(null);
}, 2000));
const entry = await Promise.race([loaded_entry, timeout]);
assert_not_equals(entry, null, 'No entry was recieved');
const entry = await await_with_timeout(2000,
"Timeout was reached before entry fired",
loaded_entry);
assert_not_equals(entry, null, 'No entry was received');
run_test(entry);
}, test_label);
};

View file

@ -135,7 +135,7 @@ const load = {
// object.
object: async (path, type) => {
const object = document.createElement("object");
const loaded = new Promise(resolve => {
const object_load_settled = new Promise(resolve => {
object.onload = object.onerror = resolve;
});
object.data = load.cache_bust(path);
@ -143,12 +143,11 @@ const load = {
object.type = type;
}
document.body.appendChild(object);
const timeout = new Promise(r => step_timeout(() => {
console.log("Timeout was reached before load or error events fired");
r();
}, 2000));
await Promise.race([loaded, timeout]);
document.body.removeChild(object);
await await_with_timeout(2000,
"Timeout was reached before load or error events fired",
object_load_settled,
() => { document.body.removeChild(object) }
);
},
// 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");
}
const load_frame_object = async path => {
return load.object(path, "text/html");
}
const load_null_object = async path => {
return load.object(path, null);
}
@ -38,6 +42,7 @@ for(const loader of [
load.xhr_async,
load.iframe,
load_image_object,
load_frame_object,
load_null_object
]) {
for(const status of status_codes) {
@ -88,6 +93,7 @@ for(const loader of [
load.stylesheet,
load.iframe,
load_image_object,
load_frame_object,
load_null_object
]) {
for(const tao of [false, true]) {
@ -113,6 +119,7 @@ for(const loader of [
// Same-Origin => Cross-Origin => Same-Origin => Same-Origin redirect chain
for(const loader of [
load.iframe,
load_frame_object,
load_null_object
]) {
for(const status of status_codes) {
@ -136,6 +143,7 @@ for(const loader of [
// Response status for iframes is exposed for same origin redirects
for(const loader of [
load.iframe,
load_frame_object,
load_null_object
]) {
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.wptrunner.wptrunner import manifestexpected
from tools.wptrunner.wptrunner.manifestupdate import get_test_name
from localpaths import repo_root
@pytest.fixture
@ -118,11 +119,11 @@ def test_update(tmp_path, metadata_file):
run_info_firefox)
# Default expected isn't stored
with pytest.raises(KeyError):
assert firefox_expected.get_test(test_id.rpartition('/')[-1]).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("expected")
assert firefox_expected.get_test(get_test_name(test_id)).get_subtest(subtest_name).expected == "FAIL"
chrome_expected = manifestexpected.get_manifest(metadata_path,
test_path,
run_info_chrome)
assert chrome_expected.get_test(test_id.rpartition('/')[-1]).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)).expected == "ERROR"
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:
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:
def __init__(self, manifest, **kwargs):
@ -218,7 +222,7 @@ class TestNode(ManifestItem):
:param test_type: The type 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)
self = cls(node)

View file

@ -11,6 +11,7 @@ from collections import defaultdict, deque, namedtuple
from . import manifestinclude
from . import manifestexpected
from . import manifestupdate
from . import mpcontext
from . import wpttest
from mozlog import structured
@ -267,7 +268,7 @@ class TestLoader:
def get_test(self, manifest_file, manifest_test, inherit_metadata, test_metadata):
if test_metadata is not None:
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)

View file

@ -7,7 +7,7 @@ from manifest import manifest as wptmanifest
from manifest.item import TestharnessTest, RefTest
from manifest.utils import to_os_path
from . test_update import tree_and_sourcefile_mocks
from .. import manifestexpected, wpttest
from .. import manifestexpected, manifestupdate, wpttest
dir_ini_0 = b"""\
@ -111,7 +111,8 @@ def make_test_object(test_name,
test_path=test_path)
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():
@ -224,7 +225,8 @@ def test_metadata_fuzzy():
test_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_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,
};
return promise_rejects_dom(
t, "NotSupportedError", assert(id, {evalByCredential: byCred }));
t, "SyntaxError", assert(id, {evalByCredential: byCred }));
}, "navigator.credentials.get() using invalid base64url credential ID");
promise_test(async t => {