mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Update web-platform-tests to revision 0abb411331f86f472103183c7ec1136ea21a7e1b
This commit is contained in:
parent
d671010e46
commit
5a5512f805
139 changed files with 2559 additions and 1445 deletions
|
@ -7,7 +7,7 @@
|
|||
expected: FAIL
|
||||
|
||||
[Opening a blob URL in a new window immediately before revoking it works.]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -128395,6 +128395,18 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/infinite-radial-gradient-crash.html": [
|
||||
[
|
||||
"css/css-images/infinite-radial-gradient-crash.html",
|
||||
[
|
||||
[
|
||||
"/css/css-images/infinite-radial-gradient-crash-ref.html",
|
||||
"=="
|
||||
]
|
||||
],
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-images/linear-gradient-1.html": [
|
||||
[
|
||||
"css/css-images/linear-gradient-1.html",
|
||||
|
@ -251340,6 +251352,9 @@
|
|||
"css/css-images/gradients-with-transparent-ref.html": [
|
||||
[]
|
||||
],
|
||||
"css/css-images/infinite-radial-gradient-crash-ref.html": [
|
||||
[]
|
||||
],
|
||||
"css/css-images/linear-gradient-ref.html": [
|
||||
[]
|
||||
],
|
||||
|
@ -264627,6 +264642,9 @@
|
|||
"docs/writing-tests/lint-tool.md": [
|
||||
[]
|
||||
],
|
||||
"docs/writing-tests/making-a-testing-plan.md": [
|
||||
[]
|
||||
],
|
||||
"docs/writing-tests/manual.md": [
|
||||
[]
|
||||
],
|
||||
|
@ -274512,9 +274530,21 @@
|
|||
"infrastructure/metadata/infrastructure/expected-fail/timeout.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception-following-subtest.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception-single-test.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-following-subtest.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-single-test.html.ini": [
|
||||
[]
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [
|
||||
[]
|
||||
],
|
||||
|
@ -276015,6 +276045,9 @@
|
|||
"mixed-content/META.yml": [
|
||||
[]
|
||||
],
|
||||
"mixed-content/README.md": [
|
||||
[]
|
||||
],
|
||||
"mixed-content/gen/top.http-rp/opt-in/audio-tag/cross-http.keep-scheme.https.html.headers": [
|
||||
[]
|
||||
],
|
||||
|
@ -287343,6 +287376,9 @@
|
|||
"upgrade-insecure-requests/META.yml": [
|
||||
[]
|
||||
],
|
||||
"upgrade-insecure-requests/README.md": [
|
||||
[]
|
||||
],
|
||||
"upgrade-insecure-requests/gen/top.http-rp/upgrade/fetch/cross-http-downgrade.downgrade.https.html.headers": [
|
||||
[]
|
||||
],
|
||||
|
@ -288492,6 +288528,9 @@
|
|||
"webgpu/framework/test_group.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/framework/tree.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/framework/url_query.js": [
|
||||
[]
|
||||
],
|
||||
|
@ -288510,6 +288549,12 @@
|
|||
"webgpu/framework/version.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/runtime/helper/options.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/runtime/helper/test_worker.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/runtime/wpt.js": [
|
||||
[]
|
||||
],
|
||||
|
@ -288555,6 +288600,9 @@
|
|||
"webgpu/suites/cts/fences.spec.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/suites/cts/format_info.js": [
|
||||
[]
|
||||
],
|
||||
"webgpu/suites/cts/gpu_test.js": [
|
||||
[]
|
||||
],
|
||||
|
@ -316696,30 +316744,6 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-box/parsing/min-height-invalid.html": [
|
||||
[
|
||||
"css/css-box/parsing/min-height-invalid.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-box/parsing/min-height-valid.html": [
|
||||
[
|
||||
"css/css-box/parsing/min-height-valid.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-box/parsing/min-width-invalid.html": [
|
||||
[
|
||||
"css/css-box/parsing/min-width-invalid.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-box/parsing/min-width-valid.html": [
|
||||
[
|
||||
"css/css-box/parsing/min-width-valid.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-box/parsing/overflow-invalid.html": [
|
||||
[
|
||||
"css/css-box/parsing/overflow-invalid.html",
|
||||
|
@ -327724,6 +327748,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"css/css-transforms/transform-scale-hittest.html": [
|
||||
[
|
||||
"css/css-transforms/transform-scale-hittest.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"css/css-transforms/transform_translate.html": [
|
||||
[
|
||||
"css/css-transforms/transform_translate.html",
|
||||
|
@ -337797,6 +337827,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"element-timing/multi-redirect-image.html": [
|
||||
[
|
||||
"element-timing/multi-redirect-image.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"element-timing/multiple-background-images.html": [
|
||||
[
|
||||
"element-timing/multiple-background-images.html",
|
||||
|
@ -367713,12 +367749,36 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception-following-subtest.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/uncaught-exception-following-subtest.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception-single-test.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/uncaught-exception-single-test.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/uncaught-exception.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection-following-subtest.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/unhandled-rejection-following-subtest.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection-single-test.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/unhandled-rejection-single-test.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection.html": [
|
||||
[
|
||||
"infrastructure/expected-fail/unhandled-rejection.html",
|
||||
|
@ -424316,6 +424376,12 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"webgpu/runtime/helper/test_worker.worker.js": [
|
||||
[
|
||||
"webgpu/runtime/helper/test_worker.worker.html",
|
||||
{}
|
||||
]
|
||||
],
|
||||
"webmessaging/Channel_postMessage_Blob.htm": [
|
||||
[
|
||||
"webmessaging/Channel_postMessage_Blob.htm",
|
||||
|
@ -468754,7 +468820,7 @@
|
|||
"support"
|
||||
],
|
||||
"common/security-features/README.md": [
|
||||
"2bb060a8900396da3fcaf605b768400801523cb1",
|
||||
"98afe1af1be8d6329f9ae687320d4bd4797ca2c8",
|
||||
"support"
|
||||
],
|
||||
"common/security-features/resources/common.sub.js": [
|
||||
|
@ -468878,7 +468944,7 @@
|
|||
"support"
|
||||
],
|
||||
"common/security-features/tools/generate.py": [
|
||||
"fa36d8c63d6d84a1c5eafd3160b879f7f3c94310",
|
||||
"6fac19827aa1043ad7d3244cf78f44a8ed0b5cbc",
|
||||
"support"
|
||||
],
|
||||
"common/security-features/tools/spec_validator.py": [
|
||||
|
@ -468894,11 +468960,11 @@
|
|||
"support"
|
||||
],
|
||||
"common/security-features/tools/template/test.debug.html.template": [
|
||||
"8ec0ab7c07544854367b662b9d0e1fd337189c40",
|
||||
"b4b0fec733e1ce6f6a5cad0f9c9d4391aa244fb1",
|
||||
"support"
|
||||
],
|
||||
"common/security-features/tools/template/test.release.html.template": [
|
||||
"6416baa8ac83cae43f18b83965e985ecf8740b68",
|
||||
"d93506e231a4c6e719b055b1e312bd163eb9519d",
|
||||
"support"
|
||||
],
|
||||
"common/security-features/tools/util.py": [
|
||||
|
@ -557229,22 +557295,6 @@
|
|||
"1e08a820d9dd1dc98f2bd0ada5550e32081d2e75",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-box/parsing/min-height-invalid.html": [
|
||||
"edc480e1e897e1a46edf8e8aa64d1b4486f96fde",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-box/parsing/min-height-valid.html": [
|
||||
"0154c02b7b913681515878471553791d9e8a7d45",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-box/parsing/min-width-invalid.html": [
|
||||
"e89826fb05694890f3469291316db1e2f4a569b9",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-box/parsing/min-width-valid.html": [
|
||||
"f745b66bd43e24460548b9d5fd3a6d0e46bf4284",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-box/parsing/overflow-invalid.html": [
|
||||
"4747764fb6a4ddd6fadf08d970753923d4afb42b",
|
||||
"testharness"
|
||||
|
@ -577109,6 +577159,14 @@
|
|||
"6947515f7e4634fc3f240ffda91c6f5bdac862ce",
|
||||
"visual"
|
||||
],
|
||||
"css/css-images/infinite-radial-gradient-crash-ref.html": [
|
||||
"a80236dcf75c22ecd8e43935d004f1fddf0550cb",
|
||||
"support"
|
||||
],
|
||||
"css/css-images/infinite-radial-gradient-crash.html": [
|
||||
"a3a1e7fb069d311162c5cfa427125bac524ffaa2",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-images/inheritance.html": [
|
||||
"5ca1ed6b23ff70637d790baf81ae4e3cbf5afe8c",
|
||||
"testharness"
|
||||
|
@ -589186,7 +589244,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/css-sizing/parsing/min-height-invalid.html": [
|
||||
"0bb939b12be245758dde7ce93e1edab8a19fa0df",
|
||||
"57119fc1ae50339c6ce34b09a285b6c09185df55",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-sizing/parsing/min-height-valid.html": [
|
||||
|
@ -589198,7 +589256,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"css/css-sizing/parsing/min-width-invalid.html": [
|
||||
"b4e600900dbb8c722567570caa3629c7c5811461",
|
||||
"1286acd9d07047d89fec5d32abe60a7ff5ffae77",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-sizing/parsing/min-width-valid.html": [
|
||||
|
@ -601497,6 +601555,10 @@
|
|||
"62b5d39037edf2e4ef499c03065e280012b9ddf8",
|
||||
"reftest"
|
||||
],
|
||||
"css/css-transforms/transform-scale-hittest.html": [
|
||||
"5a9d3f85f3983b221bf3705ac342eeddd5c933a3",
|
||||
"testharness"
|
||||
],
|
||||
"css/css-transforms/transform-scale-percent-001.html": [
|
||||
"79d32b5c0453d7a219cb3d6e03a7653ed342f947",
|
||||
"reftest"
|
||||
|
@ -631098,13 +631160,17 @@
|
|||
"support"
|
||||
],
|
||||
"docs/writing-tests/index.md": [
|
||||
"88e279b0ad128d168efc9be3d25209c8ebfec21e",
|
||||
"0e0d3f35b00a20345d319914344bf779d4016aa8",
|
||||
"support"
|
||||
],
|
||||
"docs/writing-tests/lint-tool.md": [
|
||||
"f3a34ef1bc0b7c44b28493c246859b172b6f9506",
|
||||
"support"
|
||||
],
|
||||
"docs/writing-tests/making-a-testing-plan.md": [
|
||||
"0f5673016c0502edc11c915ee64b4901ed384c23",
|
||||
"support"
|
||||
],
|
||||
"docs/writing-tests/manual.md": [
|
||||
"122a22b3f367d36d749c567c62c09ae9454c2aee",
|
||||
"support"
|
||||
|
@ -633669,6 +633735,10 @@
|
|||
"06d9bfd07a0f342dbacd00c23bc36b155335f531",
|
||||
"testharness"
|
||||
],
|
||||
"element-timing/multi-redirect-image.html": [
|
||||
"c2f570f20df7989617ea37beaee266562cbf7756",
|
||||
"testharness"
|
||||
],
|
||||
"element-timing/multiple-background-images.html": [
|
||||
"b29e66c04a70dffbc17f05f516d3d190159ec1c5",
|
||||
"testharness"
|
||||
|
@ -633730,7 +633800,7 @@
|
|||
"support"
|
||||
],
|
||||
"element-timing/resources/element-timing-helpers.js": [
|
||||
"6328ee7bb6fc8b29003882b458de90cc282dc591",
|
||||
"b7f2eef5978ac5d559865dd34848f15ef0abba10",
|
||||
"support"
|
||||
],
|
||||
"element-timing/resources/iframe-stores-entry.html": [
|
||||
|
@ -638038,11 +638108,11 @@
|
|||
"support"
|
||||
],
|
||||
"fetch/content-length/content-length.html": [
|
||||
"af8ea44eeefa6d797ac69623aaedb11a09161a0e",
|
||||
"cda9b5b523701558c0d613bf6e0e5462b0ffa9c2",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/content-length/content-length.html.headers": [
|
||||
"385ea556d7a1da0d9a0507ec3633550e4bd82060",
|
||||
"25389b7c0fab38799f117bbe0a4261c02b96cae5",
|
||||
"support"
|
||||
],
|
||||
"fetch/content-type/README.md": [
|
||||
|
@ -638218,11 +638288,11 @@
|
|||
"testharness"
|
||||
],
|
||||
"fetch/corb/script-js-mislabeled-as-html-nosniff.sub.html": [
|
||||
"f155deff090e4352580847a2aaa41e462d97958a",
|
||||
"b6bc90964deb14afaf4abe3b668d577ca8b23a7e",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/script-js-mislabeled-as-html.sub.html": [
|
||||
"3a923e66356db1725b1de1b7e211df001cb6f2a5",
|
||||
"44cb1f8659d81dc8059b866bd473caec06add274",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/script-resource-with-json-parser-breaker.tentative.sub.html": [
|
||||
|
@ -638230,23 +638300,23 @@
|
|||
"testharness"
|
||||
],
|
||||
"fetch/corb/script-resource-with-nonsniffable-types.tentative.sub.html": [
|
||||
"592a33ef3baf49b02812d49bbba1105b7766b302",
|
||||
"4e34ecd94b47839f271ec8d6998c06941e76b44f",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/style-css-mislabeled-as-html-nosniff.sub.html": [
|
||||
"1d53621186d26edc447fb74e02b6630c69b03271",
|
||||
"8fef0dc59e437b167cac10edddf113393eab3fa0",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/style-css-mislabeled-as-html.sub.html": [
|
||||
"05f6fdb9fb955b610b4fc1032cd74bcb48292868",
|
||||
"4f0b4c22f56681f42b540821799cfe4f87cb0580",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/style-css-with-json-parser-breaker.sub.html": [
|
||||
"c6b5889c331e22102f77d90f76efae200d051cd7",
|
||||
"29ed586a4f0f2f5b1c26534e45572b559bbc963e",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/corb/style-html-correctly-labeled.sub.html": [
|
||||
"c99eb053d61862260891ebdf04338a841f49d2cf",
|
||||
"cdefcd2d2c9a5fa8cd4436591ac31f3ff26700fd",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/cors-rfc1918/idlharness.tentative.any.js": [
|
||||
|
@ -638398,7 +638468,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"fetch/images/canvas-remote-read-remote-image-redirect.html": [
|
||||
"bfcb7537651f285d0aa5d60a41032c534ff39b95",
|
||||
"32a387288af1db934458bcc77512c388ec2ab168",
|
||||
"testharness"
|
||||
],
|
||||
"fetch/metadata/README.md": [
|
||||
|
@ -661106,7 +661176,7 @@
|
|||
"support"
|
||||
],
|
||||
"infrastructure/browsers/firefox/prefs.html": [
|
||||
"51f9f994ac50ea8c286bbcb2f47863550e800415",
|
||||
"9656aa051eb6539de8024c56f092f010bfcd1962",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/failing-test.html": [
|
||||
|
@ -661117,10 +661187,26 @@
|
|||
"29ff348a9af645ff59d860e91af9534e64a606c5",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception-following-subtest.html": [
|
||||
"ed95c6032841bbdc8ee589ed71cbbb0926dc3ec3",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception-single-test.html": [
|
||||
"4f88704cad67b24d6291555425b37506b30f8262",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/uncaught-exception.html": [
|
||||
"4442d513753112fac2e35855268d0b246f01fa09",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection-following-subtest.html": [
|
||||
"2cc19d96243620903eeb115397724380e9ec0289",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection-single-test.html": [
|
||||
"925787191c37a2bf897d7ed3fb29def0e15fc92a",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/expected-fail/unhandled-rejection.html": [
|
||||
"f25f6e088fa06fbcd38b62929309e761b0060988",
|
||||
"testharness"
|
||||
|
@ -661157,10 +661243,26 @@
|
|||
"53b281f8358c4f90aab96c731076439ccb5567b4",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception-following-subtest.html.ini": [
|
||||
"f7f3d4f7b5dfe3549a1602d84fffb29e70cf18d6",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception-single-test.html.ini": [
|
||||
"6d2bd7f236780e76afec7569405511ae94bf4b88",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini": [
|
||||
"0bcdd374f2521b6534208ab750a1c0d36e7dd7ca",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-following-subtest.html.ini": [
|
||||
"ff1861aff94622eb8559b1c483b67b8da2c54df4",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-single-test.html.ini": [
|
||||
"f785f4cc6ec5451cd0d41414d28050165fe38aac",
|
||||
"support"
|
||||
],
|
||||
"infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [
|
||||
"39773dfe714a6b5754bfe73c64294bcb38f2afa3",
|
||||
"support"
|
||||
|
@ -661490,7 +661592,7 @@
|
|||
"support"
|
||||
],
|
||||
"infrastructure/testdriver/file_upload.sub.html": [
|
||||
"29c42b49f1716200ef6b68eda4fefd716441fcd8",
|
||||
"451ae500f077bab14d30c60f3e8608d10f6516b3",
|
||||
"testharness"
|
||||
],
|
||||
"infrastructure/testdriver/file_upload_data.txt": [
|
||||
|
@ -662078,7 +662180,7 @@
|
|||
"support"
|
||||
],
|
||||
"interfaces/webauthn.idl": [
|
||||
"cf86a25b1013e0e4102cc9cc67ae0791c963fac6",
|
||||
"81728b8aba4751c6791cad274be67e4c08f505a3",
|
||||
"support"
|
||||
],
|
||||
"interfaces/webdriver.idl": [
|
||||
|
@ -665397,6 +665499,10 @@
|
|||
"a2889eb6c7afd8894955c54c73e77e517541b562",
|
||||
"support"
|
||||
],
|
||||
"mixed-content/README.md": [
|
||||
"407b8960cbeb108b729ba5bdc70e1ace41e944ea",
|
||||
"support"
|
||||
],
|
||||
"mixed-content/gen/top.http-rp/opt-in/audio-tag/cross-http.keep-scheme.https.html": [
|
||||
"7c3ca228d795bc7cd13d637f05baea5e1c0c61a6",
|
||||
"testharness"
|
||||
|
@ -667998,7 +668104,7 @@
|
|||
"support"
|
||||
],
|
||||
"mixed-content/generic/tools/generate.py": [
|
||||
"b80bc8df6bbebe969b88fd48d52abc7819ac9a3c",
|
||||
"060bdabf91cc41f9be0d6c8e5bbf4a8e05c381c1",
|
||||
"support"
|
||||
],
|
||||
"mixed-content/imageset.https.sub.html": [
|
||||
|
@ -677618,7 +677724,7 @@
|
|||
"support"
|
||||
],
|
||||
"referrer-policy/README.md": [
|
||||
"498f7f26137b71a7776f07868261776c542b27c7",
|
||||
"ca9977c89ec36493bb6ec35cde30df8e8e6c187a",
|
||||
"support"
|
||||
],
|
||||
"referrer-policy/css-integration/README.md": [
|
||||
|
@ -689802,7 +689908,7 @@
|
|||
"support"
|
||||
],
|
||||
"referrer-policy/generic/tools/generate.py": [
|
||||
"480603b9bd870d3e1abd577de31f3f6192caa2e8",
|
||||
"7cace61c0f0b7cd973bf2ea6f88d12a436805d48",
|
||||
"support"
|
||||
],
|
||||
"referrer-policy/generic/unsupported-csp-referrer-directive.html": [
|
||||
|
@ -690050,15 +690156,15 @@
|
|||
"testharness"
|
||||
],
|
||||
"resource-timing/crossorigin-sandwich-TAO.sub.html": [
|
||||
"04c5e2c9970c9fa1f6d4427a5a30fab4045f8e9b",
|
||||
"468d055af95b73c59f345065db76f927bf2473c3",
|
||||
"testharness"
|
||||
],
|
||||
"resource-timing/crossorigin-sandwich-no-TAO.sub.html": [
|
||||
"c7e7e5948dc5cbb5fb331112ab2dc562d5e430ad",
|
||||
"d90387b3bbda30224715f5b0602f603b2c2921d4",
|
||||
"testharness"
|
||||
],
|
||||
"resource-timing/crossorigin-sandwich-partial-TAO.sub.html": [
|
||||
"2b748e9097dacea75424412beae53fe2bf7a2bb7",
|
||||
"076a003b7c993d6e2e092c482733579595928c5f",
|
||||
"testharness"
|
||||
],
|
||||
"resource-timing/document-domain-no-impact-loader.sub.html": [
|
||||
|
@ -690106,7 +690212,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"resource-timing/resource_TAO_cross_origin_redirect_chain.html": [
|
||||
"9089e8fbb00bb8c0e84d7ce7eac84c90b1ed3e04",
|
||||
"054a0e5643e7d9464f27711599843910b57a05a9",
|
||||
"testharness"
|
||||
],
|
||||
"resource-timing/resource_TAO_match_origin.htm": [
|
||||
|
@ -690230,7 +690336,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"resource-timing/resource_timing_cross_origin_redirect_chain.html": [
|
||||
"5675f20f1dd78c90c87313ccdbbf4c9a5b7f38dc",
|
||||
"f8d39e7bfa4a5d07e99cd82d8d0b7a5f3158d594",
|
||||
"testharness"
|
||||
],
|
||||
"resource-timing/resource_timing_same_origin_redirect.html": [
|
||||
|
@ -690414,7 +690520,7 @@
|
|||
"support"
|
||||
],
|
||||
"resource-timing/resources/multi_redirect.py": [
|
||||
"e70c90bb44827466cfd5a55960de47fe37038f2c",
|
||||
"99387c15bb619e9006dc4a5fa161f1ab4ab66e93",
|
||||
"support"
|
||||
],
|
||||
"resource-timing/resources/navigate_back.html": [
|
||||
|
@ -701566,7 +701672,7 @@
|
|||
"support"
|
||||
],
|
||||
"tools/ci/epochs_update.sh": [
|
||||
"c95f9ca0f13481589ee1358c7ad8fdf94d13328b",
|
||||
"4b393fa6db5f90c18daccf6cef3a9706f1411415",
|
||||
"support"
|
||||
],
|
||||
"tools/ci/jobs.py": [
|
||||
|
@ -701854,7 +701960,7 @@
|
|||
"support"
|
||||
],
|
||||
"tools/manifest/item.py": [
|
||||
"d7165787ca4d6f8e398ecb4400673da4aeaf2d49",
|
||||
"a38709193a9bed82e6bff5849c07679abb6abafd",
|
||||
"support"
|
||||
],
|
||||
"tools/manifest/log.py": [
|
||||
|
@ -702306,11 +702412,11 @@
|
|||
"support"
|
||||
],
|
||||
"tools/requirements_flake8.txt": [
|
||||
"d73e7c3dbbe2f0cf20637e639c449b0fa4538caf",
|
||||
"16e35cf5aa957755d0b171e8a86f69c208484996",
|
||||
"support"
|
||||
],
|
||||
"tools/requirements_mypy.txt": [
|
||||
"cd4ae2b276937a9abc45db59d950d88ddb6dc626",
|
||||
"31545c2f0747a9c20d77b50d27096a4ecafd4351",
|
||||
"support"
|
||||
],
|
||||
"tools/runner/css/bootstrap-theme.min.css": [
|
||||
|
@ -706398,7 +706504,7 @@
|
|||
"support"
|
||||
],
|
||||
"tools/wpt/revlist.py": [
|
||||
"f750311914ac13408cc082e58c36c2471e8f48be",
|
||||
"c4cbc2943b7ce02ef2a58f65d34ab717bfb0c981",
|
||||
"support"
|
||||
],
|
||||
"tools/wpt/run.py": [
|
||||
|
@ -706418,7 +706524,7 @@
|
|||
"support"
|
||||
],
|
||||
"tools/wpt/tests/test_revlist.py": [
|
||||
"7b13106d0f553727f6bdb32c47a6babf70d8f4a8",
|
||||
"ec2a6b899d5d1a927dcad1f9a7583f987a3ad947",
|
||||
"support"
|
||||
],
|
||||
"tools/wpt/tests/test_run.py": [
|
||||
|
@ -706686,7 +706792,7 @@
|
|||
"support"
|
||||
],
|
||||
"tools/wptrunner/wptrunner/browsers/chrome.py": [
|
||||
"c71d77251ea1c84b404674ba6010361ae5705767",
|
||||
"80614c5e551c35dd1cf2bbd12495d40e02391371",
|
||||
"support"
|
||||
],
|
||||
"tools/wptrunner/wptrunner/browsers/chrome_android.py": [
|
||||
|
@ -707746,7 +707852,7 @@
|
|||
"support"
|
||||
],
|
||||
"trusted-types/trusted-types-reporting.tentative.https.html": [
|
||||
"10a951fa12cb8d69249a96cb85ce34f6136e52c5",
|
||||
"70afb9745a88e6ffbce15a1d868d1f099c339e80",
|
||||
"testharness"
|
||||
],
|
||||
"trusted-types/trusted-types-reporting.tentative.https.html.headers": [
|
||||
|
@ -707949,6 +708055,10 @@
|
|||
"a30208ae10d9fea605655386462d289907729a16",
|
||||
"support"
|
||||
],
|
||||
"upgrade-insecure-requests/README.md": [
|
||||
"516e8e262f4b18375689cb45d15f2c516c24571f",
|
||||
"support"
|
||||
],
|
||||
"upgrade-insecure-requests/gen/iframe-blank-inherit.meta/unset/fetch/cross-http-downgrade.downgrade.https.html": [
|
||||
"b85583ff2cee179ac58a7c429c79400c438c95b2",
|
||||
"testharness"
|
||||
|
@ -710914,7 +711024,7 @@
|
|||
"support"
|
||||
],
|
||||
"upgrade-insecure-requests/generic/tools/generate.py": [
|
||||
"cde29893f5fbd35ff0ccf00f7ee323fbb3194c8b",
|
||||
"4c19f4c34dab0ecd302ae22fcffdc3f07ce935c6",
|
||||
"support"
|
||||
],
|
||||
"upgrade-insecure-requests/link-upgrade.sub.https.html": [
|
||||
|
@ -713338,7 +713448,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"web-nfc/NDEFMessage_constructor.https.html": [
|
||||
"0ba82240781300a934cbc0f2fa96abc6a5ff490c",
|
||||
"a6a2e6bd67c5c480367e20dd46e7a796b4c4f8a9",
|
||||
"testharness"
|
||||
],
|
||||
"web-nfc/NDEFReader-document-hidden-manual.https.html": [
|
||||
|
@ -713346,7 +713456,7 @@
|
|||
"manual"
|
||||
],
|
||||
"web-nfc/NDEFReader_options.https.html": [
|
||||
"b9015dc2a57afbd1f511c84f12ae5085be3b18a0",
|
||||
"ab55e2c160bd39710a62238fce795ff63f03c995",
|
||||
"testharness"
|
||||
],
|
||||
"web-nfc/NDEFReader_scan.https.html": [
|
||||
|
@ -713362,7 +713472,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"web-nfc/NDEFRecord_constructor.https.html": [
|
||||
"6a57616d126edf339fc7f3e077b8e427e3480c5e",
|
||||
"cea517d37aa17bf94c3d96c9abd19db5f1fa184c",
|
||||
"testharness"
|
||||
],
|
||||
"web-nfc/NDEFWriter-document-hidden-manual.https.html": [
|
||||
|
@ -713370,7 +713480,7 @@
|
|||
"manual"
|
||||
],
|
||||
"web-nfc/NDEFWriter_push.https.html": [
|
||||
"0d5722bfa019610633cef78d0d2164b2e55de8bb",
|
||||
"fbebac946dfbf77a49c11c0472da900ca26759be",
|
||||
"testharness"
|
||||
],
|
||||
"web-nfc/README.md": [
|
||||
|
@ -713386,7 +713496,7 @@
|
|||
"testharness"
|
||||
],
|
||||
"web-nfc/resources/nfc-helpers.js": [
|
||||
"4685f65090dbd4c8be36af38960267bd4e7f07a0",
|
||||
"80f0882f9f8deff30b0c8c60ecb1bfc7c6df168c",
|
||||
"support"
|
||||
],
|
||||
"web-nfc/resources/support-iframe.html": [
|
||||
|
@ -715578,7 +715688,7 @@
|
|||
"support"
|
||||
],
|
||||
"webdriver/tests/take_element_screenshot/iframe.py": [
|
||||
"d081a14cdeb56d43ee7d10e5b3ec23a53c98bedc",
|
||||
"242122f0b5e7359c364a8aa1da345fc3da15acf1",
|
||||
"wdspec"
|
||||
],
|
||||
"webdriver/tests/take_element_screenshot/screenshot.py": [
|
||||
|
@ -715594,7 +715704,7 @@
|
|||
"support"
|
||||
],
|
||||
"webdriver/tests/take_screenshot/iframe.py": [
|
||||
"5206f2fa1736f118e5a4b06906325da0e06158b3",
|
||||
"4cf8ad06b56d8f44af06550af4c4a1b7715b908b",
|
||||
"wdspec"
|
||||
],
|
||||
"webdriver/tests/take_screenshot/screenshot.py": [
|
||||
|
@ -715646,15 +715756,15 @@
|
|||
"testharness"
|
||||
],
|
||||
"webgpu/framework/allowed_characters.js": [
|
||||
"f49e19641d95bcc510f09f1bb045825c19d6b28c",
|
||||
"af8f45172b52b3cdc6246218c40e5484a7517a63",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/collect_garbage.js": [
|
||||
"5589fa7deb3819dfa9cfa0b202e432b73569b675",
|
||||
"dc5a9caf850b967ea0779fee6b7c725376c0bbbb",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/fixture.js": [
|
||||
"6e13385eef42d8af73b97a44a0945802483538c7",
|
||||
"2c1ea8314689e610528ba81254ee00e99242f4d5",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/gpu/implementation.js": [
|
||||
|
@ -715674,15 +715784,15 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/framework/loader.js": [
|
||||
"c9cd20f307c3006b48a3e9f8aac373d56914f76b",
|
||||
"328989a8d7b0a9a305953e735cd2eef58a47d8e0",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/logger.js": [
|
||||
"d97be59091a1d9b5eadd93a105ba1023e730f8a1",
|
||||
"e854292473640a21d6bb660a2a0999e740a90c8e",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/params/combine.js": [
|
||||
"d85e81dc88510a314bbffccbf6fa0b6ced61c5ae",
|
||||
"181877cf1650ef59c6d1f19a2ebff8cd84c5b790",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/params/exclude.js": [
|
||||
|
@ -715694,7 +715804,7 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/framework/params/index.js": [
|
||||
"5d89da54f5b77174615a8d26edf206253fff0ace",
|
||||
"bb21202f92de8395873d807aa02e283067e84bf7",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/params/options.js": [
|
||||
|
@ -715722,11 +715832,15 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/framework/test_group.js": [
|
||||
"09697765b8c7c715bac92536418cceb1ce632ef9",
|
||||
"69d8cc0401714f4f6ffe2ddfe0f8763b833914e5",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/tree.js": [
|
||||
"a0690519dbbe9e6ddc4c036acbca60dd409e0dc0",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/url_query.js": [
|
||||
"f7c7cbc17fe5a908eb5b496a4a267274ebbc0030",
|
||||
"3712432888f6d2ac46aa410bb098ce7971ef0f93",
|
||||
"support"
|
||||
],
|
||||
"webgpu/framework/util/async_mutex.js": [
|
||||
|
@ -715746,35 +715860,47 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/framework/version.js": [
|
||||
"0bfbfad4f3995d27200b1601ef8411f5b16c12ae",
|
||||
"55a72f5efb03ad9043ea2600a311cfff249a21ce",
|
||||
"support"
|
||||
],
|
||||
"webgpu/runtime/helper/options.js": [
|
||||
"1a90beadf1ee459911b2b549fc9359b44fe37bbd",
|
||||
"support"
|
||||
],
|
||||
"webgpu/runtime/helper/test_worker.js": [
|
||||
"8a8c232f3b11b4a326a4f11ef60319d2b157710e",
|
||||
"support"
|
||||
],
|
||||
"webgpu/runtime/helper/test_worker.worker.js": [
|
||||
"513874144f714e50a289cd22cc88087cd73235e3",
|
||||
"testharness"
|
||||
],
|
||||
"webgpu/runtime/wpt.js": [
|
||||
"ec4ab0123924659e9cb23ba916c51d7ea6aa75cc",
|
||||
"c87f9167bbeba1edca847a76a6cb59401f0c7409",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/buffers/create_mapped.spec.js": [
|
||||
"30a6638889a916c03b57a9cbf33ae3f46cdc8eb0",
|
||||
"4a727008b8cfea4d9ef3fa5bd48f2b2c38d8cf37",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/buffers/map.spec.js": [
|
||||
"dfc79ac5d1e9bafb58b00c7bf4c23d029e9605c2",
|
||||
"3794573c83c6e6747e2c9055e72ba892c57fdc8c",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/buffers/map_detach.spec.js": [
|
||||
"afaab08606be74d7bee8544a23b79228a770572b",
|
||||
"c8bd2dc68e5949f7b490b43304636ec1d4f290e2",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/buffers/map_oom.spec.js": [
|
||||
"f39021ca9a181dd5f6b94ee17a895e7f0cd802f2",
|
||||
"db791cedd33018160726dd031272ea4f72ae0f63",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/buffers/mapping_test.js": [
|
||||
"1baa6ffc3519091622dab337c92b87d1e357a157",
|
||||
"20d6c96ffa2ded3d25990a578d2109548a6f6966",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/canvas/context_creation.spec.js": [
|
||||
"b0b2c48b418ebabf06c42d9a4216536484ae1c8f",
|
||||
"ba0d47228536da7192111f8bd7a6947de7c6181a",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/basic.spec.js": [
|
||||
|
@ -715782,87 +715908,91 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/compute/basic.spec.js": [
|
||||
"a001cbc0d82dc1388e875254d1eddd505ffc01f4",
|
||||
"8fcc7ef9309b5a8760247f0c86ea374c0d3f3e14",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/copies.spec.js": [
|
||||
"0055a58d115303f0dfdd79422babfede04efd3c3",
|
||||
"a93a1b2cbdf3e67724503f1a180cbdf45f5f5fc1",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/render/basic.spec.js": [
|
||||
"8f4d8c879da7b16f3fc162c697025c2fab4c6ff7",
|
||||
"89bbdd8a639891cade5dbf11f8cabb3020ab50d7",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/render/rendering.spec.js": [
|
||||
"c065ed23be4f21d3368742e0760f07cea2c6f6ff",
|
||||
"46829a8d07cc51a04ad1ec323fdaf6f5b14e6cdc",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/command_buffer/render/storeop.spec.js": [
|
||||
"da58ad2d8a571685134180199369244339d4a4a1",
|
||||
"0b38debc13425c87def0548f88085aa362a7a7cb",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/examples.spec.js": [
|
||||
"8a992a6239d78c1f45b2323d77690b8c5b4fab1f",
|
||||
"e57de1bfc8d9cf0c8d2264b77e68b56c6c2659f8",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/fences.spec.js": [
|
||||
"ccf513633daf307119ffcfc0eb3e81d27da3f9d3",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/format_info.js": [
|
||||
"d1b5b85530bdbd1af762083ad44314ecc7d36fc4",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/gpu_test.js": [
|
||||
"e437ee09449bae87f6b410c1643b8c23e628d703",
|
||||
"96f109d3043edf8f77d7cbfce88e13b348e44f58",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/index.js": [
|
||||
"b38ea11df28f63c6374d9b58df5c276d636b7b8d",
|
||||
"33934cdd38cb51c8a00dc72c436a14965ab7aa28",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createBindGroup.spec.js": [
|
||||
"24d29d0e61e653c34ebde4a35bb01717ee23ab9e",
|
||||
"4bc1d0877bab8087b3fa2bd25431b1b681ddef44",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createBindGroupLayout.spec.js": [
|
||||
"8e3bfc22572c6e8bbeab51c98520f1cfbb3633b2",
|
||||
"9ac11b49ba621ff076c0e0b94a868ec0b37e6d2e",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createPipelineLayout.spec.js": [
|
||||
"dc759750a986630dc87ea5136afffb4b3b5bd396",
|
||||
"b82229db3d9296f6dcadf70218d2143fccb8c8f6",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createRenderPipeline.spec.js": [
|
||||
"7cbe93dd9c958cc8331316a522846d126be89556",
|
||||
"cc838fc6515a5b9a7cc55bacc0361556a3bdd93c",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createTexture.spec.js": [
|
||||
"c99204b9667fbfa53d743eff285a4090abe70b07",
|
||||
"77f1c9709b6cddda912bacd988408671cb20e8bb",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/createView.spec.js": [
|
||||
"2330c6ecdd91abedde02e88391921586cfd40dec",
|
||||
"855d32a3f43990295513385ebbd161fa38d4f04a",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/error_scope.spec.js": [
|
||||
"2232db9b54e48426abf18f0d3c91f3c8901437de",
|
||||
"0ff9699a3ad3d8ef43176b3aeefb6c46d4796788",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/fences.spec.js": [
|
||||
"4aca3d7773afff6a801a705ca36fe675ee429588",
|
||||
"6c5c9f9faa14a0b9f3ee2ff5bf6dc52a9fd4e8e6",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/queue_submit.spec.js": [
|
||||
"50d912f4d6f2a3d53e072fae9b9930616e7ed1a7",
|
||||
"410e3c26e82b82637d45a2bb01e136130d82a6aa",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/render_pass.spec.js": [
|
||||
"f71a4a2b97420ab76ead6cadf29c31e3d440ce1a",
|
||||
"52da36fa7ac9cb196aaf578707acf09a7f62724d",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/render_pass_descriptor.spec.js": [
|
||||
"5a171879082762b039c1f21d18f7066b5c193078",
|
||||
"59caf533e6c3674b82ead7cd1e05048c4de3d308",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setBindGroup.spec.js": [
|
||||
"c669ea08d586b4911a74336314c72437aa2abec3",
|
||||
"73ae4ba502ea31e07fce16dc3b64766e43d53bfa",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setBlendColor.spec.js": [
|
||||
|
@ -715870,7 +716000,7 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setScissorRect.spec.js": [
|
||||
"ee1588d2a885bd2d0fc386737b3e37a5fc91dd7d",
|
||||
"aec75f536a1dca7c4448b6d901060735e7d86f6c",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setStencilReference.spec.js": [
|
||||
|
@ -715878,19 +716008,19 @@
|
|||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setVertexBuffer.spec.js": [
|
||||
"949dd91932d8d4e6b498f578e11d5c7c3fb019df",
|
||||
"1df40173abe0eab97fe384b12df94f0e4ec03c3b",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/setViewport.spec.js": [
|
||||
"5610930829e58862955ec7ba26e17d96ca5cb253",
|
||||
"715a236b18db388750f672d1caabf1466fe46611",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/validation_test.js": [
|
||||
"35ad5d895521f1207ab21be1de5af3a0d672cc4f",
|
||||
"099b8202204d06b41403410f287a770a0945559d",
|
||||
"support"
|
||||
],
|
||||
"webgpu/suites/cts/validation/vertex_input.spec.js": [
|
||||
"432a04a4ceef0e895e0bc881bf6d4f2ec7f91034",
|
||||
"951c9ead3cfc53569bbcfa322252edef3b672609",
|
||||
"support"
|
||||
],
|
||||
"webmessaging/Channel_postMessage_Blob.htm": [
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[transform-scale-hittest.html]
|
||||
[Hit test within unscaled box]
|
||||
expected: FAIL
|
||||
|
||||
[Hit test intersecting scaled box]
|
||||
expected: FAIL
|
||||
|
|
@ -6,9 +6,6 @@
|
|||
[rethrows errors when getting handleEvent]
|
||||
expected: TIMEOUT
|
||||
|
||||
[doesn't look up handleEvent method on callable event listeners]
|
||||
expected: FAIL
|
||||
|
||||
[throws if handleEvent is thruthy and not callable]
|
||||
expected: NOTRUN
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
[listeners are called when <iframe> is resized]
|
||||
expected: FAIL
|
||||
|
||||
[listener that was added twice is called only once]
|
||||
[listeners are called correct number of times]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[contenttype_txt.html]
|
||||
expected: CRASH
|
|
@ -318,18 +318,15 @@
|
|||
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html;" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/plain */*]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -53,6 +53,15 @@
|
|||
[combined text/javascript ]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript;charset=windows-1252 text/javascript]
|
||||
[separate text/javascript;charset=windows-1252 error text/javascript]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript x/x]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript error]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript ]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[script-resource-with-nonsniffable-types.tentative.sub.html]
|
||||
expected: TIMEOUT
|
||||
[CORB blocks 'multipart/byteranges']
|
||||
expected: FAIL
|
||||
|
||||
|
@ -17,3 +18,6 @@
|
|||
[CORB blocks 'application/x-gzip']
|
||||
expected: FAIL
|
||||
|
||||
[script-resource-with-nonsniffable-types]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[joint-session-history-remove-iframe.html]
|
||||
expected: CRASH
|
|
@ -1,4 +1,4 @@
|
|||
[traverse_the_history_2.html]
|
||||
[traverse_the_history_4.html]
|
||||
[Multiple history traversals, last would be aborted]
|
||||
expected: FAIL
|
||||
|
|
@ -1,24 +1,5 @@
|
|||
[open-features-negative-innerwidth-innerheight.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: negative values for legacy `innerwidth`, `innerheight`]
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=-404.5" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=-404.5" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=-404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerheight=-404e1" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerheight=-404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=-404e1" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,24 +1,5 @@
|
|||
[open-features-negative-width-height.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: negative values for `width`, `height`]
|
||||
expected: FAIL
|
||||
|
||||
[features "height=-404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "height=-404e1" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "height=-404.5" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=-404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=-404e1" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=-404.5" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,48 +1,32 @@
|
|||
[open-features-non-integer-height.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for feature `height`]
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405*3" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405.32" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405e1" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405/5" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405^4" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405.5" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405e-1" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405 " should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "height=405LLl" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "height=/404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[top=0,left=0,width=401,: absence of feature "height" should be treated same as "height=0"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[top=0,left=0: absence of feature "height" should be treated same as "height=0"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "height=_404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "height=L404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,42 +1,32 @@
|
|||
[open-features-non-integer-innerheight.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for legacy feature `innerheight`]
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405e-1" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405LLl" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405^4" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405e1" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405 " should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405/5" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405.32" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405.5" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerheight=405*3" should set "height=405"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerheight=_404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerheight=L404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerheight=/404" should NOT set "height=404"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,42 +1,32 @@
|
|||
[open-features-non-integer-innerwidth.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for legacy feature `innerwidth`]
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405e-1" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405*3" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405.5" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405e1" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405.32" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405 " should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405LLl" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405/5" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "innerwidth=405^4" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=/404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=_404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "innerwidth=L404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,42 +1,32 @@
|
|||
[open-features-non-integer-left.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for feature `left`]
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105e1" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105 " should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105/5" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105e-1" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105^4" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105LLl" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105.32" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105*3" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "left=105.5" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "left=L104" should NOT set "left=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "left=/104" should NOT set "left=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "left=_104" should NOT set "left=104"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
[open-features-non-integer-screenx.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for legacy feature `screenx`]
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105.5" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105e1" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105 " should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105*3" should set "left=105"]
|
||||
expected: FAIL
|
||||
|
@ -20,20 +19,14 @@
|
|||
expected: FAIL
|
||||
|
||||
[features "screenx=105^4" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105LLl" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105/5" should set "left=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=105.32" should set "left=105"]
|
||||
expected: FAIL
|
||||
|
||||
[features "screenx=L104" should NOT set "left=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "screenx=/104" should NOT set "left=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,42 +1,32 @@
|
|||
[open-features-non-integer-top.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for feature `top`]
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105/5" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105*3" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105LLl" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105e-1" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105.32" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105e1" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105 " should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105^4" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "top=105.5" should set "top=105"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "top=/104" should NOT set "top=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "top=_104" should NOT set "top=104"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "top=L104" should NOT set "top=104"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,48 +1,32 @@
|
|||
[open-features-non-integer-width.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[HTML: window.open `features`: non-integer values for feature `width`]
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405^4" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405.5" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405e1" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405 " should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405.32" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405LLl" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405*3" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405e-1" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
[features "width=405/5" should set "width=405"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[top=0,left=0: absence of feature "width" should be treated same as "width=0"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=_404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[top=0,left=0,height=401,: absence of feature "width" should be treated same as "width=0"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=/404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
|
||||
[features "width=L404" should NOT set "width=404"]
|
||||
expected: TIMEOUT
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[embedded-opener-remove-frame.html]
|
||||
expected: CRASH
|
||||
[opener and "removed" embedded documents]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
[supported-elements.html]
|
||||
expected: TIMEOUT
|
||||
[Contenteditable element should support autofocus]
|
||||
expected: FAIL
|
||||
|
||||
[Element with tabindex should support autofocus]
|
||||
expected: TIMEOUT
|
||||
|
||||
[Non-HTMLElement should not support autofocus]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
[non-active-document.html]
|
||||
[DOMParser]
|
||||
expected: FAIL
|
||||
|
||||
[createHTMLDocument]
|
||||
expected: FAIL
|
||||
|
||||
[<template>]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[DOMContentLoaded-defer.html]
|
||||
[The end: DOMContentLoaded and defer scripts]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
[import-in-moduleworker.html]
|
||||
expected: ERROR
|
||||
[Base URL in module dedicated workers: import]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
This directory contains the common infrastructure for the following tests.
|
||||
|
||||
|
||||
This directory contains the common infrastructure for the following tests (also referred below as projects).
|
||||
|
||||
- referrer-policy/
|
||||
- mixed-content/
|
||||
- upgrade-insecure-requests/
|
||||
|
||||
Subdirectories:
|
||||
|
||||
- `resources`:
|
||||
Serves JavaScript test helpers.
|
||||
- `subresource`:
|
||||
Serves subresources, with support for redirects, stash, etc.
|
||||
The subresource paths are managed by `subresourceMap` and
|
||||
|
@ -11,10 +17,183 @@ Subdirectories:
|
|||
- `scope`:
|
||||
Serves nested contexts, such as iframe documents or workers.
|
||||
Used from `invokeFrom*()` functions in `resources/common.js`.
|
||||
- `tools`:
|
||||
Scripts that generate test HTML files. Not used while running tests.
|
||||
- `/referrer-policy/generic/subresource-test`:
|
||||
Sanity checking tests for subresource invocation
|
||||
(This is still placed outside common/)
|
||||
|
||||
# spec.src.json format
|
||||
# Test generator
|
||||
|
||||
## Source Contexts
|
||||
The test generator (`common/security-features/tools`) generates test HTML files from templates and a seed (`spec.src.json`) that defines all the test scenarios.
|
||||
|
||||
The project (i.e. a WPT subdirectory, for example `referrer-policy/`) that uses the generator should define per-project data and invoke the common generator logic in `common/security-features/tools`.
|
||||
|
||||
This is the overview of the project structure:
|
||||
|
||||
```
|
||||
common/security-features/
|
||||
└── tools/ - the common test generator logic
|
||||
└── template/ - the test files templates
|
||||
project-directory/ (e.g. referrer-policy/)
|
||||
├── spec.src.json
|
||||
├── generic/
|
||||
│ ├── test-case.sub.js - Per-project test helper
|
||||
│ └── tools/
|
||||
│ └── generator.py - Per-project generator script
|
||||
└── gen/ - generated tests
|
||||
```
|
||||
|
||||
Invoking `project-directory/generic/tools/generate.py` will parse the spec JSON and determine which tests to generate (or skip) while using templates.
|
||||
|
||||
## Generating the tests
|
||||
|
||||
The repository already contains generated tests, so if you're making changes, see the [Removing all generated tests](#removing-all-generated-tests) section below, on how to remove them before you start generating tests which include your changes.
|
||||
|
||||
```bash
|
||||
# Chdir into the project directory.
|
||||
cd ~/web-platform-tests/project-directory
|
||||
|
||||
# Generate the test files under gen/ (HTMLs and .headers files).
|
||||
./generic/tools/generate.py
|
||||
|
||||
# Add all generated tests to the repo.
|
||||
git add gen/ && git commit -m "Add generated tests"
|
||||
```
|
||||
|
||||
During the generation, the spec is validated by ```common/security-features/tools/spec_validator.py```. This is specially important when you're making changes to `spec.src.json`. Make sure it's a valid JSON (no comments or trailing commas). The validator reports specific errors (missing keys etc.), if any.
|
||||
|
||||
### Removing all generated tests
|
||||
|
||||
Simply remove all files under `project-directory/gen/`.
|
||||
|
||||
```bash
|
||||
# Chdir into the project directory.
|
||||
cd ~/web-platform-tests/project-directory
|
||||
|
||||
# Remove all generated tests.
|
||||
rm -r gen/
|
||||
```
|
||||
|
||||
### Options for generating tests
|
||||
|
||||
Note: this section is currently obsolete. Only the release template is working.
|
||||
|
||||
The generator script ```./generic/tools/generate.py``` has two targets: ```release``` and ```debug```.
|
||||
|
||||
* Using **release** for the target will produce tests using a template for optimizing size and performance. The release template is intended for the official web-platform-tests and possibly other test suites. No sanity checking is done in release mode. Use this option whenever you're checking into web-platform-tests.
|
||||
|
||||
* When generating for ```debug```, the produced tests will contain more verbosity and sanity checks. Use this target to identify problems with the test suites when making changes locally. Make sure you don't check in tests generated with the debug target.
|
||||
|
||||
Note that **release** is the default target when invoking ```generate.py```.
|
||||
|
||||
|
||||
## Updating the tests
|
||||
|
||||
The main test logic lives in ```project-directory/generic/test-case.sub.js``` with helper functions defined in ```/common/security-features/resources/common.js``` so you should probably start there.
|
||||
|
||||
For updating the test suites you will most likely do **a subset** of the following:
|
||||
|
||||
* Add a new subresource type:
|
||||
|
||||
* Add a new sub-resource python script to `/common/security-features/subresource/`.
|
||||
* Add a sanity check test for a sub-resource to `referrer-policy/generic/subresource-test/`.
|
||||
* Add a new entry to `subresourceMap` in `/common/security-features/resources/common.js`.
|
||||
* Add a new entry to `valid_subresource_names` in `/common/security-features/tools/spec_validator.py`.
|
||||
* Add a new entry to `subresource_schema` in `spec.src.json`.
|
||||
* Update `source_context_schema` to specify in which source context the subresource can be used.
|
||||
|
||||
* Add a new subresource redirection type
|
||||
|
||||
* TODO: to be documented. Example: [https://github.com/web-platform-tests/wpt/pull/18939](https://github.com/web-platform-tests/wpt/pull/18939)
|
||||
|
||||
* Add a new subresource origin type
|
||||
|
||||
* TODO: to be documented. Example: [https://github.com/web-platform-tests/wpt/pull/18940](https://github.com/web-platform-tests/wpt/pull/18940)
|
||||
|
||||
* Add a new source context (e.g. "module sharedworker global scope")
|
||||
|
||||
* TODO: to be documented. Example: [https://github.com/web-platform-tests/wpt/pull/18904](https://github.com/web-platform-tests/wpt/pull/18904)
|
||||
|
||||
* Add a new source context list (e.g. "subresource request from a dedicated worker in a `<iframe srcdoc>`")
|
||||
|
||||
* TODO: to be documented.
|
||||
|
||||
* Implement new or update existing assertions in ```project-directory/generic/test-case.sub.js```.
|
||||
|
||||
* Exclude or add some tests by updating ```spec.src.json``` test expansions.
|
||||
|
||||
* Implement a new delivery method.
|
||||
|
||||
* TODO: to be documented. Currently the support for delivery methods are implemented in many places across `common/security-features/`.
|
||||
|
||||
* Regenerate the tests and MANIFEST.json
|
||||
|
||||
|
||||
## The spec JSON format
|
||||
|
||||
For examples of spec JSON files, see [referrer-policy/spec.src.json](../../referrer-policy/spec.src.json) or [mixed-content/spec.src.json](../../mixed-content/spec.src.json).
|
||||
|
||||
### Main sections
|
||||
|
||||
* **`specification`**
|
||||
|
||||
Top level requirements with description fields and a ```test_expansion``` rule.
|
||||
This is closely mimicking the [Referrer Policy specification](http://w3c.github.io/webappsec/specs/referrer-policy/) structure.
|
||||
|
||||
* **`excluded_tests`**
|
||||
|
||||
List of ```test_expansion``` patterns expanding into selections which get skipped when generating the tests (aka. blacklisting/suppressing)
|
||||
|
||||
* **`test_expansion_schema`**
|
||||
|
||||
Provides valid values for each field.
|
||||
Each test expansion can only contain fields and values defined by this schema (or `"*"` values that indicate all the valid values defined this schema).
|
||||
|
||||
* **`subresource_schema`**
|
||||
|
||||
Provides metadata of subresources, e.g. supported delivery types for each subresource.
|
||||
|
||||
* **`source_context_schema`**
|
||||
|
||||
Provides metadata of each single source context, e.g. supported delivery types and subresources that can be sent from the context.
|
||||
|
||||
* **`source_context_list_schema`**
|
||||
|
||||
Provides possible nested combinations of source contexts. See [Source Contexts](#source-contexts) section below for details.
|
||||
|
||||
### Test Expansion Patterns
|
||||
|
||||
Each field in a test expansion can be in one of the following formats:
|
||||
|
||||
* Single match: ```"value"```
|
||||
|
||||
* Match any of: ```["value1", "value2", ...]```
|
||||
|
||||
* Match all: ```"*"```
|
||||
|
||||
|
||||
**NOTE:** An expansion is always constructive (inclusive), there isn't a negation operator for explicit exclusion. Be aware that using an empty list ```[]``` matches (expands into) exactly nothing. Tests which are to be excluded should be defined in the ```excluded_tests``` section instead.
|
||||
|
||||
A single test expansion pattern, be it a requirement or a suppressed pattern, gets expanded into a list of **selections** as follows:
|
||||
|
||||
* Expand each field's pattern (single, any of, or all) to list of allowed values (defined by the ```test_expansion_schema```)
|
||||
|
||||
* Permute - Recursively enumerate all **selections** across all fields
|
||||
|
||||
Be aware that if there is more than one pattern expanding into a same selection, the pattern appearing later in the spec JSON will overwrite a previously generated selection. To make sure this is not undetected when generating, set the value of the ```expansion``` field to ```default``` for an expansion appearing earlier and ```override``` for the one appearing later.
|
||||
|
||||
A **selection** is a single **test instance** (scenario) with explicit values that defines a single test. The scenario is then evaluated by the ```TestCase``` in JS. For the rest of the arranging part, examine ```/common/security-features/tools/generate.py``` to see how the values for the templates are produced.
|
||||
|
||||
|
||||
Taking the spec JSON, the generator follows this algorithm:
|
||||
|
||||
* Expand all ```excluded_tests``` to create a blacklist of selections
|
||||
|
||||
* For each specification requirement: Expand the ```test_expansion``` pattern into selections and check each against the blacklist, if not marked as suppresed, generate the test resources for the selection
|
||||
|
||||
|
||||
### Source Contexts
|
||||
|
||||
In **`source_context_list_schema`**, we can specify
|
||||
|
||||
|
@ -41,7 +220,7 @@ The keys of `source_context_list_schema` can be used as the values of
|
|||
`source_context_list` fields, to indicate which source context configuration
|
||||
to be used.
|
||||
|
||||
## PolicyDelivery placeholders
|
||||
### PolicyDelivery placeholders
|
||||
|
||||
Each test contains
|
||||
|
||||
|
@ -67,27 +246,51 @@ The following placeholder strings in `source_context_list_schema` can be used:
|
|||
the target policy delivery.
|
||||
|
||||
For example, when the target policy delivery is
|
||||
{deliveryType: "http-rp", key: "referrerPolicy", value: "no-referrer"},
|
||||
`{deliveryType: "http-rp", key: "referrerPolicy", value: "no-referrer"}`,
|
||||
|
||||
"sourceContextList": [
|
||||
{"sourceContextType": "top", "policyDeliveries": ["anotherPolicy"]},
|
||||
{"sourceContextType": "classic-worker", "policyDeliveries": ["policy"]}
|
||||
```json
|
||||
"sourceContextList": [
|
||||
{
|
||||
"sourceContextType": "top",
|
||||
"policyDeliveries": [
|
||||
"anotherPolicy"
|
||||
]
|
||||
},
|
||||
{
|
||||
"sourceContextType": "classic-worker",
|
||||
"policyDeliveries": [
|
||||
"policy"
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
is replaced with
|
||||
|
||||
"sourceContextList": [
|
||||
{"sourceContextType": "top", "policyDeliveries": [
|
||||
{"deliveryType": "meta",
|
||||
```json
|
||||
"sourceContextList": [
|
||||
{
|
||||
"sourceContextType": "top",
|
||||
"policyDeliveries": [
|
||||
{
|
||||
"deliveryType": "meta",
|
||||
"key": "referrerPolicy",
|
||||
"value": "unsafe-url"}]
|
||||
},
|
||||
{"sourceContextType": "classic-worker", "policyDeliveries": [
|
||||
{"deliveryType": "http-rp",
|
||||
"key": "referrerPolicy",
|
||||
"value": "no-referrer"}]
|
||||
"value": "unsafe-url"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sourceContextType": "classic-worker",
|
||||
"policyDeliveries": [
|
||||
{
|
||||
"deliveryType": "http-rp",
|
||||
"key": "referrerPolicy",
|
||||
"value": "no-referrer"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
which indicates
|
||||
|
||||
|
@ -95,7 +298,7 @@ which indicates
|
|||
- The classic worker is created with
|
||||
`Referrer-Policy: no-referrer` HTTP response headers.
|
||||
|
||||
## `source_context_schema` and `subresource_schema`
|
||||
### `source_context_schema` and `subresource_schema`
|
||||
|
||||
These represent supported delivery types and subresources
|
||||
for each source context or subresource type. These are used
|
||||
|
|
|
@ -165,22 +165,14 @@ def generate_selection(spec_json, config, selection, spec,
|
|||
['supported_delivery_type'][selection['subresource']])
|
||||
|
||||
# We process the top source context below, and do not include it in
|
||||
# `test_parameters` in JavaScript.
|
||||
# `scenario` field in JavaScript.
|
||||
top_source_context = selection['source_context_list'].pop(0)
|
||||
assert (top_source_context.source_context_type == 'top')
|
||||
|
||||
test_parameters = dump_test_parameters(selection)
|
||||
# Adjust the template for the test invoking JS. Indent it to look nice.
|
||||
indent = "\n" + " " * 8
|
||||
test_parameters = test_parameters.replace("\n", indent)
|
||||
|
||||
selection['test_js'] = '''
|
||||
%s(
|
||||
%s,
|
||||
document.querySelector("meta[name=assert]").content,
|
||||
new SanityChecker()
|
||||
).start();
|
||||
''' % (config.test_case_name, test_parameters)
|
||||
selection['scenario'] = dump_test_parameters(selection).replace(
|
||||
"\n", indent)
|
||||
|
||||
selection['spec_name'] = spec['name']
|
||||
selection[
|
||||
|
|
|
@ -18,7 +18,13 @@
|
|||
<script src="%(helper_js)s"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>%(test_js)s</script>
|
||||
<script>
|
||||
TestCase(
|
||||
%(scenario)s,
|
||||
document.querySelector("meta[name=assert]").content,
|
||||
new SanityChecker()
|
||||
).start();
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -14,7 +14,13 @@
|
|||
<script src="%(helper_js)s"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>%(test_js)s</script>
|
||||
<script>
|
||||
TestCase(
|
||||
%(scenario)s,
|
||||
document.querySelector("meta[name=assert]").content,
|
||||
new SanityChecker()
|
||||
).start();
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS basic box model: parsing min-height with invalid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-min-height">
|
||||
<meta name="assert" content="min-height supports only the grammar '[ [<length> | <percentage>] && [border-box | content-box]? ] | available | min-content | max-content | fit-content'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_invalid_value("min-height", "complex");
|
||||
test_invalid_value("min-height", "none");
|
||||
test_invalid_value("min-height", "none available");
|
||||
test_invalid_value("min-height", "max-content 10px");
|
||||
test_invalid_value("min-height", "20% available");
|
||||
|
||||
test_invalid_value("min-height", "-10px");
|
||||
test_invalid_value("min-height", "-20%");
|
||||
test_invalid_value("min-height", "60");
|
||||
test_invalid_value("min-height", "10px 20%");
|
||||
test_invalid_value("min-height", "content-box border-box");
|
||||
test_invalid_value("min-height", "10px border-box 20%");
|
||||
test_invalid_value("min-height", "content-box 20% border-box");
|
||||
|
||||
// The following is not yet rejected by browsers:
|
||||
test_invalid_value("min-height", "auto");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS basic box model: parsing min-height with valid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-min-height">
|
||||
<meta name="assert" content="min-height supports the full grammar '[ [<length> | <percentage>] && [border-box | content-box]? ] | available | min-content | max-content | fit-content'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("min-height", "10px");
|
||||
test_valid_value("min-height", "20%");
|
||||
test_valid_value("min-height", "calc(2em + 3ex)");
|
||||
|
||||
test_valid_value("min-height", "min-content");
|
||||
test_valid_value("min-height", "max-content");
|
||||
test_valid_value("min-height", "fit-content");
|
||||
|
||||
// The following are not yet supported by browsers:
|
||||
// test_valid_value("min-height", "available");
|
||||
// test_valid_value("min-height", "10px border-box");
|
||||
// test_valid_value("min-height", "content-box 20%", "20% content-box");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,33 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS basic box model: parsing min-width with invalid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-min-width">
|
||||
<meta name="assert" content="min-width supports only the grammar '[ [<length> | <percentage>] && [border-box | content-box]? ] | available | min-content | max-content | fit-content'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_invalid_value("min-width", "complex");
|
||||
test_invalid_value("min-width", "none");
|
||||
test_invalid_value("min-width", "none available");
|
||||
test_invalid_value("min-width", "max-content 10px");
|
||||
test_invalid_value("min-width", "20% available");
|
||||
|
||||
test_invalid_value("min-width", "-10px");
|
||||
test_invalid_value("min-width", "-20%");
|
||||
test_invalid_value("min-width", "60");
|
||||
test_invalid_value("min-width", "10px 20%");
|
||||
test_invalid_value("min-width", "content-box border-box");
|
||||
test_invalid_value("min-width", "10px border-box 20%");
|
||||
test_invalid_value("min-width", "content-box 20% border-box");
|
||||
|
||||
// The following is not yet rejected by browsers:
|
||||
test_invalid_value("min-width", "auto");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS basic box model: parsing min-width with valid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-min-width">
|
||||
<meta name="assert" content="min-width supports the full grammar '[ [<length> | <percentage>] && [border-box | content-box]? ] | available | min-content | max-content | fit-content'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("min-width", "10px");
|
||||
test_valid_value("min-width", "20%");
|
||||
test_valid_value("min-width", "calc(2em + 3ex)");
|
||||
|
||||
test_valid_value("min-width", "min-content");
|
||||
test_valid_value("min-width", "max-content");
|
||||
test_valid_value("min-width", "fit-content");
|
||||
|
||||
// The following are not yet supported by browsers:
|
||||
// test_valid_value("min-width", "available");
|
||||
// test_valid_value("min-width", "10px border-box");
|
||||
// test_valid_value("min-width", "content-box 20%", "20% content-box");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,3 @@
|
|||
<!doctype html>
|
||||
<p>You should see a 300x300px green square below and no crash.</p>
|
||||
<div style="width:300px;height:300px;background:green"></div>
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<title>CSS Images Test: repeating-radial-gradient with huge size crashes Chrome</title>
|
||||
<link rel="help" href="https://crbug.com/1009307">
|
||||
<link rel="match" href="infinite-radial-gradient-crash-ref.html">
|
||||
<style>
|
||||
#crash {
|
||||
background-image: repeating-radial-gradient(closest-corner circle at 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999%, green, green);
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
<p>You should see a 300x300px green square below and no crash.</p>
|
||||
<div id="crash"></div>
|
|
@ -12,10 +12,22 @@
|
|||
<body>
|
||||
<script>
|
||||
test_invalid_value("min-height", "none");
|
||||
test_invalid_value("min-height", "min-content max-content");
|
||||
test_invalid_value("min-height", "complex");
|
||||
|
||||
test_invalid_value("min-height", "-10%");
|
||||
test_invalid_value("min-height", "-0.5em");
|
||||
test_invalid_value("min-height", "60");
|
||||
|
||||
test_invalid_value("min-height", "10px 20%");
|
||||
test_invalid_value("min-height", "max-content 10px");
|
||||
test_invalid_value("min-height", "min-content max-content");
|
||||
|
||||
// The following were previously supported by a min-height definition in
|
||||
// https://drafts.csswg.org/css-box-3/
|
||||
test_invalid_value("min-height", "available");
|
||||
test_invalid_value("min-height", "10px border-box");
|
||||
test_invalid_value("min-height", "content-box 20%");
|
||||
test_invalid_value("min-height", "fit-content");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -12,10 +12,22 @@
|
|||
<body>
|
||||
<script>
|
||||
test_invalid_value("min-width", "none");
|
||||
test_invalid_value("min-width", "min-content max-content");
|
||||
test_invalid_value("min-width", "complex");
|
||||
|
||||
test_invalid_value("min-width", "-10%");
|
||||
test_invalid_value("min-width", "-0.5em");
|
||||
test_invalid_value("min-width", "60");
|
||||
|
||||
test_invalid_value("min-width", "10px 20%");
|
||||
test_invalid_value("min-width", "max-content 10px");
|
||||
test_invalid_value("min-width", "min-content max-content");
|
||||
|
||||
// The following were previously supported by a min-width definition in
|
||||
// https://drafts.csswg.org/css-box-3/
|
||||
test_invalid_value("min-width", "available");
|
||||
test_invalid_value("min-width", "10px border-box");
|
||||
test_invalid_value("min-width", "content-box 20%");
|
||||
test_invalid_value("min-width", "fit-content");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#propdef-scale">
|
||||
<link rel="help" href="http://www.w3.org/TR/cssom-view/#extensions-to-the-document-interface">
|
||||
<link rel="help" href="https://crbug.com/1015801">
|
||||
<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
#normal {
|
||||
width: 100px;
|
||||
height: 10px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
#scaled {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
transform: scaleX(100) scaleY(100);
|
||||
transform-origin: 0px 0px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
z-index: 1; /* Hit test #scaled before #normal */
|
||||
}
|
||||
</style>
|
||||
<div id=normal></div>
|
||||
<div id=scaled></div>
|
||||
<script>
|
||||
test(() => {
|
||||
const result = document.elementFromPoint(50, 9);
|
||||
assert_equals(result, document.getElementById('normal'));
|
||||
}, 'Hit test within unscaled box');
|
||||
|
||||
test(() => {
|
||||
const result = document.elementFromPoint(50, 9.1);
|
||||
assert_equals(result, document.getElementById('scaled'));
|
||||
}, 'Hit test intersecting scaled box');
|
||||
</script>
|
|
@ -1,7 +1,10 @@
|
|||
# Writing Tests
|
||||
|
||||
If you haven't already, it's strongly recommended to read
|
||||
the [introduction](../index) first, as it introduces the various test types.
|
||||
So you'd like to write new tests for WPT? Great! For starters, we recommend
|
||||
reading [the introduction](../index) to learn how the tests are organized and
|
||||
interpreted. You might already have an idea about what needs testing, but it's
|
||||
okay if you don't know where to begin. In either case, [the guide on making a
|
||||
testing plan](making-a-testing-plan) will help you decide what to write.
|
||||
|
||||
There's also a load of [general guidelines](general-guidelines) that apply to all tests.
|
||||
|
||||
|
@ -17,6 +20,7 @@ There's also a load of [general guidelines](general-guidelines) that apply to al
|
|||
file-names
|
||||
h2tests
|
||||
lint-tool
|
||||
making-a-testing-plan
|
||||
manual
|
||||
reftest-tutorial
|
||||
reftests
|
||||
|
|
|
@ -0,0 +1,535 @@
|
|||
# Making a Testing Plan
|
||||
|
||||
When contributing to a project as large and open-ended as WPT, it's easy to get
|
||||
lost in the details. It can be helpful to start by making a rough list of tests
|
||||
you intend to write. That plan will let you anticipate how much work will be
|
||||
involved, and it will help you stay focused once you begin.
|
||||
|
||||
Many people come to WPT with a general testing goal in mind:
|
||||
|
||||
- specification authors often want to test for new spec text
|
||||
- browser maintainers often want to test new features or fixes to existing
|
||||
features
|
||||
- web developers often want to test discrepancies between browsers on their web
|
||||
applications
|
||||
|
||||
(If you don't have any particular goal, we can help you get started. Check out
|
||||
[the issues labeled with `type:missing-coverage` on
|
||||
GitHub.com](https://github.com/web-platform-tests/wpt/labels/type%3Amissing-coverage).
|
||||
Leave a comment if you'd like to get started with one, and don't hesitate to
|
||||
ask clarifying questions!)
|
||||
|
||||
This guide will help you write a testing plan by:
|
||||
|
||||
1. showing you how to use the specifications to learn what kinds of tests will
|
||||
be most helpful
|
||||
2. developing your sense for what *doesn't* need to be tested
|
||||
3. demonstrating methods for figuring out which tests (if any) have already
|
||||
been written for WPT
|
||||
|
||||
The level of detail in useful testing plans can vary widely. From [a list of
|
||||
specific
|
||||
cases](https://github.com/web-platform-tests/wpt/issues/6980#issue-252255894),
|
||||
to [an outline of important coverage
|
||||
areas](https://github.com/web-platform-tests/wpt/issues/18549#issuecomment-522631537),
|
||||
to [an annotated version of the specification under
|
||||
test](https://rwaldron.github.io/webrtc-pc/), the appropriate fidelity depends
|
||||
on your needs, so you can be as precise as you feel is helpful.
|
||||
|
||||
## Understanding the "testing surface"
|
||||
|
||||
Web platform specifications are instructions about how a feature should work.
|
||||
They're critical for implementers to "build the right thing," but they are also
|
||||
important for anyone writing tests. We can use the same instructions to infer
|
||||
what kinds of tests would be likely to detect mistakes. Here are a few common
|
||||
patterns in specification text and the kind of tests they suggest.
|
||||
|
||||
### Input sources
|
||||
|
||||
Algorithms may accept input from many sources. Modifying the input is the most
|
||||
direct way we can influence the browser's behavior and verify that it matches
|
||||
the specifications. That's why it's helpful to be able to recognize different
|
||||
sources of input.
|
||||
|
||||
```eval_rst
|
||||
================ ==============================================================
|
||||
Type of feature Potential input sources
|
||||
================ ==============================================================
|
||||
JavaScript parameters, `context object <https://dom.spec.whatwg.org/#context-object>`_
|
||||
HTML element content, attributes, attribute values
|
||||
CSS selector strings, property values, markup
|
||||
================ ==============================================================
|
||||
```
|
||||
|
||||
Determine which input sources are relevant for your chosen feature, and build a
|
||||
list of values which seem worthwhile to test (keep reading for advice on
|
||||
identifying worthwhile values). For features that accept multiple sources of
|
||||
input, remember that the interaction between values can often produce
|
||||
interesting results. Every value you identify should go into your testing plan.
|
||||
|
||||
*Example:* This is the first step of the `Notification` constructor from [the
|
||||
Notifications standard](https://notifications.spec.whatwg.org/#constructors):
|
||||
|
||||
> The Notification(title, options) constructor, when invoked, must run these steps:
|
||||
>
|
||||
> 1. If the [current global
|
||||
> object](https://html.spec.whatwg.org/multipage/webappapis.html#current-global-object)
|
||||
> is a
|
||||
> [ServiceWorkerGlobalScope](https://w3c.github.io/ServiceWorker/#serviceworkerglobalscope)
|
||||
> object, then [throw](https://heycam.github.io/webidl/#dfn-throw) a
|
||||
> `TypeError` exception.
|
||||
> 2. Let *notification* be the result of [creating a
|
||||
> notification](https://notifications.spec.whatwg.org/#create-a-notification)
|
||||
> given *title* and *options*. Rethrow any exceptions.
|
||||
>
|
||||
> [...]
|
||||
|
||||
A thorough test suite for this constructor will include tests for the behavior
|
||||
of many different values of the *title* parameter and the *options* parameter.
|
||||
Choosing those values can be a challenge unto itself--see [Avoid Excessive
|
||||
Breadth](#avoid-excessive-breadth) for advice.
|
||||
|
||||
### Browser state
|
||||
|
||||
The state of the browser may also influence algorithm behavior. Examples
|
||||
include the current document, the dimensions of the viewport, and the entries
|
||||
in the browsing history. Just like with direct input, a thorough set of tests
|
||||
will likely need to control these values. Browser state is often more expensive
|
||||
to manipulate (whether in terms of code, execution time, or system resources),
|
||||
and you may want to design your tests to mitigate these costs (e.g. by writing
|
||||
many subtests from the same state).
|
||||
|
||||
You may not be able to control all relevant aspects of the browser's state.
|
||||
[The `type:untestable`
|
||||
label](https://github.com/web-platform-tests/wpt/issues?q=is%3Aopen+is%3Aissue+label%3Atype%3Auntestable)
|
||||
includes issues for web platform features which cannot be controlled in a
|
||||
cross-browser way. You should include tests like these in your plan both to
|
||||
communicate your intention and to remind you when/if testing solutions become
|
||||
available.
|
||||
|
||||
*Example:* In [the `Notification` constructor referenced
|
||||
above](https://notifications.spec.whatwg.org/#constructors), the type of "the
|
||||
current global object" is also a form of input. The test suite should include
|
||||
tests which execute with different types of global objects.
|
||||
|
||||
### Branches
|
||||
|
||||
When an algorithm branches based on some condition, that's an indication of an
|
||||
interesting behavior that might be missed. Your testing plan should have at
|
||||
least one test that verifies the behavior when the branch is taken and at least
|
||||
one more test that verifies the behavior when the branch is *not* taken.
|
||||
|
||||
*Example:* The following algorithm from [the HTML
|
||||
standard](https://html.spec.whatwg.org/) describes how the
|
||||
`localStorage.getItem` method works:
|
||||
|
||||
> The `getItem`(*key*) method must return the current value associated with the
|
||||
> given *key*. If the given *key* does not exist in the list associated with
|
||||
> the object then this method must return null.
|
||||
|
||||
This algorithm exhibits different behavior depending on whether or not an item
|
||||
exists at the provided key. To test this thoroughly, we would write two tests:
|
||||
one test would verify that `null` is returned when there is no item at the
|
||||
provided key, and the other test would verify that an item we previously stored
|
||||
was correctly retrieved when we called the method with its name.
|
||||
|
||||
### Sequence
|
||||
|
||||
Even without branching, the interplay between sequential algorithm steps can
|
||||
suggest interesting test cases. If two steps have observable side-effects, then
|
||||
it can be useful to verify they happen in the correct order.
|
||||
|
||||
Most of the time, step sequence is implicit in the nature of the
|
||||
algorithm--each step operates on the result of the step that precedes it, so
|
||||
verifying the end result implicitly verifies the sequence of the steps. But
|
||||
sometimes, the order of two steps isn't particularly relevant to the result of
|
||||
the overall algorithm. This makes it easier for implementations to diverge.
|
||||
|
||||
There are many common patterns where step sequence is observable but not
|
||||
necessarily inherent to the correctness of the algorithm:
|
||||
|
||||
- input validation (when an algorithm verifies that two or more input values
|
||||
satisfy some criteria)
|
||||
- event dispatch (when an algorithm
|
||||
[fires](https://dom.spec.whatwg.org/#concept-event-fire) two or more events)
|
||||
- object property access (when an algorithm retrieves two or more property
|
||||
values from an object provided as input)
|
||||
|
||||
*Example:* The following text is an abbreviated excerpt of the algorithm that
|
||||
runs during drag operations (from [the HTML
|
||||
specification](https://html.spec.whatwg.org/multipage/dnd.html#dnd)):
|
||||
|
||||
> [...]
|
||||
> 4. Otherwise, if the user ended the drag-and-drop operation (e.g. by
|
||||
> releasing the mouse button in a mouse-driven drag-and-drop interface), or
|
||||
> if the `drag` event was canceled, then this will be the last iteration.
|
||||
> Run the following steps, then stop the drag-and-drop operation:
|
||||
> 1. If the [current drag
|
||||
> operation](https://html.spec.whatwg.org/multipage/dnd.html#current-drag-operation)
|
||||
> is "`none`" (no drag operation) [...] Otherwise, the drag operation
|
||||
> might be a success; run these substeps:
|
||||
> 1. Let *dropped* be true.
|
||||
> 2. If the [current target
|
||||
> element](https://html.spec.whatwg.org/multipage/dnd.html#current-target-element)
|
||||
> is a DOM element, [fire a DND
|
||||
> event](https://html.spec.whatwg.org/multipage/dnd.html#fire-a-dnd-event)
|
||||
> named `drop` at it; otherwise, use platform-specific conventions for
|
||||
> indicating a drop.
|
||||
> 3. [...]
|
||||
> 2. [Fire a DND
|
||||
> event](https://html.spec.whatwg.org/multipage/dnd.html#fire-a-dnd-event)
|
||||
> named `dragend` at the [source
|
||||
> node](https://html.spec.whatwg.org/multipage/dnd.html#source-node).
|
||||
> 3. [...]
|
||||
|
||||
A thorough test suite will verify that the `drop` event is fired as specified,
|
||||
and it will also verify that the `dragend` event is fired as specified. An even
|
||||
better test suite will also verify that the `drop` event is fired *before* the
|
||||
`dragend` event.
|
||||
|
||||
In September of 2019, [Chromium accidentally changed the ordering of the `drop`
|
||||
and `dragend`
|
||||
events](https://bugs.chromium.org/p/chromium/issues/detail?id=1005747), and as
|
||||
a result, real web applications stopped functioning. If there had been a test
|
||||
for the sequence of these events, then this confusion would have been avoided.
|
||||
|
||||
When making your testing plan, be sure to look carefully for event dispatch and
|
||||
the other patterns listed above. They won't always be as clear as the "drag"
|
||||
example!
|
||||
|
||||
### Optional behavior
|
||||
|
||||
Specifications occasionally allow browsers discretion in how they implement
|
||||
certain features. These are described using [RFC
|
||||
2119](https://tools.ietf.org/html/rfc2119) terms like "MAY" and "OPTIONAL".
|
||||
Although browsers should not be penalized for deciding not to implement such
|
||||
behavior, WPT offers tests that verify the correctness of the browsers which
|
||||
do. Be sure to [label the test as optional according to WPT's
|
||||
conventions](file-names) so that people reviewing test results know how to
|
||||
interpret failures.
|
||||
|
||||
*Example:* The algorithm underpinning
|
||||
[`document.getElementsByTagName`](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByTagName)
|
||||
includes the following paragraph:
|
||||
|
||||
> When invoked with the same argument, and as long as *root*'s [node
|
||||
> document](https://dom.spec.whatwg.org/#concept-node-document)'s
|
||||
> [type](https://dom.spec.whatwg.org/#concept-document-type) has not changed,
|
||||
> the same [HTMLCollection](https://dom.spec.whatwg.org/#htmlcollection) object
|
||||
> may be returned as returned by an earlier call.
|
||||
|
||||
That statement uses the word "may," so even though it modifies the behavior of
|
||||
the preceding algorithm, it is strictly optional. The test we write for this
|
||||
should be designated accordingly.
|
||||
|
||||
It's important to read these sections carefully because the distinction between
|
||||
"mandatory" behavior and "optional" behavior can be nuanced. In this case, the
|
||||
optional behavior is never allowed if the document's type has changed. That
|
||||
makes for a mandatory test, one that verifies browsers don't return the same
|
||||
result when the document's type changes.
|
||||
|
||||
## Exercising Restraint
|
||||
|
||||
When writing conformance tests, choosing what *not* to test is sometimes just
|
||||
as hard as finding what needs testing.
|
||||
|
||||
### Don't dive too deep
|
||||
|
||||
Algorithms are composed of many other algorithms which themselves are defined
|
||||
in terms of still more algorithms. It can be intimidating to consider
|
||||
exhaustively testing one of those "nested" algorithms, especially when they are
|
||||
shared by many different APIs.
|
||||
|
||||
In general, you should plan to write "surface tests" for the nested algorithms.
|
||||
That means only verifying that they exhibit the basic behavior you are
|
||||
expecting.
|
||||
|
||||
It's definitely important to test exhaustively, but it's just as important to
|
||||
do so in a structured way. Reach out to the test suite's maintainers to learn
|
||||
if and how they have already tested those algorithms. In many cases, it's
|
||||
acceptable to test them in just one place (and maybe through a different API
|
||||
entirely), and rely only on surface-level testing everywhere else. While it's
|
||||
always possible for more tests to uncover new bugs, the chances may be slim.
|
||||
The time we spend writing tests is highly valuable, so we have to be efficient!
|
||||
|
||||
*Example:* The following algorithm from [the DOM
|
||||
standard](https://dom.spec.whatwg.org/) powers
|
||||
[`document.querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector):
|
||||
|
||||
> To **scope-match a selectors string** *selectors* against a *node*, run these
|
||||
> steps:
|
||||
>
|
||||
> 1. Let *s* be the result of [parse a
|
||||
> selector](https://drafts.csswg.org/selectors-4/#parse-a-selector)
|
||||
> *selectors*.
|
||||
> 2. If *s* is failure, then
|
||||
> [throw](https://heycam.github.io/webidl/#dfn-throw) a
|
||||
> "[`SyntaxError`](https://heycam.github.io/webidl/#syntaxerror)"
|
||||
> [DOMException](https://heycam.github.io/webidl/#idl-DOMException).
|
||||
> 3. Return the result of [match a selector against a
|
||||
> tree](https://drafts.csswg.org/selectors-4/#match-a-selector-against-a-tree)
|
||||
> with *s* and *node*'s
|
||||
> [root](https://dom.spec.whatwg.org/#concept-tree-root) using [scoping
|
||||
> root](https://drafts.csswg.org/selectors-4/#scoping-root) *node*.
|
||||
|
||||
As described earlier in this guide, we'd certainly want to test the branch
|
||||
regarding the parsing failure. However, there are many ways a string might fail
|
||||
to parse--should we verify them all in the tests for `document.querySelector`?
|
||||
What about `document.querySelectorAll`? Should we test them all there, too?
|
||||
|
||||
The answers depend on the current state of the test suite: whether or not tests
|
||||
for selector parsing exist and where they are located. That's why it's best to
|
||||
confer with the people who are maintaining the tests.
|
||||
|
||||
### Avoid excessive breadth
|
||||
|
||||
When the set of input values is finite, it can be tempting to test them all
|
||||
exhaustively. When the set is very large, test authors can reduce repetition by
|
||||
defining tests programmatically in loops.
|
||||
|
||||
Using advanced control flow techniques to dynamically generate tests can
|
||||
actually *reduce* test quality. It may obscure the intent of the tests since
|
||||
readers have to mentally "unwind" the iteration to determine what is actually
|
||||
being verified. The practice is more susceptible to bugs. These bugs may not be
|
||||
obvious--they may not cause failures, and they may exercise fewer cases than
|
||||
intended. Finally, tests authored using this approach often take a relatively
|
||||
long time to complete, and that puts a burden on people who collect test
|
||||
results in large numbers.
|
||||
|
||||
The severity of these drawbacks varies with the complexity of the generation
|
||||
logic. For example, it would be pronounced in a test which conditionally made
|
||||
different assertions within many nested loops. Conversely, the severity would
|
||||
be low in a test which only iterated over a list of values in order to make the
|
||||
same assertions about each. Recognizing when the benefits outweigh the risks
|
||||
requires discretion, so once you understand them, you should use your best
|
||||
judgement.
|
||||
|
||||
*Example:* We can see this consideration in the very first step of the
|
||||
`Response` constructor from [the Fetch
|
||||
standard](https://fetch.spec.whatwg.org/)
|
||||
|
||||
> The `Response`(*body*, *init*) constructor, when invoked, must run these
|
||||
> steps:
|
||||
>
|
||||
> 1. If *init*["`status`"] is not in the range `200` to `599`, inclusive, then
|
||||
> [throw](https://heycam.github.io/webidl/#dfn-throw) a `RangeError`.
|
||||
>
|
||||
> [...]
|
||||
|
||||
This function accepts exactly 400 values for the "status." With [WPT's
|
||||
testharness.js](./testharness), it's easy to dynamically create one test for
|
||||
each value. Unless we have reason to believe that a browser may exhibit
|
||||
drastically different behavior for any of those values (e.g. correctly
|
||||
accepting `546` but incorrectly rejecting `547`), then the complexity of
|
||||
testing those cases probably isn't warranted.
|
||||
|
||||
Instead, focus on writing declarative tests for specific values which are novel
|
||||
in the context of the algorithm. For ranges like in this example, testing the
|
||||
boundaries is a good idea. `200` and `599` should not produce an error while
|
||||
`199` and `600` should produce an error. Feel free to use what you know about
|
||||
the feature to choose additional values. In this case, HTTP response status
|
||||
codes are classified by the "hundred" order of magnitude, so we might also want
|
||||
to test a "3xx" value and a "4xx" value.
|
||||
|
||||
## Assessing coverage
|
||||
|
||||
It's very likely that WPT already has some tests for the feature (or at least
|
||||
the specification) that you're interesting in testing. In that case, you'll
|
||||
have to learn what's already been done before starting to write new tests.
|
||||
Understanding the design of existing tests will let you avoid duplicating
|
||||
effort, and it will also help you integrate your work more logically.
|
||||
|
||||
Even if the feature you're testing does *not* have any tests, you should still
|
||||
keep these guidelines in mind. Sooner or later, someone else will want to
|
||||
extend your work, so you ought to give them a good starting point!
|
||||
|
||||
### File names
|
||||
|
||||
The names of existing files and folders in the repository can help you find
|
||||
tests that are relevant to your work. [This page on the design of
|
||||
WPT](../test-suite-design) goes into detail about how files are generally laid
|
||||
out in the repository.
|
||||
|
||||
Generally speaking, every conformance tests is stored in a subdirectory
|
||||
dedicated to the specification it verifies. The structure of these
|
||||
subdirectories vary. Some organize tests in directories related to algorithms
|
||||
or behaviors. Others have a more "flat" layout, where all tests are listed
|
||||
together.
|
||||
|
||||
Whatever the case, test authors try to choose names that communicate the
|
||||
behavior under test, so you can use them to make an educated guess about where
|
||||
your tests should go.
|
||||
|
||||
*Example:* Imagine you wanted to write a test to verify that headers were made
|
||||
immutable by the `Request.error` method defined in [the Fetch
|
||||
standard](https://fetch.spec.whatwg.org). Here's the algorithm:
|
||||
|
||||
> The static error() method, when invoked, must run these steps:
|
||||
>
|
||||
> 1. Let *r* be a new [Response](https://fetch.spec.whatwg.org/#response)
|
||||
> object, whose
|
||||
> [response](https://fetch.spec.whatwg.org/#concept-response-response) is a
|
||||
> new [network error](https://fetch.spec.whatwg.org/#concept-network-error).
|
||||
> 2. Set *r*'s [headers](https://fetch.spec.whatwg.org/#response-headers) to a
|
||||
> new [Headers](https://fetch.spec.whatwg.org/#headers) object whose
|
||||
> [guard](https://fetch.spec.whatwg.org/#concept-headers-guard) is
|
||||
> "`immutable`".
|
||||
> 3. Return *r*.
|
||||
|
||||
In order to figure out where to write the test (and whether it's needed at
|
||||
all), you can review the contents of the `fetch/` directory in WPT. Here's how
|
||||
that looks on a UNIX-like command line:
|
||||
|
||||
$ ls fetch
|
||||
api/ data-urls/ range/
|
||||
content-encoding/ http-cache/ README.md
|
||||
content-length/ images/ redirect-navigate/
|
||||
content-type/ metadata/ security/
|
||||
corb/ META.yml stale-while-revalidate/
|
||||
cors-rfc1918/ nosniff/
|
||||
cross-origin-resource-policy/ origin/
|
||||
|
||||
This test is for a behavior directly exposed through the API, so we should look
|
||||
in the `api/` directory:
|
||||
|
||||
$ ls fetch/api
|
||||
abort/ cors/ headers/ policies/ request/ response/
|
||||
basic/ credentials/ idlharness.any.js redirect/ resources/
|
||||
|
||||
And since this is a static method on the `Response` constructor, we would
|
||||
expect the test to belong in the `response/` directory:
|
||||
|
||||
$ ls fetch/api/response
|
||||
multi-globals/ response-static-error.html
|
||||
response-cancel-stream.html response-static-redirect.html
|
||||
response-clone.html response-stream-disturbed-1.html
|
||||
response-consume-empty.html response-stream-disturbed-2.html
|
||||
response-consume.html response-stream-disturbed-3.html
|
||||
response-consume-stream.html response-stream-disturbed-4.html
|
||||
response-error-from-stream.html response-stream-disturbed-5.html
|
||||
response-error.html response-stream-disturbed-6.html
|
||||
response-from-stream.any.js response-stream-with-broken-then.any.js
|
||||
response-init-001.html response-trailer.html
|
||||
response-init-002.html
|
||||
|
||||
There seems to be a test file for the `error` method:
|
||||
`response-static-error.html`. We can open that to decide if the behavior is
|
||||
already covered. If not, then we know where to [write the
|
||||
test](https://github.com/web-platform-tests/wpt/pull/19601)!
|
||||
|
||||
### Failures on wpt.fyi
|
||||
|
||||
There are many behaviors that are difficult to describe in a succinct file
|
||||
name. That's commonly the case with low-level rendering details of CSS
|
||||
specifications. Test authors may resort to generic number-based naming schemes
|
||||
for their files, e.g. `feature-001.html`, `feature-002.html`, etc. This makes
|
||||
it difficult to determine if a test case exists judging only by the names of
|
||||
files.
|
||||
|
||||
If the behavior you want to test is demonstrated by some browsers but not by
|
||||
others, you may be able to use the *results* of the tests to locate the
|
||||
relevant test.
|
||||
|
||||
[wpt.fyi](https://wpt.fyi) is a website which publishes results of WPT in
|
||||
various browsers. Because most browsers pass most tests, the pass/fail
|
||||
characteristics of the behavior you're testing can help you filter through a
|
||||
large number of highly similar tests.
|
||||
|
||||
*Example:* Imagine you've found a bug in the way Safari renders the top CSS
|
||||
border of HTML tables. By searching through directory names and file names,
|
||||
you've determined the probable location for the test: the `css/CSS2/borders/`
|
||||
directory. However, there are *three hundred* files that begin with
|
||||
`border-top-`! None of the names mention the `<table>` element, so any one of
|
||||
the files may already be testing the case you found.
|
||||
|
||||
Luckily, you also know that Firefox and Chrome do not exhibit this bug. You
|
||||
could find such tests by visual inspection of the [wpt.fyi](https://wpt.fyi)
|
||||
results overview, but [the website's "search" feature includes operators that
|
||||
let you query for this information
|
||||
directly](https://github.com/web-platform-tests/wpt.fyi/blob/master/api/query/README.md).
|
||||
To find the tests which begin with `border-top-`, pass in Chrome, pass in
|
||||
Firefox, and fail in Safari, you could write [`border-top- chrome:pass
|
||||
firefox:pass
|
||||
safari:fail](https://wpt.fyi/results/?label=master&label=experimental&aligned&q=border-top-%20safari%3Afail%20firefox%3Apass%20chrome%3Apass).
|
||||
The results show only three such tests exist:
|
||||
|
||||
- `border-top-applies-to-005.xht`
|
||||
- `border-top-color-applies-to-005.xht`
|
||||
- `border-top-width-applies-to-005.xht`
|
||||
|
||||
These may not describe the behavior you're interested in testing; the only way
|
||||
to know for sure is to review their contents. However, this is a much more
|
||||
manageable set to work with!
|
||||
|
||||
### Querying file contents
|
||||
|
||||
Some web platform features are enabled with a predictable pattern. For example,
|
||||
HTML attributes follow a fairly consistent format. If you're interested in
|
||||
testing a feature like this, you may be able to learn where your tests belong
|
||||
by querying the contents of the files in WPT.
|
||||
|
||||
You may be able to perform such a search on the web. WPT is hosted on
|
||||
GitHub.com, and [GitHub offers some basic functionality for querying
|
||||
code](https://help.github.com/en/articles/about-searching-on-github). If your
|
||||
search criteria are short and distinctive (e.g. all files containing
|
||||
"querySelectorAll"), then this interface may be sufficient. However, more
|
||||
complicated criteria may require [regular
|
||||
expressions](https://www.regular-expressions.info/). For that, you can
|
||||
[download the WPT
|
||||
repository](https://web-platform-tests.org/writing-tests/github-intro.html) and
|
||||
use [git](https://git-scm.com) to perform more powerful searches.
|
||||
|
||||
The following table lists some common search criteria and examples of how they
|
||||
can be expressed using regular expressions:
|
||||
|
||||
```eval_rst
|
||||
================================= ================== ==========================
|
||||
Criteria Example match Example regular expression
|
||||
================================= ================== ==========================
|
||||
JavaScript identifier references ``obj.foo()`` ``\bfoo\b``
|
||||
JavaScript string literals ``x = "foo";`` ``(["'])foo\1``
|
||||
HTML tag names ``<foo attr>`` ``<foo(\s|>|$)``
|
||||
HTML attributes ``<div foo=3>`` ``<[a-zA-Z][^>]*\sfoo(\s|>|=|$)``
|
||||
CSS property name ``style="foo: 4"`` ``([{;=\"']|\s|^)foo\s+:``
|
||||
================================= ================== ==========================
|
||||
```
|
||||
|
||||
Bear in mind that searches like this are not necessarily exhaustive. Depending
|
||||
on the feature, it may be difficult (or even impossible) to write a query that
|
||||
correctly identifies all relevant tests. This strategy can give a helpful
|
||||
guide, but the results may not be conclusive.
|
||||
|
||||
*Example:* Imagine you're interested in testing how the `src` attribute of the
|
||||
`iframe` element works with `javascript:` URLs. Judging only from the names of
|
||||
directories, you've found a lot of potential locations for such a test. You
|
||||
also know many tests use `javascript:` URLs without describing that in their
|
||||
name. How can you find where to contribute new tests?
|
||||
|
||||
You can design a regular expression that matches many cases where a
|
||||
`javascript:` URL is assigned to the `src` property in HTML. You can use the
|
||||
`git grep` command to query the contents of the `html/` directory:
|
||||
|
||||
$ git grep -lE "src\s*=\s*[\"']?javascript:" html
|
||||
html/browsers/browsing-the-web/navigating-across-documents/javascript-url-query-fragment-components.html
|
||||
html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling.html
|
||||
html/dom/documents/dom-tree-accessors/Document.currentScript.html
|
||||
html/dom/self-origin.sub.html
|
||||
html/editing/dnd/target-origin/114-manual.html
|
||||
html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html
|
||||
html/semantics/scripting-1/the-script-element/execution-timing/040.html
|
||||
html/semantics/scripting-1/the-script-element/execution-timing/080.html
|
||||
html/semantics/scripting-1/the-script-element/execution-timing/108.html
|
||||
html/semantics/scripting-1/the-script-element/execution-timing/109.html
|
||||
html/webappapis/dynamic-markup-insertion/opening-the-input-stream/document-open-cancels-javascript-url-navigation.html
|
||||
|
||||
You will still have to review the contents to know which are relevant for your
|
||||
purposes (if any), but compared to the 5,000 files in the `html/` directory,
|
||||
this list is far more approachable!
|
||||
|
||||
## Writing the Tests
|
||||
|
||||
With a complete testing plan in hand, you now have a good idea of the scope of
|
||||
your work. It's finally time to write the tests! There's a lot to say about how
|
||||
this is done technically. To learn more, check out [the WPT "reftest"
|
||||
tutorial](./reftest-tutorial) and [the testharness.js
|
||||
tutorial](./testharness-tutorial).
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>This test validates element timing information for cross-origin redirect chain images.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/element-timing-helpers.js"></script>
|
||||
<script src=/common/get-host-info.sub.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
async_test(t => {
|
||||
if (!window.PerformanceElementTiming) {
|
||||
assert_unreached("PerformanceElementTiming is not implemented");
|
||||
}
|
||||
let destUrl = get_host_info().HTTP_REMOTE_ORIGIN
|
||||
+ '/resource-timing/resources/multi_redirect.py?';
|
||||
destUrl += 'page_origin=' + get_host_info().HTTP_ORIGIN;
|
||||
destUrl += '&cross_origin=' + get_host_info().HTTP_REMOTE_ORIGIN;
|
||||
destUrl += '&final_resource=' + '/images/blue.png';
|
||||
destUrl += '&timing_allow=1';
|
||||
destUrl += '&tao_steps=';
|
||||
for (let taoSteps=0; taoSteps < 4; taoSteps++) {
|
||||
const image = document.createElement('img');
|
||||
image.src = destUrl + taoSteps;
|
||||
image.setAttribute('elementtiming', taoSteps);
|
||||
image.setAttribute('id', 'id' + taoSteps)
|
||||
document.body.appendChild(image);
|
||||
}
|
||||
let numObserved = 0;
|
||||
let observedMap = [false, false, false, false];
|
||||
const beforeRender = performance.now();
|
||||
new PerformanceObserver(t.step_func(entries => {
|
||||
entries.getEntries().forEach(entry => {
|
||||
const taoSteps = entry.identifier;
|
||||
assert_false(observedMap[taoSteps], 'Should observe each image once');
|
||||
observedMap[taoSteps] = true;
|
||||
if (taoSteps !== '3') {
|
||||
assert_equals(entry.renderTime, 0,
|
||||
'renderTime should be 0 when there is ' + taoSteps + ' tao steps');
|
||||
}
|
||||
const bound = taoSteps === '3' ? beforeRender : 0;
|
||||
checkElement(entry, destUrl + taoSteps, taoSteps, 'id' + taoSteps, bound,
|
||||
document.getElementById(taoSteps));
|
||||
});
|
||||
numObserved += entries.getEntries().length;
|
||||
if (numObserved === 4)
|
||||
t.done();
|
||||
})).observe({type: 'element', buffered: true});
|
||||
}, 'Cross-origin image without TAO should not have its renderTime set, with full TAO it should.');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,24 +1,25 @@
|
|||
// Common checks between checkElement() and checkElementWithoutResourceTiming().
|
||||
function checkElementInternal(entry, expectedUrl, expectedIdentifier, expectedID, beforeRender,
|
||||
expectedElement) {
|
||||
assert_equals(entry.entryType, 'element');
|
||||
assert_equals(entry.url, expectedUrl);
|
||||
assert_equals(entry.identifier, expectedIdentifier);
|
||||
assert_equals(entry.entryType, 'element', 'entryType does not match');
|
||||
assert_equals(entry.url, expectedUrl, 'url does not match');
|
||||
assert_equals(entry.identifier, expectedIdentifier, 'identifier does not match');
|
||||
if (beforeRender != 0) {
|
||||
// In this case, renderTime is not 0.
|
||||
assert_equals(entry.startTime, entry.renderTime);
|
||||
assert_equals(entry.startTime, entry.renderTime, 'startTime should equal renderTime');
|
||||
} else {
|
||||
// In this case, renderTime is 0, so compare to loadTime.
|
||||
assert_equals(entry.startTime, entry.loadTime);
|
||||
assert_equals(entry.startTime, entry.loadTime, 'startTime should equal loadTime');
|
||||
}
|
||||
assert_equals(entry.duration, 0);
|
||||
assert_equals(entry.id, expectedID);
|
||||
assert_greater_than_equal(entry.renderTime, beforeRender);
|
||||
assert_greater_than_equal(performance.now(), entry.renderTime);
|
||||
assert_equals(entry.duration, 0, 'duration should be 0');
|
||||
assert_equals(entry.id, expectedID, 'id does not match');
|
||||
assert_greater_than_equal(entry.renderTime, beforeRender, 'renderTime greater than beforeRender');
|
||||
assert_greater_than_equal(performance.now(), entry.renderTime, 'renderTime bounded by now()');
|
||||
if (expectedElement !== null) {
|
||||
assert_equals(entry.element, expectedElement);
|
||||
assert_equals(entry.identifier, expectedElement.elementTiming);
|
||||
assert_equals(entry.id, expectedElement.id);
|
||||
assert_equals(entry.element, expectedElement, 'element does not match');
|
||||
assert_equals(entry.identifier, expectedElement.elementTiming,
|
||||
'identifier must be the elementtiming of the element');
|
||||
assert_equals(entry.id, expectedElement.id, 'id must be the id of the element');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
onload = function() {
|
||||
assert_equals(document.body.textContent, "PASS");
|
||||
done();
|
||||
|
|
|
@ -1 +1 @@
|
|||
Content-Length: 373
|
||||
Content-Length: 403
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<div id=log></div>
|
||||
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
window.has_executed_script = false;
|
||||
</script>
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<div id=log></div>
|
||||
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
window.has_executed_script = false;
|
||||
</script>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<script src="/common/utils.js"></script>
|
||||
<div id=log></div>
|
||||
<script>
|
||||
setup({allow_uncaught_exception : true});
|
||||
setup({allow_uncaught_exception : true, single_test : true});
|
||||
|
||||
function test(mime_type, is_blocking_expected) {
|
||||
var action = is_blocking_expected ? "blocks" : "does not block";
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
- fetch/nosniff/stylesheet.html
|
||||
-->
|
||||
<meta charset="utf-8">
|
||||
<title>CSS is not applied (because of nosniff + non-text/css headers)</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
|
@ -31,11 +32,11 @@ h1 { color: green; }
|
|||
</body>
|
||||
|
||||
<script>
|
||||
// Verify that CSS is not applied (because of nosniff + non-text/css headers).
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), external_color);
|
||||
done();
|
||||
test(() => {
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), external_color);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
as text/html (because even without CORB mislabeled CSS will be rejected).
|
||||
-->
|
||||
<meta charset="utf-8">
|
||||
<title>CSS is not applied (because of strict content-type enforcement for cross-origin stylesheets)</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
|
@ -25,12 +26,11 @@ h1 { color: green; }
|
|||
</body>
|
||||
|
||||
<script>
|
||||
// Verify that CSS is not applied (because of strict content-type enforcement
|
||||
// for cross-origin stylesheets).
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), external_color);
|
||||
done();
|
||||
test(() => {
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), external_color);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
2) starts with a JSON parser breaker (like )]}')
|
||||
-->
|
||||
<meta charset="utf-8">
|
||||
<title>CORB doesn't block a stylesheet that has a proper Content-Type and begins with a JSON parser breaker</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
|
@ -26,11 +27,12 @@ h1 { color: green; }
|
|||
</body>
|
||||
|
||||
<script>
|
||||
// Verify that CSS got applied / did not get blocked by CORB.
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), external_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), default_color);
|
||||
done();
|
||||
test(() => {
|
||||
// Verify that CSS got applied / did not get blocked by CORB.
|
||||
let style = getComputedStyle(document.getElementById('header'));
|
||||
const external_color = 'rgb(255, 0, 0)'; // red
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), external_color);
|
||||
assert_not_equals(style.getPropertyValue('color'), default_color);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
CORB-blocked response as a stylesheet.
|
||||
-->
|
||||
<meta charset="utf-8">
|
||||
<title>CSS is not applied (because of mismatched Content-Type header)</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
|
@ -32,9 +33,9 @@ h1 { color: green; }
|
|||
</body>
|
||||
|
||||
<script>
|
||||
// Verify that CSS is not applied (because of mismatched Content-Type header).
|
||||
var style = getComputedStyle(document.getElementById('header'));
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
done();
|
||||
test(() => {
|
||||
var style = getComputedStyle(document.getElementById('header'));
|
||||
const default_color = 'rgb(0, 128, 0)'; // green
|
||||
assert_equals(style.getPropertyValue('color'), default_color);
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/get-host-info.sub.js"></script>
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
var image = new Image();
|
||||
image.onload = function() {
|
||||
const canvas = document.createElement("canvas");
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
assert_equals(getComputedStyle(document.documentElement).color, "rgb(0, 255, 0)")
|
||||
done();
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(document.documentElement).color, "rgb(0, 255, 0)")
|
||||
});
|
||||
</script>
|
||||
<p>This should be green</p>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Uncaught exception following subtest</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(function() {});
|
||||
throw new Error("error outside any setup or test");
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Uncaught exception in single-page test</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
throw new Error("error outside any setup or test");
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Unhandled rejection following subtest</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
test(function() {});
|
||||
Promise.reject(new Error("error outside any setup or test"));
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>Unhandled rejection in single-page test</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
setup({ single_test: true });
|
||||
Promise.reject(new Error("error outside any setup or test"));
|
||||
</script>
|
|
@ -0,0 +1,6 @@
|
|||
[uncaught-exception-following-subtest.html]
|
||||
expected: ERROR
|
||||
|
||||
[Uncaught exception following subtest]
|
||||
expected: PASS
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[uncaught-exception-single-test.html]
|
||||
[Uncaught exception in single-page test]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
[unhandled-rejection-following-subtest.html]
|
||||
expected: ERROR
|
||||
|
||||
[Unhandled rejection following subtest]
|
||||
expected: PASS
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[unhandled-rejection-single-test.html]
|
||||
[Unhandled rejection in single-page test]
|
||||
expected: FAIL
|
||||
|
|
@ -9,9 +9,10 @@
|
|||
<input id="file_input" name="file_input" type="file">
|
||||
</form>
|
||||
<script>
|
||||
let form = document.getElementById("form");
|
||||
let input = document.getElementById("file_input");
|
||||
test_driver
|
||||
promise_test(() => {
|
||||
let form = document.getElementById("form");
|
||||
let input = document.getElementById("file_input");
|
||||
return test_driver
|
||||
.send_keys(input, "{{fs_path(file_upload_data.txt)}}")
|
||||
.then(() =>
|
||||
fetch("file_upload.py",
|
||||
|
@ -20,7 +21,6 @@ test_driver
|
|||
.then(response => response.text())
|
||||
.then(data => {
|
||||
assert_equals(data, "PASS");
|
||||
done();
|
||||
})
|
||||
.catch(() => assert_unreached("File upload failed"));
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -61,7 +61,6 @@ dictionary PublicKeyCredentialCreationOptions {
|
|||
|
||||
dictionary PublicKeyCredentialEntity {
|
||||
required DOMString name;
|
||||
USVString icon;
|
||||
};
|
||||
|
||||
dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
|
||||
|
|
4
tests/wpt/web-platform-tests/mixed-content/README.md
Normal file
4
tests/wpt/web-platform-tests/mixed-content/README.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Mixed-content Web Platform Tests
|
||||
|
||||
The subdirectory `gen/` is generated using the generator at `common/security-features`.
|
||||
See [common/security-features/README.md](../common/security-features/README.md) for how to generate tests.
|
|
@ -31,8 +31,6 @@ class MixedContentConfig(object):
|
|||
self.sanity_checker_js = '/mixed-content/generic/sanity-checker.js'
|
||||
self.spec_json_js = '/mixed-content/spec_json.js'
|
||||
|
||||
self.test_case_name = 'TestCase'
|
||||
|
||||
script_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
self.spec_directory = os.path.abspath(
|
||||
os.path.join(script_directory, '..', '..'))
|
||||
|
|
|
@ -2,239 +2,5 @@
|
|||
|
||||
The Referrer-Policy tests are designed for testing browser implementations and conformance to the [W3 Referrer-Policy Specification](http://w3c.github.io/webappsec/specs/referrer-policy/).
|
||||
|
||||
## Project structure
|
||||
|
||||
The project contains tools, templates and a seed (```spec.src.json```) for generating tests. The main assertion logic resides in JS files in the root of the ```./generic/``` directory.
|
||||
|
||||
This is the overview of the project structure:
|
||||
|
||||
```
|
||||
.
|
||||
└── generic
|
||||
├── subresource - documents being served as sub-resources (python scripts)
|
||||
├── subresource-test - sanity checking tests for resource invocation
|
||||
├── template - the test files template used for generating the tests
|
||||
└── tools - for generating and maintaining the test suite
|
||||
└── (genereated_tests_for_a_specification_1)
|
||||
└── (genereated_tests_for_a_specification_2)
|
||||
└── ...
|
||||
└── (genereated_tests_for_a_specification_N)
|
||||
```
|
||||
|
||||
## The spec JSON
|
||||
|
||||
The ```spec.src.json``` defines all the test scenarios for the referrer policy.
|
||||
|
||||
Invoking ```./generic/tools/generate.py``` will parse the spec JSON and determine which tests to generate (or skip) while using templates.
|
||||
|
||||
|
||||
The spec can be validated by running ```./generic/tools/spec_validator.py```. This is specially important when you're making changes to ```spec.src.json```. Make sure it's a valid JSON (no comments or trailing commas). The validator should be informative and very specific on any issues.
|
||||
|
||||
The ```spec.src.json``` file can be formatted by running ```../common/security-features/tools/format_spec_src_json.py```.
|
||||
|
||||
For details about the spec JSON, see **Overview of the spec JSON** below.
|
||||
|
||||
|
||||
## Generating and running the tests
|
||||
|
||||
The repository already contains generated tests, so if you're making changes,
|
||||
see the **Removing all generated tests** section below, on how to remove them before you start generating tests which include your changes.
|
||||
|
||||
Start from the command line:
|
||||
|
||||
```bash
|
||||
|
||||
# Chdir into the tests directory.
|
||||
cd ~/web-platform-tests/referrer-policy
|
||||
|
||||
# Generate the test resources.
|
||||
./generic/tools/generate.py
|
||||
|
||||
# Add all generated tests to the repo.
|
||||
git add * && git commit -m "Add generated tests"
|
||||
|
||||
# Regenerate the manifest.
|
||||
../wpt manifest
|
||||
|
||||
```
|
||||
|
||||
Navigate to [http://web-platform.test:8000/tools/runner/index.html](http://web-platform.test:8000/tools/runner/index.html).
|
||||
|
||||
Run tests under path: ```/referrer-policy```.
|
||||
|
||||
Click start.
|
||||
|
||||
|
||||
## Options for generating tests
|
||||
|
||||
The generator script ```./generic/tools/generate.py``` has two targets: ```release``` and ```debug```.
|
||||
|
||||
* Using **release** for the target will produce tests using a template for optimizing size and performance. The release template is intended for the official web-platform-tests and possibly other test suites. No sanity checking is done in release mode. Use this option whenever you're checking into web-platform-tests.
|
||||
|
||||
* When generating for ```debug```, the produced tests will contain more verbosity and sanity checks. Use this target to identify problems with the test suite when making changes locally. Make sure you don't check in tests generated with the debug target.
|
||||
|
||||
Note that **release** is the default target when invoking ```generate.py```.
|
||||
|
||||
|
||||
## Removing all generated tests
|
||||
|
||||
```bash
|
||||
# Chdir into the tests directory.
|
||||
cd ~/web-platform-tests/referrer-policy
|
||||
|
||||
# Remove all generated tests.
|
||||
./generic/tools/clean.py
|
||||
|
||||
# Remove all generated tests to the repo.
|
||||
git add * && git commit -m "Remove generated tests"
|
||||
|
||||
# Regenerate the manifest.
|
||||
../wpt manifest
|
||||
```
|
||||
|
||||
**Important:**
|
||||
The ```./generic/tools/clean.py``` utility will only work if there is a valid ```spec.src.json``` and previously generated directories match the specification requirement names. So make sure you run ```clean.py``` before you alter the specification section of the spec JSON.
|
||||
|
||||
|
||||
## Updating the tests
|
||||
|
||||
The main test logic lives in ```./generic/referrer-policy-test-case.sub.js``` with helper functions defined in ```./common/security-features/resources/common.js``` so you should probably start there.
|
||||
|
||||
For updating the test suite you will most likely do **a subset** of the following:
|
||||
|
||||
* Add a new sub-resource python script to ```./generic/subresource/```,
|
||||
and update the reference to it in ```spec.src.json```.
|
||||
|
||||
* Add a sanity check test for a sub-resource to ```./generic/subresource-test/```.
|
||||
|
||||
* Implement new or update existing assertions in ```./generic/referrer-policy-test-case.sub.js```.
|
||||
|
||||
* Exclude or add some tests by updating ```spec.src.json``` test expansions.
|
||||
|
||||
* Update the template files living in ```./generic/template/```.
|
||||
|
||||
* Implement a new delivery method via HTTP headers or as part of the test template in ```./generic/tools/generate.py```
|
||||
|
||||
* Update the spec schema by editing ```spec.src.json``` while updating the
|
||||
```./generic/tools/spec_validator.py``` and ```./generic/tools/generate.py```
|
||||
and making sure both still work after the change (by running them).
|
||||
|
||||
* Regenerate the tests and MANIFEST.json
|
||||
|
||||
|
||||
## Updating the spec and regenerating
|
||||
|
||||
When updating the ```spec.src.json```, e.g. by adding a test expansion pattern to the ```excluded_tests``` section or when removing an expansion in the ```specification``` section, make sure to remove all previously generated files which would still get picked up by ```MANIFEST.json``` in the web-platform-tests root. As long as you don't change the specification requirements' names or remove them, you can easily regenerate the tests via command line:
|
||||
|
||||
```bash
|
||||
|
||||
# Chdir into the tests directory.
|
||||
cd ~/web-platform-tests/referrer-policy
|
||||
|
||||
# Regenerate the test resources.
|
||||
./generic/tools/regenerate
|
||||
|
||||
# Add all the tests to the repo.
|
||||
git add * && git commit -m "Update generated tests"
|
||||
|
||||
# Regenerate the manifest.
|
||||
../wpt manifest
|
||||
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Overview of the spec JSON
|
||||
|
||||
**Main sections:**
|
||||
|
||||
* **specification**
|
||||
|
||||
Top level requirements with description fields and a ```test_expansion``` rule.
|
||||
This is closely mimicking the [Referrer Policy specification](http://w3c.github.io/webappsec/specs/referrer-policy/) structure.
|
||||
|
||||
* **excluded_tests**
|
||||
|
||||
List of ```test_expansion``` patterns expanding into selections which get skipped when generating the tests (aka. blacklisting/suppressing)
|
||||
|
||||
* **referrer_policy_schema**
|
||||
|
||||
The schema to validate fields which define the ```referrer_policy``` elsewhere in the JSON.
|
||||
A value for a referrer_policy can only be one specified in the referrer_policy_schema.
|
||||
|
||||
* **test_expansion_schema**
|
||||
|
||||
The schema used to check if a ```test_expansion``` is valid.
|
||||
Each test expansion can only contain fields defined by this schema.
|
||||
|
||||
### Test Expansion Patterns
|
||||
|
||||
Each field in a test expansion can be in one of the following formats:
|
||||
|
||||
* Single match: ```"value"```
|
||||
|
||||
* Match any of: ```["value1", "value2", ...]```
|
||||
|
||||
* Match all: ```"*"```
|
||||
|
||||
#### Example: test expansion in a requirement specification
|
||||
|
||||
The following example shows how to restrict the expansion of ```referrer_url``` to ```origin``` and allow rest of the arrangement to expand (permute) to all possible values. The name field will be the prefix of a generated HTML file name for the test.
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "origin-only",
|
||||
"title": "Referrer Policy is set to 'origin-only'",
|
||||
"description": "Check that all sub-resources in all cases get only the origin portion of the referrer URL.",
|
||||
"specification_url": "https://w3c.github.io/webappsec/specs/referrer-policy/#referrer-policy-state-origin",
|
||||
"referrer_policy": "origin",
|
||||
"test_expansion": [
|
||||
{
|
||||
"name": "generic",
|
||||
"expansion": "default",
|
||||
"source_protocol": "*",
|
||||
"target_protocol": "*",
|
||||
"delivery_method": "*",
|
||||
"redirection": "*",
|
||||
"origin": "*",
|
||||
"subresource": "*",
|
||||
"referrer_url": "origin"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**NOTE:** An expansion is always constructive (inclusive), there isn't a negation operator for explicit exclusion. Be aware that using an empty list ```[]``` matches (expands into) exactly nothing. Tests which are to be excluded should be defined in the ```excluded_tests``` section instead.
|
||||
|
||||
A single test expansion pattern, be it a requirement or a suppressed pattern, gets expanded into a list of **selections** as follows:
|
||||
|
||||
* Expand each field's pattern (single, any of, or all) to list of allowed values (defined by the ```test_expansion_schema```)
|
||||
|
||||
* Permute - Recursively enumerate all **selections** across all fields
|
||||
|
||||
Be aware that if there is more than one pattern expanding into a same selection (which also shares the same ```name``` field), the pattern appearing later in the spec JSON will overwrite a previously generated selection. To make sure this is not undetected when generating, set the value of the ```expansion``` field to ```default``` for an expansion appearing earlier and ```override``` for the one appearing later.
|
||||
|
||||
A **selection** is a single **test instance** (scenario) with explicit values, for example:
|
||||
|
||||
```javascript
|
||||
var scenario = {
|
||||
"referrer_policy": "origin-when-cross-origin",
|
||||
"delivery_method": "meta-referrer",
|
||||
"redirection": "no-redirect",
|
||||
"origin": "cross-origin",
|
||||
"source_protocol": "http",
|
||||
"target_protocol": "http",
|
||||
"subresource": "iframe-tag",
|
||||
"referrer_url": "origin"
|
||||
};
|
||||
```
|
||||
|
||||
Essentially, this is what gets generated and defines a single test. The scenario is then evaluated by the ```ReferrerPolicyTestCase``` in JS. For the rest of the arranging part, see the ```./generic/template/``` directory and examine ```./generic/tools/generate.py``` to see how the values for the templates are produced.
|
||||
|
||||
|
||||
Taking the spec JSON, the generator follows this algorithm:
|
||||
|
||||
* Expand all ```excluded_tests``` to create a blacklist of selections
|
||||
|
||||
* For each specification requirement: Expand the ```test_expansion``` pattern into selections and check each against the blacklist, if not marked as suppresed, generate the test resources for the selection
|
||||
|
||||
The subdirectory `gen/` is generated using the generator at `common/security-features`.
|
||||
See [common/security-features/README.md](../common/security-features/README.md) for how to generate tests.
|
||||
|
|
|
@ -31,8 +31,6 @@ class ReferrerPolicyConfig(object):
|
|||
self.sanity_checker_js = '/referrer-policy/generic/sanity-checker.js'
|
||||
self.spec_json_js = '/referrer-policy/spec_json.js'
|
||||
|
||||
self.test_case_name = 'TestCase'
|
||||
|
||||
script_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
self.spec_directory = os.path.abspath(
|
||||
os.path.join(script_directory, '..', '..'))
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
destUrl += 'page_origin=' + pageOrigin;
|
||||
destUrl += '&timing_allow=1';
|
||||
destUrl += '&cross_origin=' + crossOrigin;
|
||||
destUrl += '&final_resource=' + "/resource-timing/resources/blank-with-tao.html";
|
||||
destUrl += '&tao_steps=3';
|
||||
const frameContext = document.getElementById('frameContext');
|
||||
frameContext.onload = onload_test;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
let destUrl = pageOrigin + '/resource-timing/resources/multi_redirect.py?';
|
||||
destUrl += 'page_origin=' + pageOrigin;
|
||||
destUrl += '&cross_origin=' + crossOrigin;
|
||||
destUrl += '&final_resource=' + "/resource-timing/resources/blank-with-tao.html";
|
||||
const frameContext = document.getElementById('frameContext');
|
||||
frameContext.onload = onload_test;
|
||||
frameContext.src = destUrl;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
destUrl += 'page_origin=' + pageOrigin;
|
||||
destUrl += '&timing_allow=1';
|
||||
destUrl += '&cross_origin=' + crossOrigin;
|
||||
destUrl += '&final_resource=' + "/resource-timing/resources/blank-with-tao.html";
|
||||
destUrl += '&tao_steps=2';
|
||||
const frameContext = document.getElementById('frameContext');
|
||||
frameContext.onload = onload_test;
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
let destUrl = get_host_info().HTTP_REMOTE_ORIGIN + '/resource-timing/resources/multi_redirect.py?';
|
||||
destUrl += 'page_origin=' + 'http://' + document.location.host;
|
||||
destUrl += '&cross_origin=' + get_host_info().HTTP_REMOTE_ORIGIN;
|
||||
destUrl += '&final_resource=' + "/resource-timing/resources/blank-with-tao.html";
|
||||
destUrl += '&tao_steps=3';
|
||||
destUrl += '&timing_allow=1';
|
||||
const frameContext = document.getElementById('frameContext');
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
let destUrl = get_host_info().HTTP_REMOTE_ORIGIN + '/resource-timing/resources/multi_redirect.py?';
|
||||
destUrl += 'page_origin=' + 'http://' + document.location.host;
|
||||
destUrl += '&cross_origin=' + get_host_info().HTTP_REMOTE_ORIGIN;
|
||||
destUrl += '&final_resource=' + "/resource-timing/resources/blank-with-tao.html";
|
||||
const frameContext = document.getElementById('frameContext');
|
||||
frameContext.onload = onload_test;
|
||||
frameContext.src = destUrl;
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
def main(request, response):
|
||||
"""Handler that causes multiple redirections.
|
||||
The request has two mandatory and one optional query parameters:
|
||||
"""Handler that causes multiple redirections. Redirect chain is as follows:
|
||||
1. Initial URL containing multi-redirect.py
|
||||
2. Redirect to cross-origin URL
|
||||
3. Redirect to same-origin URL
|
||||
4. Final URL containing the final same-origin resource.
|
||||
The request has three mandatory and one optional query parameters:
|
||||
page_origin - The page origin, used for redirection and to set TAO. This is a mandatory parameter.
|
||||
cross_origin - The cross origin used to make this a cross-origin redirect. This is a mandatory parameter.
|
||||
final_resource - Path of the final resource, without origin. This is a mandatory parameter.
|
||||
timing_allow - Whether TAO should be set or not in the redirect chain. This is an optional parameter. Default: not set.
|
||||
Note that |step| is a parameter used internally for the multi-redirect. It's the step we're at in the redirect chain.
|
||||
"""
|
||||
|
@ -16,6 +21,7 @@ def main(request, response):
|
|||
origin = request.url_parts.scheme + "://" + request.url_parts.hostname + ":" + str(request.url_parts.port)
|
||||
page_origin = request.GET.first("page_origin")
|
||||
cross_origin = request.GET.first("cross_origin")
|
||||
final_resource = request.GET.first("final_resource")
|
||||
tao_steps = 0
|
||||
if "tao_steps" in request.GET:
|
||||
tao_steps = int(request.GET.first("tao_steps"))
|
||||
|
@ -27,6 +33,7 @@ def main(request, response):
|
|||
redirect_url_path = "/resource-timing/resources/multi_redirect.py?"
|
||||
redirect_url_path += "page_origin=" + page_origin
|
||||
redirect_url_path += "&cross_origin=" + cross_origin
|
||||
redirect_url_path += "&final_resource=" + final_resource
|
||||
redirect_url_path += "&timing_allow=" + timing_allow
|
||||
redirect_url_path += "&tao_steps=" + str(next_tao_steps)
|
||||
redirect_url_path += "&step="
|
||||
|
@ -41,7 +48,7 @@ def main(request, response):
|
|||
redirect_url = page_origin + redirect_url_path + "3"
|
||||
else:
|
||||
# On the third request, redirect to a static response
|
||||
redirect_url = page_origin + "/resource-timing/resources/blank-with-tao.html"
|
||||
redirect_url = page_origin + final_resource
|
||||
|
||||
response.status = 302
|
||||
response.headers.set("Location", redirect_url)
|
||||
|
|
|
@ -3,6 +3,37 @@ set -ex
|
|||
|
||||
SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
|
||||
WPT_ROOT=$SCRIPT_DIR/../..
|
||||
|
||||
EPOCHS=(
|
||||
epochs/three_hourly::3h
|
||||
epochs/six_hourly::6h
|
||||
epochs/twelve_hourly::12h
|
||||
epochs/daily::1d
|
||||
epochs/weekly::1w
|
||||
)
|
||||
|
||||
function get_epoch_branch_name () {
|
||||
echo ${1} | awk -F '::' '{print $1}'
|
||||
}
|
||||
|
||||
function get_epoch_timeval () {
|
||||
echo ${1} | awk -F '::' '{print $2}'
|
||||
}
|
||||
|
||||
main () {
|
||||
ALL_BRANCHES_NAMES=""
|
||||
for e in "${EPOCHS[@]}";
|
||||
do
|
||||
EPOCH=$(get_epoch_timeval ${e})
|
||||
EPOCH_BRANCH_NAME=$(get_epoch_branch_name ${e})
|
||||
git branch ${EPOCH_BRANCH_NAME} $(./wpt rev-list --epoch ${EPOCH})
|
||||
ALL_BRANCHES_NAMES="${ALL_BRANCHES_NAMES} ${EPOCH_BRANCH_NAME}"
|
||||
done
|
||||
# This is safe because `git push` will by default fail for a non-fast-forward
|
||||
# push, for example if the remote branch is ahead of the local branch.
|
||||
git push ${REMOTE} ${ALL_BRANCHES_NAMES}
|
||||
}
|
||||
|
||||
cd $WPT_ROOT
|
||||
|
||||
if [ -z "$GITHUB_TOKEN" ]; then
|
||||
|
@ -12,7 +43,4 @@ fi
|
|||
|
||||
REMOTE=https://x-access-token:$GITHUB_TOKEN@github.com/web-platform-tests/wpt.git
|
||||
|
||||
git branch epochs/three_hourly $(./wpt rev-list --epoch 3h)
|
||||
# This is safe because `git push` will by default fail for a non-fast-forward
|
||||
# push, for example if the remote branch is ahead of the local branch.
|
||||
git push $REMOTE epochs/three_hourly
|
||||
main
|
||||
|
|
|
@ -78,7 +78,7 @@ class ManifestItem(with_metaclass(ManifestItemMeta)):
|
|||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
return "<%s.%s id=%s, path=%s>" % (self.__module__, self.__class__.__name__, self.id, self.path)
|
||||
return "<%s.%s id=%r, path=%r>" % (self.__module__, self.__class__.__name__, self.id, self.path)
|
||||
|
||||
def to_json(self):
|
||||
# type: () -> Tuple[Any, ...]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
flake8==3.7.8
|
||||
flake8==3.7.9
|
||||
pycodestyle==2.5.0
|
||||
pyflakes==2.1.1
|
||||
pep8-naming==0.8.2
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
mypy==0.730
|
||||
mypy==0.740
|
||||
mypy-extensions==0.4.3
|
||||
typed-ast==1.4.0
|
||||
|
|
|
@ -50,18 +50,14 @@ def get_tagged_revisions(pattern):
|
|||
yield tag, commit, date
|
||||
|
||||
|
||||
def list_tagged_revisons(epoch, max_count):
|
||||
def get_epoch_revisions(epoch, until, max_count):
|
||||
# type: (**Any) -> List[Text]
|
||||
logger.debug("list_tagged_revisons(%s, %s)" % (epoch, max_count))
|
||||
logger.debug("get_epoch_revisions(%s, %s)" % (epoch, max_count))
|
||||
# Set an offset to start to count the the weekly epoch from
|
||||
# Monday 00:00:00. This is particularly important for the weekly epoch
|
||||
# because fix the start of the epoch to Monday. This offset is calculated
|
||||
# from Thursday, 1 January 1970 0:00:00 to Monday, 5 January 1970 0:00:00
|
||||
epoch_offset = 345600
|
||||
# "epoch_threshold" set a safety margin after this time it is fine to
|
||||
# consider that any tags are created and pushed.
|
||||
epoch_threshold = 600
|
||||
epoch_until = int(time.time()) - epoch_threshold
|
||||
count = 0
|
||||
|
||||
# Iterates the tagged revisions in descending order finding the more
|
||||
|
@ -84,12 +80,12 @@ def list_tagged_revisons(epoch, max_count):
|
|||
# now
|
||||
# Expected result: N,M,K,J,H,G,F,C,A
|
||||
|
||||
cutoff_date = calculate_cutoff_date(epoch_until, epoch, epoch_offset)
|
||||
cutoff_date = calculate_cutoff_date(until, epoch, epoch_offset)
|
||||
for _, commit, date in get_tagged_revisions("refs/tags/merge_pr_*"):
|
||||
if count >= max_count:
|
||||
return
|
||||
if date < cutoff_date:
|
||||
print(commit)
|
||||
yield commit
|
||||
count += 1
|
||||
cutoff_date = calculate_cutoff_date(date, epoch, epoch_offset)
|
||||
|
||||
|
@ -115,4 +111,9 @@ def get_parser():
|
|||
|
||||
def run_rev_list(**kwargs):
|
||||
# type: (**Any) -> None
|
||||
list_tagged_revisons(kwargs["epoch"], kwargs["max_count"])
|
||||
# "epoch_threshold" is a safety margin. After this time it is fine to
|
||||
# assume that any tags are created and pushed.
|
||||
epoch_threshold = 600
|
||||
until = int(time.time()) - epoch_threshold
|
||||
for line in get_epoch_revisions(kwargs["epoch"], until, kwargs["max_count"]):
|
||||
print(line)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import mock
|
||||
from tools.wpt import revlist
|
||||
|
||||
|
||||
|
@ -13,3 +14,150 @@ def test_parse_epoch():
|
|||
assert revlist.parse_epoch(b"10h") == 36000
|
||||
assert revlist.parse_epoch(b"10d") == 864000
|
||||
assert revlist.parse_epoch(b"10w") == 6048000
|
||||
|
||||
|
||||
@mock.patch('subprocess.check_output')
|
||||
def test_get_epoch_revisions(mocked_check_output):
|
||||
# check:
|
||||
#
|
||||
# * Several revisions in the same epoch offset (BC, DEF, HIJ, and LM)
|
||||
# * Revision with a timestamp exactly equal to the epoch boundary (H)
|
||||
# * Revision in non closed interval (O)
|
||||
#
|
||||
# mon tue wed thu fri sat sun mon thu wed
|
||||
# | | | | | | | | |
|
||||
# -A---B-C---DEF---G---H--IJ----------K-----L-M----N--O--
|
||||
# ^
|
||||
# until
|
||||
# max_count: 5; epoch: 1d
|
||||
# Expected result: N,M,K,J,G,F,C,A
|
||||
epoch = 86400
|
||||
until = 1188000 # Wednesday, 14 January 1970 18:00:00 UTC
|
||||
mocked_check_output.return_value = b'''
|
||||
merge_pr_O O 1166400 _wed_
|
||||
merge_pr_N N 1080000 _tue_
|
||||
merge_pr_M M 1015200 _mon_
|
||||
merge_pr_L L 993600 _mon_
|
||||
merge_pr_K K 907200 _sun_
|
||||
merge_pr_J J 734400 _fri_
|
||||
merge_pr_I I 712800 _fri_
|
||||
merge_pr_H H 691200 _fri_
|
||||
merge_pr_G G 648000 _thu_
|
||||
merge_pr_F F 583200 _wed_
|
||||
merge_pr_E E 561600 _wed_
|
||||
merge_pr_D D 540000 _wed_
|
||||
merge_pr_C C 475200 _tue_
|
||||
merge_pr_B B 453600 _tue_
|
||||
merge_pr_A A 388800 _mon_
|
||||
'''
|
||||
tagged_revisons = revlist.get_epoch_revisions(epoch, until, 8)
|
||||
assert tagged_revisons.next() == 'N'
|
||||
assert tagged_revisons.next() == 'M'
|
||||
assert tagged_revisons.next() == 'K'
|
||||
assert tagged_revisons.next() == 'J'
|
||||
assert tagged_revisons.next() == 'G'
|
||||
assert tagged_revisons.next() == 'F'
|
||||
assert tagged_revisons.next() == 'C'
|
||||
assert tagged_revisons.next() == 'A'
|
||||
assert len(list(tagged_revisons)) == 0 # generator exhausted
|
||||
|
||||
|
||||
# check: max_count with enough candidate items in the revision list
|
||||
#
|
||||
# mon tue wed thu fri sat sun mon
|
||||
# | | | | | | |
|
||||
# ------B-----C-----D----E-----F-----G------H---
|
||||
# ^
|
||||
# until
|
||||
# max_count: 5; epoch: 1d
|
||||
# Expected result: G,F,E,D,C
|
||||
epoch = 86400
|
||||
until = 1015200 # Monday, 12 January 1970 18:00:00 UTC
|
||||
mocked_check_output.return_value = b'''
|
||||
merge_pr_H H 993600 _mon_
|
||||
merge_pr_G G 907200 _sun_
|
||||
merge_pr_F F 820800 _sat_
|
||||
merge_pr_E E 734400 _fri_
|
||||
merge_pr_D D 648000 _thu_
|
||||
merge_pr_C C 561600 _wed_
|
||||
merge_pr_B B 475200 _thu_
|
||||
'''
|
||||
tagged_revisons = revlist.get_epoch_revisions(epoch, until, 5)
|
||||
assert tagged_revisons.next() == 'G'
|
||||
assert tagged_revisons.next() == 'F'
|
||||
assert tagged_revisons.next() == 'E'
|
||||
assert tagged_revisons.next() == 'D'
|
||||
assert tagged_revisons.next() == 'C'
|
||||
assert len(list(tagged_revisons)) == 0 # generator exhausted
|
||||
|
||||
|
||||
# check: max_count with less returned candidates items than the needed
|
||||
#
|
||||
# mon tue wed thu fri sat sun mon
|
||||
# | | | | | | |
|
||||
# -----------------------------F-----G------H---
|
||||
# ^
|
||||
# until
|
||||
# max_count: 5; epoch: 1d
|
||||
# Expected result: G,F
|
||||
epoch = 86400
|
||||
until = 1015200 # Monday, 12 January 1970 18:00:00 UTC
|
||||
mocked_check_output.return_value = b'''
|
||||
merge_pr_H H 993600 _mon_
|
||||
merge_pr_G G 907200 _sun_
|
||||
merge_pr_F F 820800 _sat_
|
||||
'''
|
||||
tagged_revisons = revlist.get_epoch_revisions(epoch, until, 5)
|
||||
assert tagged_revisons.next() == 'G'
|
||||
assert tagged_revisons.next() == 'F'
|
||||
assert len(list(tagged_revisons)) == 0 # generator exhausted
|
||||
|
||||
|
||||
# check: initial until value is on an epoch boundary
|
||||
#
|
||||
# sud mon tue wed thu
|
||||
# | | | |
|
||||
# -F-G-----------------H
|
||||
# ^
|
||||
# until
|
||||
# max_count: 3; epoch: 1d
|
||||
# Expected result: G,F
|
||||
# * H is skipped because because the epoch
|
||||
# interval is defined as an right-open interval
|
||||
# * G is included but in the Monday's interval
|
||||
# * F is included because it is the unique candidate
|
||||
# included in the Sunday's interval
|
||||
epoch = 86400
|
||||
until = 1296000 # Thursday, 15 January 1970 0:00:00 UTC
|
||||
mocked_check_output.return_value = b'''
|
||||
merge_pr_H H 1296000 _wed_
|
||||
merge_pr_G G 950400 _mon_
|
||||
merge_pr_F F 921600 _sud_
|
||||
'''
|
||||
tagged_revisons = revlist.get_epoch_revisions(epoch, until, 3)
|
||||
assert tagged_revisons.next() == 'G'
|
||||
assert tagged_revisons.next() == 'F'
|
||||
assert len(list(tagged_revisons)) == 0 # generator exhausted
|
||||
|
||||
|
||||
# check: until aligned with Monday, 5 January 1970 0:00:00 (345600)
|
||||
# not with Thursday, 1 January 1970 0:00:00 (0)
|
||||
#
|
||||
# sud mon tue wed thu
|
||||
# | | | |
|
||||
# -F-G--------------H---
|
||||
# ^
|
||||
# until
|
||||
# max_count: 1; epoch: 1w
|
||||
# Expected result: F
|
||||
epoch = 604800
|
||||
moday = 950400 # Monday, 12 January 1970 00:00:00 UTC
|
||||
until = moday + 345600 # 1296000. Thursday, 15 January 1970 0:00:00 UTC
|
||||
mocked_check_output.return_value = b'''
|
||||
merge_pr_H H 1180800 _wed_
|
||||
merge_pr_G G 950400 _mon_
|
||||
merge_pr_F F 921600 _sud_
|
||||
'''
|
||||
tagged_revisons = revlist.get_epoch_revisions(epoch, until, 1)
|
||||
assert tagged_revisons.next() == 'F'
|
||||
assert len(list(tagged_revisons)) == 0 # generator exhausted
|
||||
|
|
|
@ -39,7 +39,6 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
|
|||
executor_kwargs["supports_eager_pageload"] = False
|
||||
|
||||
capabilities = {
|
||||
"acceptInsecureCerts": True,
|
||||
"goog:chromeOptions": {
|
||||
"prefs": {
|
||||
"profile": {
|
||||
|
@ -62,7 +61,9 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
|
|||
chrome_options["binary"] = kwargs["binary"]
|
||||
|
||||
# Here we set a few Chrome flags that are always passed.
|
||||
chrome_options["args"] = []
|
||||
# ChromeDriver's "acceptInsecureCerts" capability only controls the current
|
||||
# browsing context, whereas the CLI flag works for workers, too.
|
||||
chrome_options["args"] = ["--ignore-certificate-errors"]
|
||||
# Allow audio autoplay without a user gesture.
|
||||
chrome_options["args"].append("--autoplay-policy=no-user-gesture-required")
|
||||
# Allow WebRTC tests to call getUserMedia.
|
||||
|
|
|
@ -179,18 +179,6 @@
|
|||
return p;
|
||||
}, "Trusted Type violation report: sample for script innerText assignment");
|
||||
|
||||
promise_test(t => {
|
||||
let p = Promise.resolve()
|
||||
.then(promise_violation("trusted-types one"))
|
||||
.then(expect_blocked_uri("trusted-types-sink"))
|
||||
.then(expect_sample("eval"))
|
||||
.then(expect_sample("2+2"))
|
||||
.then(promise_flush());
|
||||
expect_throws(_ => eval("2+2"));
|
||||
flush();
|
||||
return p;
|
||||
}, "Trusted Type violation report: sample for eval");
|
||||
|
||||
promise_test(t => {
|
||||
// We expect the sample string to always contain the name, and at least the
|
||||
// start of the value, but it should not be excessively long.
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Upgrade-insecure-requests Web Platform Tests
|
||||
|
||||
The subdirectory `gen/` is generated using the generator at `common/security-features`.
|
||||
See [common/security-features/README.md](../common/security-features/README.md) for how to generate tests.
|
|
@ -31,8 +31,6 @@ class UpgradeInsecureRequestsConfig(object):
|
|||
self.sanity_checker_js = '/upgrade-insecure-requests/generic/sanity-checker.js'
|
||||
self.spec_json_js = '/upgrade-insecure-requests/spec_json.js'
|
||||
|
||||
self.test_case_name = 'TestCase'
|
||||
|
||||
script_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
self.spec_directory = os.path.abspath(
|
||||
os.path.join(script_directory, '..', '..'))
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
assert_equals(message.records.length, 1, 'one text record');
|
||||
assert_equals(message.records[0].recordType, 'text', 'messageType');
|
||||
assert_equals(message.records[0].mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(message.records[0].encoding, 'utf-8', 'encoding');
|
||||
assert_equals(message.records[0].lang, 'en', 'lang');
|
||||
assert_true(message.records[0].data instanceof DataView,
|
||||
'data returns a DataView');
|
||||
const decoder = new TextDecoder();
|
||||
|
|
|
@ -47,6 +47,13 @@ const NDEFReaderOptionTests =
|
|||
unmatchedScanOptions: {recordType: "json"},
|
||||
message: createMessage([createUrlRecord(test_url_data)])
|
||||
},
|
||||
{
|
||||
desc: "Test that reading data succeed when NDEFScanOptions'" +
|
||||
" recordType is set to 'absolute-url'.",
|
||||
scanOptions: {recordType: "absolute-url"},
|
||||
unmatchedScanOptions: {recordType: "json"},
|
||||
message: createMessage([createUrlRecord(test_url_data, true)])
|
||||
},
|
||||
{
|
||||
desc: "Test that reading data succeed when NDEFScanOptions'" +
|
||||
" recordType is set to a custom type for external type records.",
|
||||
|
@ -109,6 +116,13 @@ const ReadMultiMessagesTests =
|
|||
message: createMessage([createUrlRecord(test_url_data)]),
|
||||
unmatchedMessage: createMessage([createTextRecord(test_text_data)])
|
||||
},
|
||||
{
|
||||
desc: "Test that filtering 'absolute-url' record from different messages" +
|
||||
" correctly with NDEFScanOptions' recordType is set to 'absolute-url'.",
|
||||
scanOptions: {recordType: "absolute-url"},
|
||||
message: createMessage([createUrlRecord(test_url_data, true)]),
|
||||
unmatchedMessage: createMessage([createTextRecord(test_text_data)])
|
||||
},
|
||||
{
|
||||
desc: "Test that filtering external record from different messages" +
|
||||
" correctly with NDEFScanOptions' recordType is set to the custom type.",
|
||||
|
|
|
@ -20,12 +20,70 @@
|
|||
const record = new NDEFRecord(createTextRecord(test_text_data));
|
||||
assert_equals(record.recordType, 'text', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(record.encoding, 'utf-8', 'encoding');
|
||||
assert_equals(record.lang, 'en', 'lang');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_text_data,
|
||||
'data has the same content with the original dictionary');
|
||||
assert_equals(record.text(), test_text_data,
|
||||
'text() has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with text record type');
|
||||
}, 'NDEFRecord constructor with text record type and string data');
|
||||
|
||||
test(() => {
|
||||
const encoder = new TextEncoder();
|
||||
const uint8Array = encoder.encode(test_text_data);
|
||||
const record = new NDEFRecord(createTextRecord(uint8Array.buffer));
|
||||
assert_equals(record.recordType, 'text', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(record.encoding, 'utf-8', 'encoding');
|
||||
assert_equals(record.lang, 'en', 'lang');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_text_data,
|
||||
'data has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with text record type and arrayBuffer data');
|
||||
|
||||
test(() => {
|
||||
const encoder = new TextEncoder();
|
||||
const uint8Array = encoder.encode(test_text_data);
|
||||
const record = new NDEFRecord(createTextRecord(uint8Array));
|
||||
assert_equals(record.recordType, 'text', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(record.encoding, 'utf-8', 'encoding');
|
||||
assert_equals(record.lang, 'en', 'lang');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_text_data,
|
||||
'data has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with text record type and arrayBufferView data');
|
||||
|
||||
test(() => {
|
||||
const encodings = ['utf-8', 'utf-16', 'utf-16be', 'utf-16le'];
|
||||
for (const encoding of encodings) {
|
||||
const lang = 'fr';
|
||||
const record = new NDEFRecord(createTextRecord(test_text_data, encoding, lang));
|
||||
assert_equals(record.recordType, 'text', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(record.encoding, encoding, 'encoding');
|
||||
assert_equals(record.lang, lang, 'lang');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_text_data,
|
||||
'data has the same content with the original dictionary');
|
||||
}
|
||||
}, 'NDEFRecord constructor with text record type, encoding, and lang');
|
||||
|
||||
test(t => {
|
||||
const previous_lang = document.querySelector('html').getAttribute('lang');
|
||||
const test_lang = 'fr';
|
||||
document.querySelector('html').setAttribute('lang', test_lang);
|
||||
t.add_cleanup(() => {
|
||||
document.querySelector('html').setAttribute('lang', previous_lang);
|
||||
});
|
||||
const record = new NDEFRecord(createTextRecord(test_text_data));
|
||||
assert_equals(record.recordType, 'text', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
assert_equals(record.encoding, 'utf-8', 'encoding');
|
||||
assert_equals(record.lang, test_lang, 'lang');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_text_data,
|
||||
'data has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with text record type and custom document language');
|
||||
|
||||
test(() => {
|
||||
const record = new NDEFRecord(createUrlRecord(test_url_data));
|
||||
|
@ -38,6 +96,17 @@
|
|||
'text() has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with url record type');
|
||||
|
||||
test(() => {
|
||||
const record = new NDEFRecord(createUrlRecord(test_url_data, true));
|
||||
assert_equals(record.recordType, 'absolute-url', 'recordType');
|
||||
assert_equals(record.mediaType, 'text/plain', 'mediaType');
|
||||
const decoder = new TextDecoder();
|
||||
assert_equals(decoder.decode(record.data), test_url_data,
|
||||
'data has the same content with the original dictionary');
|
||||
assert_equals(record.text(), test_url_data,
|
||||
'text() has the same content with the original dictionary');
|
||||
}, 'NDEFRecord constructor with absolute-url record type');
|
||||
|
||||
test(() => {
|
||||
let buffer = new ArrayBuffer(4);
|
||||
let buffer_view = new Uint8Array(buffer);
|
||||
|
|
|
@ -27,11 +27,18 @@ const invalid_type_messages =
|
|||
// NDEFRecord must have data.
|
||||
createMessage([createTextRecord()]),
|
||||
|
||||
// NDEFRecord.data for 'text' record must be a string.
|
||||
createMessage([createTextRecord(test_buffer_data)]),
|
||||
// NDEFRecord.data for 'text' record must be either a string,
|
||||
// an arrayBuffer, or an arrayBufferView.
|
||||
createMessage([createTextRecord(test_json_data)]),
|
||||
createMessage([createTextRecord(test_number_data)]),
|
||||
|
||||
// NDEFRecord.encoding for 'text' record must be either "utf-8",
|
||||
// "utf-16", "utf-16le" or "utf-16be".
|
||||
createMessage([createTextRecord(test_text_data, "chinese")]),
|
||||
|
||||
// NDEFRecord.lang length for 'text' record must be lower than 64.
|
||||
createMessage([createTextRecord(test_text_data, undefined /* encoding */, [...Array(64)].map(_ => 'a'))]),
|
||||
|
||||
// https://w3c.github.io/web-nfc/#dfn-map-a-json-object-to-ndef
|
||||
// NDEFRecord must have data.
|
||||
createMessage([createJsonRecord()]),
|
||||
|
@ -40,11 +47,20 @@ const invalid_type_messages =
|
|||
// NDEFRecord must have data.
|
||||
createMessage([createUrlRecord()]),
|
||||
|
||||
// https://w3c.github.io/web-nfc/#dfn-map-a-url-to-ndef
|
||||
// NDEFRecord must have data.
|
||||
createMessage([createUrlRecord(undefined, true)]),
|
||||
|
||||
// NDEFRecord.data for 'url' record must be string.
|
||||
createMessage([createUrlRecord(test_buffer_data)]),
|
||||
createMessage([createUrlRecord(test_number_data)]),
|
||||
createMessage([createUrlRecord(test_json_data)]),
|
||||
|
||||
// NDEFRecord.data for 'absolute-url' record must be string.
|
||||
createMessage([createUrlRecord(test_buffer_data, true)]),
|
||||
createMessage([createUrlRecord(test_number_data, true)]),
|
||||
createMessage([createUrlRecord(test_json_data, true)]),
|
||||
|
||||
// https://w3c.github.io/web-nfc/#dfn-map-binary-data-to-ndef
|
||||
// NDEFRecord must have data.
|
||||
createMessage([createOpaqueRecord()]),
|
||||
|
@ -75,8 +91,9 @@ const invalid_syntax_messages =
|
|||
createMessage([createRecord('text', 'application/json',
|
||||
test_text_data)]),
|
||||
|
||||
// Data for 'url' record, must be a valid URL.
|
||||
// Data for 'url' or 'absolute-url' record, must be a valid URL.
|
||||
createMessage([createUrlRecord('Invalid URL:// Data')]),
|
||||
createMessage([createUrlRecord('Invalid URL:// Data', true)]),
|
||||
|
||||
// A JSON MIME type is any MIME type whose subtype ends in "+json" or
|
||||
// whose essence is "application/json" or "text/json".
|
||||
|
@ -285,12 +302,13 @@ nfc_test(async (t, mockNFC) => {
|
|||
createJsonRecord(test_number_data),
|
||||
createOpaqueRecord(test_buffer_data),
|
||||
createUrlRecord(test_url_data),
|
||||
createUrlRecord(test_url_data, true),
|
||||
createRecord('w3.org:xyz', '', test_buffer_data)],
|
||||
test_message_origin);
|
||||
await writer.push(message);
|
||||
assertNDEFMessagesEqual(message, mockNFC.pushedMessage());
|
||||
}, "NDEFWriter.push NDEFMessage containing text, json, opaque, url and external records \
|
||||
with default NDEFPushOptions.");
|
||||
}, "NDEFWriter.push NDEFMessage containing text, json, opaque, url, absolute-url \
|
||||
and external records with default NDEFPushOptions.");
|
||||
|
||||
nfc_test(async (t, mockNFC) => {
|
||||
const writer = new NDEFWriter();
|
||||
|
@ -429,14 +447,6 @@ nfc_test(async (t, mockNFC) => {
|
|||
NDEFRecordInit.record's recordType is 'json' and NDEFRecordInit.record's \
|
||||
mediaType is undefined.");
|
||||
|
||||
nfc_test(async (t, mockNFC) => {
|
||||
const writer = new NDEFWriter();
|
||||
await writer.push({ records: [{ recordType: "url", data: test_url_data }] });
|
||||
const message = createMessage([createUrlRecord(test_url_data)]);
|
||||
assertNDEFMessagesEqual(message, mockNFC.pushedMessage());
|
||||
}, "Test that mediaType should be set to 'text/plain' if NDEFRecordInit.record's \
|
||||
recordType is 'url' and NDEFRecordInit.record's mediaType is undefined.");
|
||||
|
||||
nfc_test(async (t, mockNFC) => {
|
||||
const writer = new NDEFWriter();
|
||||
await writer.push({ records: [{ recordType: "w3.org:xyz", data: test_buffer_data }] });
|
||||
|
|
|
@ -84,19 +84,23 @@ function createMessage(records) {
|
|||
}
|
||||
}
|
||||
|
||||
function createRecord(recordType, mediaType, data) {
|
||||
function createRecord(recordType, mediaType, data, encoding, lang) {
|
||||
let record = {};
|
||||
if (recordType !== undefined)
|
||||
record.recordType = recordType;
|
||||
if (mediaType !== undefined)
|
||||
record.mediaType = mediaType;
|
||||
if (encoding !== undefined)
|
||||
record.encoding = encoding;
|
||||
if (lang !== undefined)
|
||||
record.lang = lang;
|
||||
if (data !== undefined)
|
||||
record.data = data;
|
||||
return record;
|
||||
}
|
||||
|
||||
function createTextRecord(text) {
|
||||
return createRecord('text', 'text/plain', text);
|
||||
function createTextRecord(data, encoding, lang) {
|
||||
return createRecord('text', 'text/plain', data, encoding, lang);
|
||||
}
|
||||
|
||||
function createJsonRecord(json) {
|
||||
|
@ -107,7 +111,10 @@ function createOpaqueRecord(buffer) {
|
|||
return createRecord('opaque', 'application/octet-stream', buffer);
|
||||
}
|
||||
|
||||
function createUrlRecord(url) {
|
||||
function createUrlRecord(url, isAbsUrl) {
|
||||
if (isAbsUrl) {
|
||||
return createRecord('absolute-url', 'text/plain', url);
|
||||
}
|
||||
return createRecord('url', 'text/plain', url);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ DEFAULT_CSS_STYLE = """
|
|||
</style>
|
||||
"""
|
||||
|
||||
DEFAULT_CONTENT = "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>"
|
||||
DEFAULT_CONTENT = "<div>Lorem ipsum dolor sit amet.</div>"
|
||||
|
||||
|
||||
def take_element_screenshot(session, element_id):
|
||||
|
|
|
@ -18,7 +18,7 @@ DEFAULT_CSS_STYLE = """
|
|||
</style>
|
||||
"""
|
||||
|
||||
DEFAULT_CONTENT = "<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>"
|
||||
DEFAULT_CONTENT = "<div>Lorem ipsum dolor sit amet.</div>"
|
||||
|
||||
|
||||
def take_screenshot(session):
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
**/
|
||||
|
||||
// It may be OK to add more allowed characters here.
|
||||
export const allowedTestNameCharacters = 'a-zA-Z0-9/_ ';
|
||||
export const allowedTestNameCharacters = 'a-zA-Z0-9/_';
|
||||
//# sourceMappingURL=allowed_characters.js.map
|
|
@ -3,7 +3,7 @@
|
|||
**/
|
||||
|
||||
export function attemptGarbageCollection() {
|
||||
const w = window;
|
||||
const w = self;
|
||||
|
||||
if (w.GCController) {
|
||||
w.GCController.collect();
|
||||
|
|
|
@ -13,6 +13,8 @@ export class Fixture {
|
|||
|
||||
_defineProperty(this, "rec", void 0);
|
||||
|
||||
_defineProperty(this, "eventualExpectations", []);
|
||||
|
||||
_defineProperty(this, "numOutstandingAsyncExpectations", 0);
|
||||
|
||||
this.rec = rec;
|
||||
|
@ -35,6 +37,8 @@ export class Fixture {
|
|||
if (this.numOutstandingAsyncExpectations !== 0) {
|
||||
throw new Error('there were outstanding asynchronous expectations (e.g. shouldReject) at the end of the test');
|
||||
}
|
||||
|
||||
await Promise.all(this.eventualExpectations);
|
||||
}
|
||||
|
||||
warn(msg) {
|
||||
|
@ -45,18 +49,19 @@ export class Fixture {
|
|||
this.rec.fail(msg);
|
||||
}
|
||||
|
||||
ok(msg) {
|
||||
const m = msg ? ': ' + msg : '';
|
||||
this.log('OK' + m);
|
||||
}
|
||||
|
||||
async asyncExpectation(fn) {
|
||||
async immediateAsyncExpectation(fn) {
|
||||
this.numOutstandingAsyncExpectations++;
|
||||
const ret = await fn();
|
||||
this.numOutstandingAsyncExpectations--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
eventualAsyncExpectation(fn) {
|
||||
const promise = fn();
|
||||
this.eventualExpectations.push(promise);
|
||||
return promise;
|
||||
}
|
||||
|
||||
expectErrorValue(expectedName, ex, m) {
|
||||
if (!(ex instanceof Error)) {
|
||||
this.fail('THREW NON-ERROR');
|
||||
|
@ -68,12 +73,12 @@ export class Fixture {
|
|||
if (actualName !== expectedName) {
|
||||
this.fail(`THREW ${actualName} INSTEAD OF ${expectedName}${m}`);
|
||||
} else {
|
||||
this.ok(`threw ${actualName}${m}`);
|
||||
this.debug(`OK: threw ${actualName}${m}`);
|
||||
}
|
||||
}
|
||||
|
||||
async shouldReject(expectedName, p, msg) {
|
||||
this.asyncExpectation(async () => {
|
||||
shouldReject(expectedName, p, msg) {
|
||||
this.eventualAsyncExpectation(async () => {
|
||||
const m = msg ? ': ' + msg : '';
|
||||
|
||||
try {
|
||||
|
@ -98,7 +103,8 @@ export class Fixture {
|
|||
|
||||
expect(cond, msg) {
|
||||
if (cond) {
|
||||
this.ok(msg);
|
||||
const m = msg ? ': ' + msg : '';
|
||||
this.debug('expect OK' + m);
|
||||
} else {
|
||||
this.rec.fail(msg);
|
||||
}
|
||||
|
|
|
@ -38,9 +38,7 @@ export class TestLoader {
|
|||
|
||||
|
||||
async loadTestsFromCmdLine(filters) {
|
||||
// In actual URL queries (?q=...), + represents a space. But decodeURIComponent doesn't do this,
|
||||
// so do it manually. (+ is used over %20 for readability.) (See also encodeSelectively.)
|
||||
return this.loadTests(filters.map(f => decodeURIComponent(f.replace(/\+/g, '%20'))));
|
||||
return this.loadTests(filters);
|
||||
}
|
||||
|
||||
async loadTests(filters) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
import { makeQueryString } from './url_query.js';
|
||||
import { extractPublicParams } from './url_query.js';
|
||||
import { getStackTrace, now } from './util/index.js';
|
||||
import { version } from './version.js';
|
||||
export class Logger {
|
||||
|
@ -39,7 +40,7 @@ export class TestSpecRecorder {
|
|||
record(test, params) {
|
||||
const result = {
|
||||
test,
|
||||
params,
|
||||
params: params ? extractPublicParams(params) : null,
|
||||
status: 'running',
|
||||
timems: -1
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ let _Symbol$iterator;
|
|||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
export function pcombine(params) {
|
||||
export function pcombine(...params) {
|
||||
return new PCombine(params);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
|
||||
**/
|
||||
|
||||
import { objectEquals } from '../util/index.js';
|
||||
export * from './combine.js';
|
||||
export * from './exclude.js';
|
||||
export * from './filter.js';
|
||||
export * from './options.js';
|
||||
export * from './exclude.js';
|
||||
export function paramsEquals(x, y) {
|
||||
if (x === y) {
|
||||
return true;
|
||||
|
@ -16,17 +17,17 @@ export function paramsEquals(x, y) {
|
|||
}
|
||||
|
||||
for (const xk of Object.keys(x)) {
|
||||
if (!y.hasOwnProperty(xk)) {
|
||||
if (x[xk] !== undefined && !y.hasOwnProperty(xk)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (x[xk] !== y[xk]) {
|
||||
if (!objectEquals(x[xk], y[xk])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const yk of Object.keys(y)) {
|
||||
if (!x.hasOwnProperty(yk)) {
|
||||
if (y[yk] !== undefined && !x.hasOwnProperty(yk)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|||
|
||||
import { allowedTestNameCharacters } from './allowed_characters.js';
|
||||
import { paramsEquals } from './params/index.js';
|
||||
import { checkPublicParamType, extractPublicParams } from './url_query.js';
|
||||
const validNames = new RegExp('^[' + allowedTestNameCharacters + ']+$');
|
||||
export class TestGroup {
|
||||
constructor(fixture) {
|
||||
|
@ -44,6 +45,12 @@ export class TestGroup {
|
|||
|
||||
|
||||
test(name, fn) {
|
||||
// Replace spaces with underscores for readability.
|
||||
if (name.indexOf('_') !== -1) {
|
||||
throw new Error('Invalid test name ${name}: contains underscore (use space)');
|
||||
}
|
||||
|
||||
name = name.replace(/ /g, '_');
|
||||
this.checkName(name);
|
||||
const test = new Test(name, this.fixture, fn);
|
||||
this.tests.push(test);
|
||||
|
@ -76,11 +83,18 @@ class Test {
|
|||
const seen = []; // This is n^2.
|
||||
|
||||
for (const spec of cases) {
|
||||
if (seen.some(x => paramsEquals(x, spec))) {
|
||||
const publicParams = extractPublicParams(spec); // Check type of public params: can only be (currently):
|
||||
// number, string, boolean, undefined, number[]
|
||||
|
||||
for (const v of Object.values(publicParams)) {
|
||||
checkPublicParamType(v);
|
||||
}
|
||||
|
||||
if (seen.some(x => paramsEquals(x, publicParams))) {
|
||||
throw new Error('Duplicate test case params');
|
||||
}
|
||||
|
||||
seen.push(spec);
|
||||
seen.push(publicParams);
|
||||
}
|
||||
|
||||
this.cases = cases;
|
||||
|
@ -88,27 +102,30 @@ class Test {
|
|||
|
||||
*iterate(rec) {
|
||||
for (const params of this.cases || [null]) {
|
||||
yield new RunCaseSpecific(rec, {
|
||||
test: this.name,
|
||||
params
|
||||
}, this.fixture, this.fn);
|
||||
yield new RunCaseSpecific(rec, this.name, params, this.fixture, this.fn);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RunCaseSpecific {
|
||||
constructor(recorder, id, fixture, fn) {
|
||||
constructor(recorder, test, params, fixture, fn) {
|
||||
_defineProperty(this, "id", void 0);
|
||||
|
||||
_defineProperty(this, "params", void 0);
|
||||
|
||||
_defineProperty(this, "recorder", void 0);
|
||||
|
||||
_defineProperty(this, "fixture", void 0);
|
||||
|
||||
_defineProperty(this, "fn", void 0);
|
||||
|
||||
this.id = {
|
||||
test,
|
||||
params: params ? extractPublicParams(params) : null
|
||||
};
|
||||
this.params = params;
|
||||
this.recorder = recorder;
|
||||
this.id = id;
|
||||
this.fixture = fixture;
|
||||
this.fn = fn;
|
||||
}
|
||||
|
@ -118,17 +135,32 @@ class RunCaseSpecific {
|
|||
rec.start(debug);
|
||||
|
||||
try {
|
||||
const inst = new this.fixture(rec, this.id.params || {});
|
||||
const inst = new this.fixture(rec, this.params || {});
|
||||
await inst.init();
|
||||
|
||||
try {
|
||||
await this.fn(inst);
|
||||
} catch (ex) {
|
||||
// There was an exception from the test itself.
|
||||
rec.threw(ex);
|
||||
} // Runs as long as constructor and init succeeded, even if the test rejected.
|
||||
|
||||
|
||||
await inst.finalize();
|
||||
} catch (e) {
|
||||
rec.threw(e);
|
||||
} catch (ex) {
|
||||
// There was an exception from constructor, init, or finalize.
|
||||
// (An error from finalize may have been an eventualAsyncExpectation failure.)
|
||||
rec.threw(ex);
|
||||
}
|
||||
|
||||
rec.finish();
|
||||
return res;
|
||||
}
|
||||
|
||||
injectResult(result) {
|
||||
const [, res] = this.recorder.record(this.id.test, this.id.params);
|
||||
Object.assign(res, result);
|
||||
}
|
||||
|
||||
}
|
||||
//# sourceMappingURL=test_group.js.map
|
90
tests/wpt/web-platform-tests/webgpu/framework/tree.js
Normal file
90
tests/wpt/web-platform-tests/webgpu/framework/tree.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* AUTO-GENERATED - DO NOT EDIT. Source: https://github.com/gpuweb/cts
|
||||
**/
|
||||
|
||||
// e.g. iteratePath('a/b/c/d', ':') yields ['a/', 'a/b/', 'a/b/c/', 'a/b/c/d:']
|
||||
function* iteratePath(path, terminator) {
|
||||
const parts = path.split('/');
|
||||
|
||||
if (parts.length > 1) {
|
||||
let partial = parts[0] + '/';
|
||||
yield partial;
|
||||
|
||||
for (let i = 1; i < parts.length - 1; ++i) {
|
||||
partial += parts[i] + '/';
|
||||
yield partial;
|
||||
} // Path ends in '/' (so is a README).
|
||||
|
||||
|
||||
if (parts[parts.length - 1] === '') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
yield path + terminator;
|
||||
}
|
||||
|
||||
export function treeFromFilterResults(log, listing) {
|
||||
function insertOrNew(n, k) {
|
||||
const children = n.children;
|
||||
|
||||
if (children.has(k)) {
|
||||
return children.get(k);
|
||||
}
|
||||
|
||||
const v = {
|
||||
children: new Map()
|
||||
};
|
||||
children.set(k, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
const tree = {
|
||||
children: new Map()
|
||||
};
|
||||
|
||||
for (const f of listing) {
|
||||
const files = insertOrNew(tree, f.id.suite + ':');
|
||||
|
||||
if (f.id.path === '') {
|
||||
// This is a suite README.
|
||||
files.description = f.spec.description;
|
||||
continue;
|
||||
}
|
||||
|
||||
let tests = files;
|
||||
|
||||
for (const path of iteratePath(f.id.path, ':')) {
|
||||
tests = insertOrNew(tests, f.id.suite + ':' + path);
|
||||
}
|
||||
|
||||
if (f.spec.description) {
|
||||
// This is a directory README or spec file.
|
||||
tests.description = f.spec.description.trim();
|
||||
}
|
||||
|
||||
if (!('g' in f.spec)) {
|
||||
// This is a directory README.
|
||||
continue;
|
||||
}
|
||||
|
||||
const [tRec] = log.record(f.id);
|
||||
const fId = f.id.suite + ':' + f.id.path;
|
||||
|
||||
for (const t of f.spec.g.iterate(tRec)) {
|
||||
let cases = tests;
|
||||
|
||||
for (const path of iteratePath(t.id.test, '~')) {
|
||||
cases = insertOrNew(cases, fId + ':' + path);
|
||||
}
|
||||
|
||||
const p = t.id.params ? JSON.stringify(t.id.params) : '';
|
||||
cases.children.set(fId + ':' + t.id.test + '=' + p, {
|
||||
runCase: t
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
//# sourceMappingURL=tree.js.map
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue