Update web-platform-tests to revision 21461a83c51b72bcff82476c1b79a26a194e7bab

This commit is contained in:
WPT Sync Bot 2019-02-15 20:34:22 -05:00
parent ea206034ad
commit f96f9a1b78
61 changed files with 1372 additions and 376 deletions

View file

@ -13543,18 +13543,6 @@
{}
]
],
"payment-request/payment-request-multiple-show-manual.https.html": [
[
"/payment-request/payment-request-multiple-show-manual.https.html",
{}
]
],
"payment-request/payment-request-show-method-manual.https.html": [
[
"/payment-request/payment-request-show-method-manual.https.html",
{}
]
],
"payment-request/payment-response/complete-method-manual.https.html": [
[
"/payment-request/payment-response/complete-method-manual.https.html",
@ -144921,6 +144909,18 @@
{}
]
],
"css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html": [
[
"/css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html",
[
[
"/css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html",
"=="
]
],
{}
]
],
"css/css-transforms/css-rotate-2d-3d-001.html": [
[
"/css/css-transforms/css-rotate-2d-3d-001.html",
@ -273706,6 +273706,11 @@
{}
]
],
"css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html": [
[
{}
]
],
"css/css-transforms/css-rotate-2d-3d-001-ref.html": [
[
{}
@ -292536,6 +292541,11 @@
{}
]
],
"html/browsers/windows/nested-browsing-contexts/resources/post-to-parent.html": [
[
{}
]
],
"html/browsers/windows/resources/browsing-context-window.html": [
[
{}
@ -299476,6 +299486,16 @@
{}
]
],
"html/semantics/forms/form-submission-target/resources/endpoint.html": [
[
{}
]
],
"html/semantics/forms/form-submission-target/resources/reltester.js": [
[
{}
]
],
"html/semantics/forms/introduction-1/contains.json": [
[
{}
@ -336759,6 +336779,12 @@
{}
]
],
"animation-worklet/animate-non-accelerated-property.https.html": [
[
"/animation-worklet/animate-non-accelerated-property.https.html",
{}
]
],
"animation-worklet/animation-worklet-inside-iframe.https.html": [
[
"/animation-worklet/animation-worklet-inside-iframe.https.html",
@ -336777,6 +336803,12 @@
{}
]
],
"animation-worklet/cancel-non-accelerated-property.https.html": [
[
"/animation-worklet/cancel-non-accelerated-property.https.html",
{}
]
],
"animation-worklet/current-time.https.html": [
[
"/animation-worklet/current-time.https.html",
@ -347423,6 +347455,12 @@
{}
]
],
"css/css-position/position-absolute-container-dynamic.html": [
[
"/css/css-position/position-absolute-container-dynamic.html",
{}
]
],
"css/css-position/position-absolute-crash-chrome-001.html": [
[
"/css/css-position/position-absolute-crash-chrome-001.html",
@ -347441,6 +347479,12 @@
{}
]
],
"css/css-position/position-absolute-percentage-height.html": [
[
"/css/css-position/position-absolute-percentage-height.html",
{}
]
],
"css/css-position/position-absolute-replaced-minmax.html": [
[
"/css/css-position/position-absolute-replaced-minmax.html",
@ -348971,6 +349015,12 @@
{}
]
],
"css/css-syntax/cdc-vs-ident-tokens.html": [
[
"/css/css-syntax/cdc-vs-ident-tokens.html",
{}
]
],
"css/css-syntax/charset-is-not-a-rule.html": [
[
"/css/css-syntax/charset-is-not-a-rule.html",
@ -373279,6 +373329,12 @@
{}
]
],
"html/browsers/windows/nested-browsing-contexts/name-attribute.window.js": [
[
"/html/browsers/windows/nested-browsing-contexts/name-attribute.window.html",
{}
]
],
"html/browsers/windows/nested-browsing-contexts/window-parent-null.html": [
[
"/html/browsers/windows/nested-browsing-contexts/window-parent-null.html",
@ -378663,6 +378719,30 @@
{}
]
],
"html/semantics/forms/form-submission-target/rel-base-target.html": [
[
"/html/semantics/forms/form-submission-target/rel-base-target.html",
{}
]
],
"html/semantics/forms/form-submission-target/rel-button-target.html": [
[
"/html/semantics/forms/form-submission-target/rel-button-target.html",
{}
]
],
"html/semantics/forms/form-submission-target/rel-form-target.html": [
[
"/html/semantics/forms/form-submission-target/rel-form-target.html",
{}
]
],
"html/semantics/forms/form-submission-target/rel-input-target.html": [
[
"/html/semantics/forms/form-submission-target/rel-input-target.html",
{}
]
],
"html/semantics/forms/historical.html": [
[
"/html/semantics/forms/historical.html",
@ -385727,6 +385807,12 @@
{}
]
],
"kv-storage/backingstore.https.html": [
[
"/kv-storage/backingstore.https.html",
{}
]
],
"kv-storage/cause-errors-via-idb.https.html": [
[
"/kv-storage/cause-errors-via-idb.https.html",
@ -400250,7 +400336,9 @@
"payment-request/payment-request-show-method.https.html": [
[
"/payment-request/payment-request-show-method.https.html",
{}
{
"testdriver": true
}
]
],
"payment-request/payment-response/onpayerdetailchange-attribute.https.html": [
@ -411457,6 +411545,12 @@
{}
]
],
"screen-capture/feature-policy.https.html": [
[
"/screen-capture/feature-policy.https.html",
{}
]
],
"screen-capture/getdisplaymedia.https.html": [
[
"/screen-capture/getdisplaymedia.https.html",
@ -420974,21 +421068,29 @@
"webgl/webgl1-idlharness.any.js": [
[
"/webgl/webgl1-idlharness.any.html",
{}
{
"timeout": "long"
}
],
[
"/webgl/webgl1-idlharness.any.worker.html",
{}
{
"timeout": "long"
}
]
],
"webgl/webgl2-idlharness.any.js": [
[
"/webgl/webgl2-idlharness.any.html",
{}
{
"timeout": "long"
}
],
[
"/webgl/webgl2-idlharness.any.worker.html",
{}
{
"timeout": "long"
}
]
],
"webmessaging/Channel_postMessage_Blob.htm": [
@ -448847,6 +448949,12 @@
{}
]
],
"webdriver/tests/execute_async_script/promise.py": [
[
"/webdriver/tests/execute_async_script/promise.py",
{}
]
],
"webdriver/tests/execute_async_script/user_prompts.py": [
[
"/webdriver/tests/execute_async_script/user_prompts.py",
@ -457518,6 +457626,10 @@
"d22ed4cd251a20de43c4425e54abdc984b41976a",
"testharness"
],
"animation-worklet/animate-non-accelerated-property.https.html": [
"8e30387530ca2d8b9f7b7d2e7dfe85a20736ee02",
"testharness"
],
"animation-worklet/animation-worklet-inside-iframe.https.html": [
"b02186309dc2cf8df05559ef9fb9bcacdf535112",
"testharness"
@ -457530,6 +457642,10 @@
"1ff2544d6a9a4ee2cb251ef1d27b2278d979344f",
"testharness"
],
"animation-worklet/cancel-non-accelerated-property.https.html": [
"594da4c419135ef2e5ac32680cffedbb9a18bfdd",
"testharness"
],
"animation-worklet/common.js": [
"983c22403c44256f11ca470f2f74410ac3b84e08",
"support"
@ -571154,6 +571270,10 @@
"2b158a86f6599e43f6a2315a2943b4d394405ba5",
"testharness"
],
"css/css-position/position-absolute-container-dynamic.html": [
"711d31766da2e324d3d5ddf0362bc1c71b76d7f3",
"testharness"
],
"css/css-position/position-absolute-crash-chrome-001.html": [
"592e5d22e70f1b0c5e3e4b9222cbd1ccef99bdef",
"testharness"
@ -571166,6 +571286,10 @@
"5d36710b6fe694b256d9841b3e7a0fff4535c85b",
"testharness"
],
"css/css-position/position-absolute-percentage-height.html": [
"8b2e5c0f720d43d3aa922d2077ab305f6a61d59d",
"testharness"
],
"css/css-position/position-absolute-replaced-minmax.html": [
"644b147a227e100c500de2de9e4f8e8449a4a21e",
"testharness"
@ -576294,6 +576418,10 @@
"787700cebf39e5cc4fa0d5a2934a7e52bec6da32",
"testharness"
],
"css/css-syntax/cdc-vs-ident-tokens.html": [
"02cfbe11ae906f50ec3498f554395b7ad495bd70",
"testharness"
],
"css/css-syntax/charset-is-not-a-rule.html": [
"81b2a04dc5a0dd2f3434150f7bfb6a6d3f1cfef3",
"testharness"
@ -582582,6 +582710,14 @@
"e9a463fc0b0b7e893d3c801c6a78aa5368ef3e60",
"reftest"
],
"css/css-transforms/composited-under-rotateY-180deg-clip-perspective-ref.html": [
"ebd2d860cec74ba0d535637934aca8dadf90571d",
"support"
],
"css/css-transforms/composited-under-rotateY-180deg-clip-perspective.html": [
"6381ee7fa78036c7b17136edc1c81efb9609a0f1",
"reftest"
],
"css/css-transforms/css-rotate-2d-3d-001-ref.html": [
"54940566cd107ba443d3183dccecb505a811d14e",
"support"
@ -614103,7 +614239,7 @@
"testharness"
],
"custom-elements/reactions/HTMLButtonElement.html": [
"9b134ce2c6841a844b85e9fd27bc52c24fa29c91",
"b97d479d7c6ddcc4dc05d3a3501fe60b21ff051d",
"testharness"
],
"custom-elements/reactions/HTMLCanvasElement.html": [
@ -614443,7 +614579,7 @@
"support"
],
"docs/_writing-tests/testdriver.md": [
"a53a418fe3e39c543edd9361f3bd54a2a2581574",
"2526774a95cfd552bf19da55d8bfaad0b64d7680",
"support"
],
"docs/_writing-tests/testharness-api.md": [
@ -616171,7 +616307,7 @@
"support"
],
"domparsing/XMLSerializer-serializeToString.html": [
"5f7e2bb0d4b459bd20acb43aca19b848920ac8bb",
"81df61f5bc42880ee013287e90a3808bdccd536b",
"testharness"
],
"domparsing/createContextualFragment.html": [
@ -621587,31 +621723,31 @@
"support"
],
"fetch/stale-while-revalidate/fetch.tentative.html": [
"01a991ebfb1cb42288a01da37c76b09fa53f407c",
"5b9b2dc5de2835d1f4a9f49cc63e0b3f03317698",
"testharness"
],
"fetch/stale-while-revalidate/stale-css.py": [
"6f3014db5246994383354b139e7900306297dd57",
"425c889ac5ec58527e63ab25a4f70558b7daeef3",
"support"
],
"fetch/stale-while-revalidate/stale-css.tentative.html": [
"9b95b891fff2db4a29bd438208ea4274a762977d",
"3459493f28c22011e96def2549f01df1d5e0cbf2",
"testharness"
],
"fetch/stale-while-revalidate/stale-image.py": [
"42d0764eb91e7145cfe1638d90421ca7492379db",
"ce7f0fc782613e0a36e3d0aba0521e45f1ca6bf0",
"support"
],
"fetch/stale-while-revalidate/stale-image.tentative.html": [
"a5d4e79c54b8fca7a7089efcca0bc5f6f7c1202a",
"8b6a896eb15219e2222d65863c81724959c1ee1a",
"testharness"
],
"fetch/stale-while-revalidate/stale-script.py": [
"c17528d8e6314e60407085ca778ba2ff70666985",
"0f91a9b83486678eabd600ecb6336695e5dd6970",
"support"
],
"fetch/stale-while-revalidate/stale-script.tentative.html": [
"2e04e3905780add84f3da805a238946256ebda87",
"8cbb54b7dab3bc9b9e8763c5358a9232d24c1e7f",
"testharness"
],
"fonts/AD.woff": [
@ -625494,6 +625630,10 @@
"2f5b1c466f8bdaf2555e548f4140abdcc18d79bc",
"testharness"
],
"html/browsers/windows/nested-browsing-contexts/name-attribute.window.js": [
"69908af71b7239d72e33d33be79edd1f344a1870",
"testharness"
],
"html/browsers/windows/nested-browsing-contexts/resources/frameElement-nested-frame.html": [
"d066b8d4cb2dc76e85fa53f28c2053f9acbfbd72",
"support"
@ -625506,6 +625646,10 @@
"65a825f5737468d64c34d1399d0d0875c2dfe983",
"support"
],
"html/browsers/windows/nested-browsing-contexts/resources/post-to-parent.html": [
"302e9d9cc12b347da03c20e288f7dad12598d179",
"support"
],
"html/browsers/windows/nested-browsing-contexts/window-parent-null.html": [
"428312086ecf54e6f04129ffd3b91f4d7073e81f",
"testharness"
@ -636082,6 +636226,30 @@
"f37bc33f6f93ca94940ffeb0066945eb9aa020ee",
"testharness"
],
"html/semantics/forms/form-submission-target/rel-base-target.html": [
"222be95d2e8a9da39525fbf6d8048e6cdfd7a982",
"testharness"
],
"html/semantics/forms/form-submission-target/rel-button-target.html": [
"76fa8685905ad233f9312be3f6bf09503158a666",
"testharness"
],
"html/semantics/forms/form-submission-target/rel-form-target.html": [
"58611f41a9fdaea1611513e02dad87e017728f9a",
"testharness"
],
"html/semantics/forms/form-submission-target/rel-input-target.html": [
"b80e0240bae3802b04118249ec2b94e16a91e9e6",
"testharness"
],
"html/semantics/forms/form-submission-target/resources/endpoint.html": [
"be9e7942927dabeea32bf9e17b88d6643bc4ea91",
"support"
],
"html/semantics/forms/form-submission-target/resources/reltester.js": [
"0fa9774ce4f15be8909a0aceaa4879e9c5ab39c1",
"support"
],
"html/semantics/forms/historical.html": [
"6873ecd251741fb8436a377081d5a6d3de53b7ab",
"testharness"
@ -637271,7 +637439,7 @@
"support"
],
"html/semantics/rellist-feature-detection.html": [
"f4ce621172ebd5831fe259ab9603162549795dee",
"d290439d8ee647b2f8d95ddc45ac390dccde9843",
"testharness"
],
"html/semantics/scripting-1/META.yml": [
@ -642755,7 +642923,7 @@
"support"
],
"interfaces/font-metrics-api.idl": [
"b13def2d74c74b12821b9691f84088e23dc35040",
"b38024e44616599596661fcd72d705424b0debfc",
"support"
],
"interfaces/fullscreen.idl": [
@ -642795,7 +642963,7 @@
"support"
],
"interfaces/html.idl": [
"0d6445e7f016b736966e621a414cbe9bc9219e99",
"f530f3559b68af565fc07f4372a1444d5036eac2",
"support"
],
"interfaces/image-capture.idl": [
@ -642991,7 +643159,7 @@
"support"
],
"interfaces/storage.idl": [
"29603241222b9c472ca21184d04e1966e2f7198a",
"437bc6dd43c2bd17113c6b823a238e7141fb25bf",
"support"
],
"interfaces/touch-events.idl": [
@ -643043,7 +643211,7 @@
"support"
],
"interfaces/web-nfc.idl": [
"5a6d6f8a06b1d7bfbcf5b3cc1b5078ff930cbedc",
"913d1fe808adf50f66fa621eb62d12b1b41a3a05",
"support"
],
"interfaces/web-share.idl": [
@ -643450,8 +643618,12 @@
"90e705862d599f2920ebdf5fa07cc3e4ba1f6d46",
"testharness"
],
"kv-storage/backingstore.https.html": [
"44e634d85bbc34621450c4029a63c5e9114075b3",
"testharness"
],
"kv-storage/cause-errors-via-idb.https.html": [
"21fe36b36cb1dbedca5383abb526b9b4f6c8ce3e",
"d77e56621e037b71fa6ae9bfb3e80a0ab85677fc",
"testharness"
],
"kv-storage/entries.https.html": [
@ -643467,7 +643639,7 @@
"support"
],
"kv-storage/helpers/kvs-tests.js": [
"a6c4d58dfa5e928768d483df11c7d06180bac9fb",
"0cf4c2fd3d5fcaa392e8cbbcf64101155bcbe441",
"support"
],
"kv-storage/key-types.https.html": [
@ -643495,7 +643667,7 @@
"testharness"
],
"kv-storage/storage-smoke-test.https.html": [
"df6fd8c8181f579df03972d25fe9a91b2354380f",
"da48dc7cf13cb31fd5f5a3b4b7fa086100197bd9",
"testharness"
],
"kv-storage/undefined-value.https.html": [
@ -655374,10 +655546,6 @@
"02122203d51eaff6c6639c9762b1495173bbf66e",
"testharness"
],
"payment-request/payment-request-multiple-show-manual.https.html": [
"cc412171a6d74cd242c32a2bb50b83eaaf156478",
"manual"
],
"payment-request/payment-request-not-exposed.https.worker.js": [
"e5576e673520ea33504d8ddea0e862d54b28e8fb",
"testharness"
@ -655402,12 +655570,8 @@
"11f75b1c862224b5655cb724d8c8f5b25ab1af00",
"testharness"
],
"payment-request/payment-request-show-method-manual.https.html": [
"6ef98e85a6092a648897bfbca966d78a5a2195f8",
"manual"
],
"payment-request/payment-request-show-method.https.html": [
"dd04987092b49bbfb5d525da7ce0af63fa60a495",
"cc8c881d1147c8cebb87a84d6b466a7b4d32ea13",
"testharness"
],
"payment-request/payment-response/complete-method-manual.https.html": [
@ -666779,7 +666943,7 @@
"support"
],
"resources/testdriver.js": [
"ea380dbd3c32def105c1483230e91e9c7e979b27",
"e328302e4f345114654eda323dbd09a5f650d419",
"support"
],
"resources/testdriver.js.headers": [
@ -667638,6 +667802,10 @@
"47882d3275f1cc928555045b2def8fc90f6bcdb0",
"support"
],
"screen-capture/feature-policy.https.html": [
"56c9e80a1307484a26ab370298789030a6fa350e",
"testharness"
],
"screen-capture/getdisplaymedia.https.html": [
"7427e3433d01682570126b4bfe967c240fd12d3e",
"testharness"
@ -676739,7 +676907,7 @@
"support"
],
"tools/ci/taskcluster-run.py": [
"2b3270c17aaacd053bdff516fa1f1ee666011858",
"78c50a6285e81c8fa5e69585a28f04e957a59869",
"support"
],
"tools/ci/tcdownload.py": [
@ -681947,7 +682115,7 @@
"support"
],
"tools/wptrunner/wptrunner/testdriver-extra.js": [
"ca61caf51e8eaf4f378da3165ed5c50bc0e3593a",
"6336d227db8d7d9f3e6c4276ad2f5c609e9f27e9",
"support"
],
"tools/wptrunner/wptrunner/testdriver-vendor.js": [
@ -687014,6 +687182,10 @@
"7c454eaf4ac4f83d7594e58f99dbdb525ef7d687",
"wdspec"
],
"webdriver/tests/execute_async_script/promise.py": [
"8b6d7d9157b28570e7984491e02e42f6a64ce15c",
"wdspec"
],
"webdriver/tests/execute_async_script/user_prompts.py": [
"5c873935519716a3f4933b710828118218f7220c",
"wdspec"
@ -687039,7 +687211,7 @@
"wdspec"
],
"webdriver/tests/execute_script/promise.py": [
"1eab7822c5c2f3c8d3fa51ac0713ebdc2c19269c",
"8bb637853ccd789f128a8293a678f58cfe030912",
"wdspec"
],
"webdriver/tests/execute_script/user_prompts.py": [
@ -687747,11 +687919,11 @@
"testharness"
],
"webgl/webgl1-idlharness.any.js": [
"884def896cb4d1c987f678c1d9e71aa157773e70",
"2cf80395230604336daadeaa2ac4a910552215b5",
"testharness"
],
"webgl/webgl2-idlharness.any.js": [
"97edfa18285daeeb35a2bf563981283b6399fde4",
"c8efcd031fe53a37c5db3740b82db4a1f0df647d",
"testharness"
],
"webmessaging/Channel_postMessage_Blob.htm": [

View file

@ -62,18 +62,12 @@
[Matching font-weight: '399' should prefer '450 460' over '500 501']
expected: FAIL
[Matching font-stretch: '100%' should prefer '100%' over '110% 120%']
expected: FAIL
[Matching font-style: 'normal' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
[Matching font-style: 'italic' should prefer 'italic' over 'oblique 20deg']
expected: FAIL
[Matching font-style: 'italic' should prefer 'oblique 20deg' over 'oblique 30deg 60deg']
expected: FAIL
[Matching font-style: 'italic' should prefer 'oblique 30deg 60deg' over 'oblique 40deg 50deg']
expected: FAIL
@ -101,9 +95,6 @@
[Matching font-style: 'oblique 21deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
[Matching font-style: 'oblique 10deg' should prefer 'oblique 5deg' over 'oblique 15deg 20deg']
expected: FAIL
[Matching font-style: 'oblique 10deg' should prefer 'oblique 15deg 20deg' over 'oblique 30deg 60deg']
expected: FAIL
@ -113,9 +104,6 @@
[Matching font-style: 'oblique 10deg' should prefer 'oblique 40deg 50deg' over 'italic']
expected: FAIL
[Matching font-style: 'oblique 10deg' should prefer 'italic' over 'oblique 0deg']
expected: FAIL
[Matching font-style: 'oblique 10deg' should prefer 'oblique 0deg' over 'oblique -50deg -20deg']
expected: FAIL
@ -302,9 +290,6 @@
[Matching font-style: 'oblique 20deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg']
expected: FAIL
[Matching font-style: 'oblique 0deg' should prefer 'oblique 40deg 50deg' over 'italic']
expected: FAIL
[Matching font-weight: '500' should prefer '500' over '450 460']
expected: FAIL

View file

@ -0,0 +1,2 @@
[composited-under-rotateY-180deg-clip-perspective.html]
expected: FAIL

View file

@ -1,19 +1,7 @@
[HTMLButtonElement.html]
[formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when adding a new attribute]
expected: FAIL
[disabled on HTMLButtonElement must enqueue an attributeChanged reaction when adding disabled content attribute]
expected: FAIL
[disabled on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[formNoValidate on HTMLButtonElement must enqueue an attributeChanged reaction when replacing an existing attribute]
expected: FAIL
[autofocus on HTMLButtonElement must enqueue an attributeChanged reaction when adding autofocus content attribute]
expected: FAIL

View file

@ -48,3 +48,15 @@
[Check if an attribute with namespace and no prefix is serialized with the nearest-declared prefix even if the prefix is assigned to another namespace.]
expected: FAIL
[Check if start tag serialization finds an appropriate prefix.]
expected: FAIL
[Check if start tag serialization drops element prefix if the namespace is same as inherited default namespace.]
expected: FAIL
[Check if start tag serialization applied the original prefix even if it is declared in an ancestor element.]
expected: FAIL
[Check if start tag serialization takes into account of its xmlns:* attributes]
expected: FAIL

View file

@ -312,3 +312,6 @@
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain;charset=gbk text/html]
expected: FAIL

View file

@ -0,0 +1,5 @@
[javascript-url-abort-return-value-undefined.tentative.html]
expected: TIMEOUT
[Not aborting fetch for javascript:undefined navigation]
expected: TIMEOUT

View file

@ -0,0 +1,4 @@
[navigation-unload-same-origin-fragment.html]
[Tests that a fragment navigation in the unload handler will not block the initial navigation]
expected: FAIL

View file

@ -0,0 +1,74 @@
[name-attribute.window.html]
expected: TIMEOUT
[cross-origin <frame name=>]
expected: TIMEOUT
[cross-origin <embed name=>]
expected: TIMEOUT
[same-origin <frame name=>]
expected: TIMEOUT
[cross-origin <iframe name=initialvalue>]
expected: FAIL
[cross-origin <embed name=initialvalue>]
expected: TIMEOUT
[same-origin <iframe name=>]
expected: FAIL
[same-origin <embed>]
expected: TIMEOUT
[cross-origin <iframe>]
expected: FAIL
[cross-origin <frame name=initialvalue>]
expected: TIMEOUT
[cross-origin <iframe name=>]
expected: FAIL
[same-origin <object name=initialvalue>]
expected: TIMEOUT
[cross-origin <object name=initialvalue>]
expected: TIMEOUT
[same-origin <iframe>]
expected: FAIL
[same-origin <iframe name=initialvalue>]
expected: FAIL
[same-origin <object name=>]
expected: TIMEOUT
[same-origin <embed name=>]
expected: TIMEOUT
[same-origin <object>]
expected: TIMEOUT
[cross-origin <frame>]
expected: TIMEOUT
[same-origin <frame>]
expected: TIMEOUT
[cross-origin <object>]
expected: TIMEOUT
[cross-origin <embed>]
expected: TIMEOUT
[cross-origin <object name=>]
expected: TIMEOUT
[same-origin <frame name=initialvalue>]
expected: TIMEOUT
[same-origin <embed name=initialvalue>]
expected: TIMEOUT

View file

@ -9381,6 +9381,18 @@
[HTMLIFrameElement interface: attribute allow]
expected: FAIL
[HTMLFormElement interface: attribute rel]
expected: FAIL
[HTMLFormElement interface: attribute relList]
expected: FAIL
[HTMLFormElement interface: document.createElement("form") must inherit property "rel" with the proper type]
expected: FAIL
[HTMLFormElement interface: document.createElement("form") must inherit property "relList" with the proper type]
expected: FAIL
[interfaces.https.html?exclude=(Document|Window|HTML.*)]
[HTML IDL tests]

View file

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

View file

@ -0,0 +1,22 @@
[rel-base-target.html]
[<form rel="noreferrer opener"> with <base target>]
expected: FAIL
[<form rel="opener"> with <base target>]
expected: FAIL
[<form rel="opener noopener"> with <base target>]
expected: FAIL
[<form rel="noopener noreferrer"> with <base target>]
expected: FAIL
[<form rel="noopener"> with <base target>]
expected: FAIL
[<form rel="noreferrer"> with <base target>]
expected: FAIL
[<form rel=""> with <base target>]
expected: FAIL

View file

@ -0,0 +1,22 @@
[rel-button-target.html]
[<form rel="opener noopener"> with <button formtarget>]
expected: FAIL
[<form rel="noopener noreferrer"> with <button formtarget>]
expected: FAIL
[<form rel=""> with <button formtarget>]
expected: FAIL
[<form rel="noreferrer opener"> with <button formtarget>]
expected: FAIL
[<form rel="noopener"> with <button formtarget>]
expected: FAIL
[<form rel="noreferrer"> with <button formtarget>]
expected: FAIL
[<form rel="opener"> with <button formtarget>]
expected: FAIL

View file

@ -0,0 +1,22 @@
[rel-form-target.html]
[<form rel="noopener noreferrer"> with <form target>]
expected: FAIL
[<form rel="noreferrer opener"> with <form target>]
expected: FAIL
[<form rel="noreferrer"> with <form target>]
expected: FAIL
[<form rel="opener noopener"> with <form target>]
expected: FAIL
[<form rel=""> with <form target>]
expected: FAIL
[<form rel="noopener"> with <form target>]
expected: FAIL
[<form rel="opener"> with <form target>]
expected: FAIL

View file

@ -0,0 +1,22 @@
[rel-input-target.html]
[<form rel="opener"> with <input formtarget>]
expected: FAIL
[<form rel="opener noopener"> with <input formtarget>]
expected: FAIL
[<form rel=""> with <input formtarget>]
expected: FAIL
[<form rel="noreferrer opener"> with <input formtarget>]
expected: FAIL
[<form rel="noopener noreferrer"> with <input formtarget>]
expected: FAIL
[<form rel="noreferrer"> with <input formtarget>]
expected: FAIL
[<form rel="noopener"> with <input formtarget>]
expected: FAIL

View file

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

View file

@ -0,0 +1,44 @@
<!DOCTYPE html>
<title>Animate non-accelerated property using worklet animation</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="common.js"></script>
<div id="target"></div>
<div id="target2"></div>
<script>
promise_test(async t => {
await registerConstantLocalTimeAnimator(1000);
const target = document.getElementById("target");
const effect = new KeyframeEffect(
target,
[
{ background: 'green' },
{ background: 'blue' },
],
{ duration: 2000 }
);
const target2 = document.getElementById("target2");
const effect2 = new KeyframeEffect(
target2,
[
{ boxShadow: '4px 4px 25px blue' },
{ boxShadow: '4px 4px 25px green' }
],
{ duration: 2000 }
);
const animation = new WorkletAnimation('constant_time', effect);
animation.play();
const animation2 = new WorkletAnimation('constant_time', effect2);
animation2.play();
await waitForAsyncAnimationFrames(1);
assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 64, 128)");
assert_equals(getComputedStyle(target2).boxShadow, "rgb(0, 64, 128) 4px 4px 25px 0px");
}, "Individual worklet animation should output values at specified local time for corresponding targets and effects");
</script>

View file

@ -0,0 +1,45 @@
<!DOCTYPE html>
<title>Cancel non accelerated property using worklet animation</title>
<link rel="help" href="https://drafts.css-houdini.org/css-animationworklet/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/web-animations/testcommon.js"></script>
<script src="common.js"></script>
<style>
#target {
background-color: red;
}
</style>
<div id="target"></div>
<script>
promise_test(async t => {
await registerConstantLocalTimeAnimator(1000);
const target = document.getElementById('target');
const effect = new KeyframeEffect(
target,
[
{ background: 'green' },
{ background: 'blue' },
],
{
duration: 2000,
iteration: Infinity
}
);
const animation = new WorkletAnimation('constant_time', effect);
animation.play();
await waitForAsyncAnimationFrames(1);
// establish that the animation started
assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 64, 128)");
animation.cancel();
await waitForAsyncAnimationFrames(1);
// confirm the animation is cancelled
assert_equals(getComputedStyle(target).backgroundColor, "rgb(255, 0, 0)");
}, "Animation should update the outputs after starting and then return to pre-animated values after being cancelled");
</script>

View file

@ -0,0 +1,35 @@
<!DOCTYPE html>
<title>CSS Position Absolute: dynamic changes to containing block width</title>
<link rel="author" href="mailto:atotic@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://www.w3.org/TR/css-position-3/#abs-non-replaced-width">
<meta name="assert" content="abspos descendant responds to containing block size change">
<style>
#container {
position: relative;
width: 50px;
height: 100px;
background: red;
}
#target {
position: absolute;
left: 0;
width: 100%;
height: 100%;
background: green;
}
</style>
<div id="container">
<div style="display:flex;">
<div id="target"></div>
</div>
</div>
<script>
document.body.offsetTop;
test(() => {
document.getElementById("container").style.width = "100px";
assert_equals(document.querySelector("#target").offsetWidth, 100);
}, '#target used container width when computing size');
</script>

View file

@ -0,0 +1,59 @@
<!DOCTYPE html>
<title>CSS Position Absolute: css-position-3</title>
<link rel="author" href="mailto:atotic@google.com">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<link rel="help" href="https://www.w3.org/TR/css-position-3/">
<meta name="assert" content="abspos resolves %-ge sizes correctly.">
<style>
#container {
position: relative;
}
#image-wrapper {
display: flex;
position: absolute;
height: 100%;
background: green;
}
#content-wrapper {
margin-left: 30%;
}
#target {
display: block;
min-height: 100%;
opacity: 0.5;
}
</style>
<!-- IMG height is 100% of image wrapper height.
IMG width is 100% of image wrapper width.
IMG width equals IMG height -->
<div id="container">
<div id="image-wrapper">
<!-- 1x1 green pixel -->
<img id="target" src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEBgIApD5fRAAAAABJRU5ErkJggg==">
</div>
<div id="content-wrapper">
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</div>
</div>
<script>
document.body.offsetTop;
test(() => {
let target = document.querySelector("#target");
assert_equals(target.offsetWidth, target.offsetHeight);
assert_equals(target.offsetWidth, document.querySelector("#image-wrapper").offsetWidth);
assert_equals(target.offsetHeight, document.querySelector("#content-wrapper").offsetHeight);
}, '#target height matches containing block height, and target parent width matches #target width' );
test(() => {
document.body.style.marginLeft = "300px";
let target = document.querySelector("#target");
assert_equals(target.offsetWidth, target.offsetHeight);
assert_equals(target.offsetWidth, document.querySelector("#image-wrapper").offsetWidth);
assert_equals(target.offsetHeight, document.querySelector("#content-wrapper").offsetHeight);
}, '#target height matches containing block height, and target parent width matches #target width after resize');
</script>

View file

@ -0,0 +1,28 @@
<!doctype html>
<title>CDC versus Ident Token</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
-->
--foo { color: blue; }
</style>
<meta name=author content="Tab Atkins-Bittner">
<link rel=help href="https://drafts.csswg.org/css-syntax/#consume-token">
<!--
The ordering of the checks in the HYPHEN-MINUS step is important;
if you get it wrong, ident-token can swallow cdc-token.
-->
<script>
test(()=>{
const rule = document.styleSheets[0].cssRules[0];
assert_equals(rule.selectorText, "--foo");
}, "CDC-token is properly emitted, and not parsed as an ident.");
</script>

View file

@ -0,0 +1,2 @@
<!DOCTYPE html>
<div style="width: 100px; height: 100px; background: green"></div>

View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<title>CSS Test (Transforms): composited under rotateY(180deg) with overflow clip under perspective</title>
<link rel="help" href="http://www.w3.org/TR/css-transforms-2">
<meta name="assert" content="This tests that a composited element with default
backface-visibility is visible under rotateY(180deg) with overflow clip under
perspective.">
<link rel="match" href="composited-under-rotateY-180deg-clip-perspective-ref.html">
<div style="perspective: 1px">
<div style="transform: rotateY(180deg); overflow: hidden; width: 100px">
<div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
</div>
<div style="transform: rotateY(180deg); overflow: hidden; width: 100px; backface-visibility: hidden">
<div style="width: 100px; height: 100px; background: green; will-change: transform"></div>
</div>
</div>

View file

@ -16,15 +16,15 @@ function getParentElement(parentElementName) {
return parentElement;
}
testReflectAttributeWithContentValues('autofocus', 'autofocus', true, 'true', false, 'false', 'autofocus on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectAttributeWithContentValues('disabled', 'disabled', true, 'true', false, 'false', 'disabled on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectBooleanAttribute('autofocus', 'autofocus', 'autofocus on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectBooleanAttribute('disabled', 'disabled', 'disabled on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectAttribute('name', 'name', 'intel', 'intel1', 'name on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectAttribute('value', 'value', 'HTML', 'CSS', 'value on HTMLButtonElement', 'button', HTMLButtonElement);
testReflectAttributeWithParentNode('type', 'type', 'submit', 'reset', 'type on HTMLButtonElement', 'button', () => getParentElement('form'), HTMLButtonElement);
testReflectAttrWithDepAttr('formAction', 'formaction', 'type', 'intel.asp', 'intel1.asp', 'submit', 'formAction on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
testReflectAttrWithDepAttr('formEnctype', 'formenctype', 'type', 'text/plain', 'multipart/form-data', 'submit', 'formEnctype on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
testReflectAttrWithDepAttr('formMethod', 'formmethod', 'type', 'get', 'post', 'submit', 'formMethod on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
testReflectAttrWithContentValuesAndDepAttr('formNoValidate', 'formnovalidate', 'type', true, 'true', false, 'false', 'submit', 'formNoValidate on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
testReflectAttrWithContentValuesAndDepAttr('formNoValidate', 'formnovalidate', 'type', true, '', false, null, 'submit', 'formNoValidate on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
testReflectAttrWithDepAttr('formTarget', 'formtarget', 'type', '_blank', '_self', 'submit', 'formTarget on HTMLButtonElement', 'button', 'form', HTMLButtonElement);
//In parent node, sub node's observeAttribute which depends another attribute can enqueue by changing attribute value

View file

@ -5,7 +5,9 @@ order: 8.5
---
testdriver.js provides a means to automate tests that cannot be
written purely using web platform APIs.
written purely using web platform APIs. Outside of automation
contexts, it allows human operators to provide expected input
manually (for operations which may be described in simple terms).
It is currently supported only for [testharness.js][testharness]
tests.

View file

@ -27,28 +27,22 @@ function serialize(node) {
}
test(function() {
var serializer = new XMLSerializer();
var root = createXmlDoc().documentElement;
var xmlString = serializer.serializeToString(root);
assert_equals(xmlString, '<root><child1>value1</child1></root>');
assert_equals(serialize(root), '<root><child1>value1</child1></root>');
}, 'check XMLSerializer.serializeToString method could parsing xmldoc to string');
test(function() {
var serializer = new XMLSerializer();
var root = createXmlDoc().documentElement;
var element = root.ownerDocument.createElementNS('urn:foo', 'another');
var child1 = root.firstChild;
root.replaceChild(element, child1);
element.appendChild(child1);
var xmlString = serializer.serializeToString(root);
assert_equals(xmlString, '<root><another xmlns="urn:foo"><child1 xmlns="">value1</child1></another></root>');
assert_equals(serialize(root), '<root><another xmlns="urn:foo"><child1 xmlns="">value1</child1></another></root>');
}, 'Check if the default namespace is correctly reset.');
test(function() {
var input = '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>';
var root = (new DOMParser()).parseFromString(input, 'text/xml').documentElement;
var xmlString = (new XMLSerializer()).serializeToString(root);
assert_equals(xmlString, '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
var root = parse('<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
assert_equals(serialize(root), '<root xmlns="urn:bar"><outer xmlns=""><inner>value1</inner></outer></root>');
}, 'Check if there is no redundant empty namespace declaration.');
test(function() {
@ -124,54 +118,73 @@ test(function() {
}, 'Check if the prefix of an attribute is replaced with a generated one in a case where the prefix is already mapped to a different namespace URI.');
test(function() {
var serializer = new XMLSerializer();
var parser = new DOMParser();
var root = parser.parseFromString('<root />', 'text/xml').documentElement;
var root = parse('<root />');
root.setAttribute('attr', '\t');
assert_in_array(serializer.serializeToString(root), [
assert_in_array(serialize(root), [
'<root attr="&#9;"/>', '<root attr="&#x9;"/>']);
root.setAttribute('attr', '\n');
assert_in_array(serializer.serializeToString(root), [
assert_in_array(serialize(root), [
'<root attr="&#xA;"/>', '<root attr="&#10;"/>']);
root.setAttribute('attr', '\r');
assert_in_array(serializer.serializeToString(root), [
assert_in_array(serialize(root), [
'<root attr="&#xD;"/>', '<root attr="&#13;"/>']);
}, 'check XMLSerializer.serializeToString escapes attribute values for roundtripping');
test(function() {
const root = (new Document()).createElement('root');
root.setAttributeNS('uri1', 'p:foobar', 'value1');
root.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:p', 'uri2');
const xmlString = (new XMLSerializer()).serializeToString(root);
assert_equals(xmlString, '<root xmlns:ns1="uri1" ns1:foobar="value1" xmlns:p="uri2"/>');
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
assert_equals(serialize(root), '<root xmlns:ns1="uri1" ns1:foobar="value1" xmlns:p="uri2"/>');
}, 'Check if attribute serialization takes into account of following xmlns:* attributes');
test(function() {
const input = '<root xmlns:p="uri1"><child/></root>';
const root = (new DOMParser()).parseFromString(input, 'text/xml').documentElement;
const root = parse('<root xmlns:p="uri1"><child/></root>');
root.firstChild.setAttributeNS('uri2', 'p:foobar', 'v');
const xmlString = (new XMLSerializer()).serializeToString(root);
assert_equals(xmlString, '<root xmlns:p="uri1"><child xmlns:ns1="uri2" ns1:foobar="v"/></root>');
assert_equals(serialize(root), '<root xmlns:p="uri1"><child xmlns:ns1="uri2" ns1:foobar="v"/></root>');
}, 'Check if attribute serialization takes into account of the same prefix declared in an ancestor element');
test(function() {
const input = '<root><child1/><child2/></root>';
const root = (new DOMParser()).parseFromString(input, 'text/xml').documentElement;
assert_equals(serialize(parse('<root><child/></root>')), '<root><child/></root>');
assert_equals(serialize(parse('<root><child xmlns=""/></root>')), '<root><child/></root>');
assert_equals(serialize(parse('<root xmlns="u1"><child xmlns="u1"/></root>')), '<root xmlns="u1"><child/></root>');
assert_equals(serialize(parse('<root xmlns="u1"><p:child xmlns:p="u1"/></root>')), '<root xmlns="u1"><child xmlns:p="u1"/></root>');
}, 'Check if start tag serialization drops element prefix if the namespace is same as inherited default namespace.');
test(function() {
const root = parse('<root xmlns:p1="u1"><child xmlns:p2="u1"/></root>');
const child2 = root.ownerDocument.createElementNS('u1', 'child2');
root.firstChild.appendChild(child2);
assert_equals(serialize(root), '<root xmlns:p1="u1"><child xmlns:p2="u1"><p2:child2/></child></root>');
}, 'Check if start tag serialization finds an appropriate prefix.');
test(function() {
const root = (new Document()).createElementNS('uri1', 'p:root');
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
assert_equals(serialize(root), '<ns1:root xmlns:ns1="uri1" xmlns:p="uri2"/>');
}, 'Check if start tag serialization takes into account of its xmlns:* attributes');
test(function() {
const root = (new Document()).createElement('root');
root.setAttributeNS(XMLNS_URI, 'xmlns:p', 'uri2');
const child = root.ownerDocument.createElementNS('uri1', 'p:child');
root.appendChild(child);
assert_equals(serialize(root), '<root xmlns:p="uri2"><p:child xmlns:p="uri1"/></root>');
}, 'Check if start tag serialization applied the original prefix even if it is declared in an ancestor element.');
test(function() {
const root = parse('<root><child1/><child2/></root>');
root.firstChild.setAttributeNS('uri1', 'attr1', 'value1');
root.firstChild.setAttributeNS('uri2', 'attr2', 'value2');
root.lastChild.setAttributeNS('uri3', 'attr3', 'value3');
const xmlString = (new XMLSerializer()).serializeToString(root);
assert_equals(xmlString, '<root><child1 xmlns:ns1="uri1" ns1:attr1="value1" xmlns:ns2="uri2" ns2:attr2="value2"/><child2 xmlns:ns3="uri3" ns3:attr3="value3"/></root>');
assert_equals(serialize(root), '<root><child1 xmlns:ns1="uri1" ns1:attr1="value1" xmlns:ns2="uri2" ns2:attr2="value2"/><child2 xmlns:ns3="uri3" ns3:attr3="value3"/></root>');
}, 'Check if generated prefixes match to "ns${index}".');
test(function() {
const input = '<root xmlns:ns2="uri2"><child xmlns:ns1="uri1"/></root>';
const root = (new DOMParser()).parseFromString(input, 'text/xml').documentElement;
const root = parse('<root xmlns:ns2="uri2"><child xmlns:ns1="uri1"/></root>');
root.firstChild.setAttributeNS('uri3', 'attr1', 'value1');
const xmlString = (new XMLSerializer()).serializeToString(root);
// According to 'DOM Parsing and Serialization' draft as of 2018-12-11,
// 'generate a prefix' result can conflict with an existing xmlns:ns* declaration.
assert_equals(xmlString, '<root xmlns:ns2="uri2"><child xmlns:ns1="uri1" xmlns:ns1="uri3" ns1:attr1="value1"/></root>');
assert_equals(serialize(root), '<root xmlns:ns2="uri2"><child xmlns:ns1="uri1" xmlns:ns1="uri3" ns1:attr1="value1"/></root>');
}, 'Check if "ns1" is generated even if the element already has xmlns:ns1.');
test(function() {

View file

@ -7,11 +7,14 @@ https://github.com/whatwg/fetch/pull/853
<title>Tests Stale While Revalidate is not executed for fetch API</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<script>
promise_test(async (test) => {
const response = await fetch(`stale-script.py`);
const response2 = await fetch(`stale-script.py`);
var request_token = token();
assert_not_equals(response.headers.get('Token'), response2.headers.get('Token'));
const response = await fetch(`stale-script.py?token=` + request_token);
const response2 = await fetch(`stale-script.py?token=` + request_token);
assert_not_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id'));
}, 'Second fetch does not return same response');
</script>

View file

@ -1,9 +1,10 @@
def main(request, response):
cookie = request.cookies.first("Count", None)
token = request.GET.first("token", None)
value = request.server.stash.take(token)
count = 0
if cookie != None:
count = int(cookie.value)
if value != None:
count = int(value)
if request.GET.first("query", None) != None:
headers = [("Count", count)]
content = ""
@ -15,6 +16,7 @@ def main(request, response):
content = "body { background: rgb(255, 0, 0); }"
headers = [("Content-Type", "text/css"),
("Set-Cookie", "Count={}".format(count)),
("Cache-Control", "private, max-age=0, stale-while-revalidate=10")]
("Cache-Control", "private, max-age=0, stale-while-revalidate=60")]
request.server.stash.put(token, count)
return 200, headers, content

View file

@ -7,9 +7,11 @@ https://github.com/whatwg/fetch/pull/853
<title>Tests Stale While Revalidate works for css</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<body>
<script>
var request_token = token();
async_test(t => {
window.onload = t.step_func(() => {
t.step_timeout(() => {
@ -19,10 +21,10 @@ async_test(t => {
assert_equals(window.getComputedStyle(document.body).getPropertyValue('background-color'), "rgb(0, 128, 0)");
var checkResult = () => {
// We poll because we don't know when the revalidation will occur.
fetch("stale-css.py?query").then(t.step_func((response) => {
fetch("stale-css.py?query&token=" + request_token).then(t.step_func((response) => {
var count = response.headers.get("Count");
if (count == '2') {
t.done();
t.done();
} else {
t.step_timeout(checkResult, 25);
}
@ -32,7 +34,7 @@ async_test(t => {
});
link2.rel = "stylesheet";
link2.type = "text/css";
link2.href = "stale-css.py";
link2.href = "stale-css.py?token=" + request_token;
document.body.appendChild(link2);
}, 0);
});
@ -41,7 +43,7 @@ async_test(t => {
var link = document.createElement("link");
link.rel = "stylesheet";
link.type = "text/css";
link.href = "stale-css.py";
link.href = "stale-css.py?token=" + request_token;
document.body.appendChild(link);
</script>
</body>

View file

@ -2,10 +2,11 @@ import os.path
def main(request, response):
cookie = request.cookies.first("Count", None)
token = request.GET.first("token", None)
value = request.server.stash.take(token)
count = 0
if cookie != None:
count = int(cookie.value)
if value != None:
count = int(value)
if request.GET.first("query", None) != None:
headers = [("Count", count)]
content = ""
@ -13,18 +14,18 @@ def main(request, response):
else:
count = count + 1
filename = "green-16x16.png"
if cookie > 1:
if count > 1:
filename = "green-256x256.png"
path = os.path.join(os.path.dirname(__file__), "../../images", filename)
body = open(path, "rb").read()
request.server.stash.put(token, count)
response.add_required_headers = False
response.writer.write_status(200)
response.writer.write_header("content-length", len(body))
response.writer.write_header("Cache-Control", "private, max-age=0, stale-while-revalidate=10")
response.writer.write_header("Cache-Control", "private, max-age=0, stale-while-revalidate=60")
response.writer.write_header("content-type", "image/png")
response.writer.write_header("Set-Cookie", "Count={}".format(count))
response.writer.end_headers()
response.writer.write(body)

View file

@ -7,6 +7,7 @@ https://github.com/whatwg/fetch/pull/853
<title>Tests Stale While Revalidate works for images</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<body>
<!--
Use a child document to load the second stale image into because
@ -16,6 +17,7 @@ See: https://html.spec.whatwg.org/#the-list-of-available-images
<iframe id="child" srcdoc=""></iframe>
<script>
var request_token = token();
async_test(t => {
window.onload = t.step_func(() => {
t.step_timeout(() => {
@ -26,7 +28,7 @@ async_test(t => {
assert_equals(img2.width, 16, "image dimension");
var checkResult = () => {
// We poll because we don't know when the revalidation will occur.
fetch("stale-image.py?query").then(t.step_func((response) => {
fetch("stale-image.py?query&token=" + request_token).then(t.step_func((response) => {
var count = response.headers.get("Count");
if (count == '2') {
t.done();
@ -37,14 +39,14 @@ async_test(t => {
};
t.step_timeout(checkResult, 25);
});
img2.src = "stale-image.py";
img2.src = "stale-image.py?token=" + request_token;
childDocument.body.appendChild(img2);
}, 0);
});
}, 'Cache returns stale resource');
var img = document.createElement("img");
img.src = "stale-image.py";
img.src = "stale-image.py?token=" + request_token;
img.id = "firstimage";
document.body.appendChild(img);
</script>

View file

@ -1,14 +1,15 @@
import random, string, datetime
def token():
def id_token():
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(20))
def main(request, response):
cookie = request.cookies.first("Count", None)
token = request.GET.first("token", None)
value = request.server.stash.take(token)
count = 0
if cookie != None:
count = int(cookie.value)
if value != None:
count = int(value)
if request.GET.first("query", None) != None:
headers = [("Count", count)]
content = ""
@ -16,10 +17,10 @@ def main(request, response):
else:
count = count + 1
unique_id = token()
unique_id = id_token()
headers = [("Content-Type", "text/javascript"),
("Cache-Control", "private, max-age=0, stale-while-revalidate=10"),
("Set-Cookie", "Count={}".format(count)),
("Token", unique_id)]
("Cache-Control", "private, max-age=0, stale-while-revalidate=60"),
("Unique-Id", unique_id)]
content = "report('{}')".format(unique_id)
request.server.stash.put(token, count)
return 200, headers, content

View file

@ -7,10 +7,12 @@ https://github.com/whatwg/fetch/pull/853
<title>Tests Stale While Revalidate works for scripts</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/utils.js"></script>
<body>
<script>
var last_modified;
var last_modified_count = 0;
var request_token = token();
// The script will call report via a uniquely generated ID on the subresource.
// If it is a cache hit the ID will be the same and the test will pass.
@ -27,13 +29,13 @@ async_test(t => {
window.onload = t.step_func(() => {
step_timeout(() => {
var script = document.createElement("script");
script.src = "stale-script.py";
script.src = "stale-script.py?token=" + request_token;
document.body.appendChild(script);
script.onload = t.step_func(() => {
assert_equals(last_modified_count, 2, "last modified");
var checkResult = () => {
// We poll because we don't know when the revalidation will occur.
fetch("stale-script.py?query").then(t.step_func((response) => {
fetch("stale-script.py?query&token=" + request_token).then(t.step_func((response) => {
var count = response.headers.get("Count");
if (count == '2') {
t.done();
@ -49,7 +51,7 @@ async_test(t => {
}, 'Cache returns stale resource');
var script = document.createElement("script");
script.src = "stale-script.py";
script.src = "stale-script.py?token=" + request_token;
document.body.appendChild(script);
</script>
</body>

View file

@ -0,0 +1,58 @@
// META: script=/common/get-host-info.sub.js
[
"frame", // This works without <frameset>, so great
"iframe",
"object",
"embed",
].forEach(element => {
[
null,
"",
"initialvalue"
].forEach(initialNameValue => {
[
"same-origin",
"cross-origin"
].forEach(originType => {
async_test(t => {
const ident = element + initialNameValue + originType,
file = `${new URL("resources/post-to-parent.html", location.href).pathname}?ident=${ident}`,
child = originType === "same-origin" ? file : `${get_host_info().HTTP_REMOTE_ORIGIN}${file}`,
frame = document.createElement(element),
expectedNameValue = initialNameValue || "";
let state = "set";
const listener = t.step_func(e => {
if (e.data.ident === ident) {
assert_equals(e.data.name, expectedNameValue); // This check is always the same
if (state === "set") {
frame.setAttribute("name", "meh");
state = "remove"
e.source.postMessage(null, "*");
return;
}
if (state === "remove") {
frame.removeAttribute("name");
state = "done";
e.source.postMessage(null, "*");
return;
}
if (state === "done") {
t.done();
}
}
});
frame.setAttribute(element === "object" ? "data" : "src", child);
if (initialNameValue !== null) {
frame.setAttribute("name", initialNameValue);
}
t.add_cleanup(() => {
self.removeEventListener("message", listener);
frame.remove();
});
self.addEventListener("message", listener);
document.body.append(frame);
}, `${originType} <${element}${initialNameValue !== null ? ' name=' + initialNameValue : ''}>`);
});
});
});

View file

@ -0,0 +1,6 @@
<script>
const ident = new URL(location).searchParams.get("ident"),
post = () => parent.postMessage({ name: window.name, ident }, "*");
onmessage = () => post();
post();
</script>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>&lt;form rel> with &lt;base target></title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src=resources/reltester.js></script>
<base target=_blank>
<div id=log></div>
<form action=resources/endpoint.html><input type=hidden name=channelname></form>
<script>
const submitter = document.querySelector("form"),
channelInput = document.querySelector("input");
relTester(submitter, channelInput, "<base target>");
</script>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>&lt;form rel> with &lt;button formtarget></title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src=resources/reltester.js></script>
<div id=log></div>
<form action=resources/endpoint.html><input type=hidden name=channelname><button type=submit formtarget=_blank></form>
<script>
const submitter = document.querySelector("button"),
channelInput = document.querySelector("input");
relTester(submitter, channelInput, "<button formtarget>");
</script>

View file

@ -0,0 +1,12 @@
<!DOCTYPE html>
<title>&lt;form rel target></title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src=resources/reltester.js></script>
<div id=log></div>
<form action=resources/endpoint.html target=_blank><input type=hidden name=channelname></form>
<script>
const submitter = document.querySelector("form"),
channelInput = document.querySelector("input");
relTester(submitter, channelInput, "<form target>");
</script>

View file

@ -0,0 +1,13 @@
<!DOCTYPE html>
<title>&lt;form rel> with &lt;input formtarget></title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src=resources/reltester.js></script>
<base target=_blank>
<div id=log></div>
<form action=resources/endpoint.html><input type=hidden name=channelname><input type=submit formtarget=_blank></form>
<script>
const submitter = document.querySelector("input[type=submit]"),
channelInput = document.querySelector("input");
relTester(submitter, channelInput, "<input formtarget>");
</script>

View file

@ -0,0 +1,11 @@
<script>
const channelName = new URL(location).searchParams.get("channelname"),
channel = new BroadcastChannel(channelName);
channel.postMessage({ haveOpener: window.opener !== null,
referrer: document.referrer });
// Because messages are not delivered synchronously and because closing a
// browsing context prompts the eventual clearing of all task sources, this
// document should not be closed until the opener document has confirmed
// receipt.
channel.onmessage = () => window.close();
</script>

View file

@ -0,0 +1,65 @@
function relTester(submitter, channelInput, title) {
[
{
rel: "",
exposed: "all"
},
{
rel: "noopener",
exposed: "noopener"
},
{
rel: "noreferrer",
exposed: "noreferrer"
},
{
rel: "opener",
exposed: "all"
},
{
rel: "noopener noreferrer",
exposed: "noreferrer"
},
{
rel: "noreferrer opener",
exposed: "noreferrer"
},
{
rel: "opener noopener",
exposed: "noopener"
}
].forEach(relTest => {
// Use promise_test to submit only after one test concluded
promise_test(t => {
return new Promise(resolve => {
const channelName = Date.now() + relTest.rel,
channel = new BroadcastChannel(channelName);
let form = submitter;
if (submitter.localName !== "form") {
form = submitter.form;
}
form.rel = relTest.rel;
channelInput.value = channelName;
if (submitter.localName !== "form") {
submitter.click();
} else {
submitter.submit();
}
channel.onmessage = t.step_func(e => {
if (relTest.exposed === "all" || relTest.exposed === "noopener") {
assert_equals(e.data.referrer, window.location.href, "referrer");
} else {
assert_equals(e.data.referrer, "", "referrer");
}
if (relTest.exposed === "all") {
assert_true(e.data.haveOpener, "opener");
} else {
assert_false(e.data.haveOpener, "opener");
}
resolve();
});
t.add_cleanup(() => channel.postMessage(null));
});
}, `<form rel="${relTest.rel}"> with ${title}`);
});
}

View file

@ -15,7 +15,7 @@ link_support_table['link'] = {
'noreferrer', 'noopener']
};
link_support_table['a'] = {
supported : ['noreferrer', 'noopener'],
supported : ['noreferrer', 'noopener', 'opener'],
unsupported : ['author', 'bookmark', 'external', 'help', 'license',
'nofollow', 'pingback', 'prev', 'search', 'tag',
'modulepreload', 'preload', 'preconnect', 'dns-prefetch',
@ -24,6 +24,7 @@ link_support_table['a'] = {
'apple-touch-icon-precomposed', 'canonical']
};
link_support_table['area'] = link_support_table['a'];
link_support_table['form'] = link_support_table['form'];
function test_rellist(tag_name, rel_table) {
let element = document.createElement(tag_name);
@ -77,5 +78,6 @@ test(function() {
test_rellist('LINK', link_support_table['link']);
test_rellist('A', link_support_table['a']);
test_rellist('AREA', link_support_table['area']);
test_rellist('FORM', link_support_table['form']);
}, 'Make sure that relList based feature detection is working');
</script>

View file

@ -10,7 +10,7 @@ partial interface Document {
interface FontMetrics {
readonly attribute double width;
readonly attribute sequence<double> advances;
readonly attribute FrozenArray<double> advances;
readonly attribute double boundingBoxLeft;
readonly attribute double boundingBoxRight;
@ -24,8 +24,8 @@ interface FontMetrics {
readonly attribute double fontBoundingBoxDescent;
readonly attribute Baseline dominantBaseline;
readonly attribute sequence<Baseline> baselines;
readonly attribute sequence<Font> fonts;
readonly attribute FrozenArray<Baseline> baselines;
readonly attribute FrozenArray<Font> fonts;
};
interface Baseline {

View file

@ -725,6 +725,8 @@ interface HTMLFormElement : HTMLElement {
[CEReactions] attribute DOMString name;
[CEReactions] attribute boolean noValidate;
[CEReactions] attribute DOMString target;
[CEReactions] attribute DOMString rel;
[SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
[SameObject] readonly attribute HTMLFormControlsCollection elements;
readonly attribute unsigned long length;

View file

@ -5,7 +5,7 @@
[SecureContext]
interface mixin NavigatorStorage {
readonly attribute StorageManager storage;
[SameObject] readonly attribute StorageManager storage;
};
Navigator includes NavigatorStorage;
WorkerNavigator includes NavigatorStorage;

View file

@ -75,10 +75,4 @@ dictionary NFCReaderOptions {
USVString url = "";
NFCRecordType recordType;
USVString mediaType = "";
NFCAccept accept = "web-nfc-only";
};
enum NFCAccept {
"web-nfc-only",
"any"
};

View file

@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>KV Storage: backingStore getter</title>
<!-- See https://github.com/WICG/kv-storage/issues/45 -->
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script type="module">
import { storage } from "std:kv-storage";
test(() => {
assert_equals(storage.backingStore, storage.backingStore);
}, "backingStore must return the same object each time");
test(() => {
assert_true(Object.isFrozen(storage.backingStore));
}, "backingStore must be a frozen object");
test(() => {
const { backingStore } = storage;
assert_array_equals(Object.keys(backingStore), ["database", "store", "version"], "property names");
assert_array_equals(Object.getOwnPropertySymbols(backingStore), [], "no symbols")
assert_own_property(backingStore, "database");
assert_own_property(backingStore, "store");
assert_own_property(backingStore, "version");
assert_equals(Object.getPrototypeOf(backingStore), Object.prototype);
assert_equals(backingStore.database, "kv-storage:default");
assert_equals(backingStore.store, "store");
assert_equals(backingStore.version, 1);
}, "backingStore object must have the right shape");
</script>

View file

@ -7,7 +7,7 @@
<script src="/IndexedDB/support-promises.js"></script>
<script type="module">
import { testWithArea } from "./helpers/kvs-tests.js";
import { testWithArea, testWithAreaNoCleanup } from "./helpers/kvs-tests.js";
const mustFail = {
"set()": area => area.set(1, "value 1"),
@ -29,7 +29,7 @@ const mustFail = {
for (const [method, testFn] of Object.entries(mustFail)) {
testWithArea(async (area, t) => {
const { database, store, version } = area.backingStore;
const { database, version } = area.backingStore;
const db = await migrateNamedDatabase(t, database, version + 1, () => {});
const result = testFn(area);
@ -37,8 +37,8 @@ for (const [method, testFn] of Object.entries(mustFail)) {
await promise_rejects(t, "VersionError", result);
}, `${method}: upgrading the database must cause a "VersionError" DOMException`);
testWithArea(async (area, t) => {
const { database, store } = area.backingStore;
testWithAreaNoCleanup(async (area, t) => {
const { database } = area.backingStore;
// Set up a new database with that name, but with no object stores!
// NB: this depends on the fact that createNameDatabase sets the initial version to 1, which is
@ -47,7 +47,69 @@ for (const [method, testFn] of Object.entries(mustFail)) {
const result = testFn(area);
await promise_rejects(t, "NotFoundError", result);
}, `${method}: creating a same-named database with no object store must cause a "NotFoundError" DOMException`);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with no object store must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore("wrongName");
});
const result = testFn(area);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with a single object store with the wrong name must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store);
db.createObjectStore("wrongName");
});
const result = testFn(area);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database with more than one object store must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store, { autoIncrement: true });
});
const result = testFn(area);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (autoIncrement = true) must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
db.createObjectStore(store, { keyPath: "somekey" });
});
const result = testFn(area);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (keyPath != null) must cause an "InvalidStateError" DOMException`);
testWithAreaNoCleanup(async (area, t) => {
const { database, store } = area.backingStore;
const db = await createNamedDatabase(t, database, db => {
const s = db.createObjectStore(store);
s.createIndex("index", "indexKey");
});
const result = testFn(area);
await promise_rejects(t, "InvalidStateError", result);
}, `${method}: creating a same-named database the right object store but a bad schema (has indices) must cause an "InvalidStateError" DOMException`);
}
</script>

View file

@ -1,6 +1,17 @@
import { StorageArea, storage as defaultArea } from "std:kv-storage";
import { assertAsyncIteratorEquals, assertAsyncIteratorCustomEquals } from "./equality-asserters.js";
// Used when we're manually creating the database, and so the IDB helpers also want to clean it up.
// If we used testWithArea, then the IDB helpers would time out in their cleanup steps when they
// fail to delete the already-deleted database.
export function testWithAreaNoCleanup(testFn, description) {
promise_test(t => {
const area = new StorageArea(description);
return testFn(area, t);
}, description);
}
export function testWithArea(testFn, description) {
promise_test(t => {
const area = new StorageArea(description);

View file

@ -9,19 +9,6 @@
import { testVariousMethodsWithDefaultArea } from "./helpers/kvs-tests.js";
import { storage } from "std:kv-storage";
test(() => {
const { backingStore } = storage;
assert_array_equals(Object.keys(backingStore), ["database", "store", "version"]);
assert_own_property(backingStore, "database");
assert_own_property(backingStore, "store");
assert_own_property(backingStore, "version");
assert_equals(Object.getPrototypeOf(backingStore), Object.prototype);
assert_equals(backingStore.database, "kv-storage:default");
assert_equals(backingStore.store, "store");
assert_equals(backingStore.version, 1);
}, "backingStore returns the correct object");
testVariousMethodsWithDefaultArea(
"Storage methods smoke test with string key and value", "key", "value", assert_equals
);

View file

@ -1,66 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Manual test for multiple PaymentRequest.show()</title>
<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
setup({
allow_uncaught_exception: true,
});
const defaultMethods = Object.freeze([
{ supportedMethods: "basic-card" },
{
supportedMethods: "https://apple.com/apple-pay",
data: {
version: 3,
merchantIdentifier: "merchant.com.example",
countryCode: "US",
merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"],
}
},
]);
const defaultDetails = Object.freeze({
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00",
},
},
});
function testCallingShowMultipleTimes() {
promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails);
const p1 = request.show();
const p2 = request.show();
const p3 = request.show();
const promises = new Set([p1, p2, p3]);
await request.abort();
assert_equals(promises.size, 3, "Must have three unique objects");
await promise_rejects(t, "AbortError", p1);
await promise_rejects(t, "InvalidStateError", p2);
await promise_rejects(t, "InvalidStateError", p3);
}, "Calling show() multiple times is always a new object.");
}
</script>
<h2>Manual test for multiple PaymentRequest.show()</h2>
<p>
Click on the button to bring up the Payment Request UI window and then will
close it automatically. (If a payment sheet stays open, the test has failed.)
</p>
<ul>
<li>
<button onclick="testCallingShowMultipleTimes()">
Calling show() multiple times is always a new object.
</button>
</li>
</ul>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>

View file

@ -1,97 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Manual tests for PaymentRequest.show() method</title>
<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
"use strict";
setup({
explicit_done: true,
explicit_timeout: true,
});
const defaultMethods = Object.freeze([
{ supportedMethods: "basic-card" },
{
supportedMethods: "https://apple.com/apple-pay",
data: {
version: 3,
merchantIdentifier: "merchant.com.example",
countryCode: "US",
merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"],
}
},
]);
const defaultDetails = Object.freeze({
total: {
label: "Total",
amount: {
currency: "USD",
value: "1.00",
},
},
});
function testThrowsIfStateIsNotCreated() {
promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails);
const acceptPromise = request.show(); // Sets state to "interactive"
await promise_rejects(t, "InvalidStateError", request.show());
await request.abort();
await promise_rejects(t, "AbortError", acceptPromise);
}, "Throws if the promise [[state]] is not 'created'.");
}
function testPaymentRequestIsShowingBoolean() {
promise_test(async t => {
const request1 = new PaymentRequest(defaultMethods, defaultDetails);
const request2 = new PaymentRequest(defaultMethods, defaultDetails);
const acceptPromise1 = request1.show();
const acceptPromise2 = request2.show();
await promise_rejects(t, "AbortError", acceptPromise2);
await request1.abort();
await promise_rejects(t, "AbortError", acceptPromise1);
}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
}
function testNotSupportedError() {
promise_test(async t => {
const request = new PaymentRequest(
[{ supportedMethods: "this-is-not-supported" }],
defaultDetails
);
const acceptPromise = request.show();
await promise_rejects(t, "NotSupportedError", acceptPromise);
}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
}
</script>
<h2>Manual tests for PaymentRequest.show() method</h2>
<p>
Click on each button in sequence from top to bottom without refreshing the
page. Each button will bring up the Payment Request UI window and then will
close it automatically. (If a payment sheet stays open, the test has failed.)
</p>
<ol>
<li>
<button onclick="testThrowsIfStateIsNotCreated()">
Throws if the promise [[state]] is not 'created'.
</button>
</li>
<li>
<button onclick="testPaymentRequestIsShowingBoolean()">
If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.
</button>
</li>
<li>
<button onclick="testNotSupportedError()">
If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.
</button>
</li>
<li><button onclick="done()">Done!</button></li>
</ol>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>

View file

@ -4,6 +4,8 @@
<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
"use strict";
const defaultMethods = Object.freeze([
@ -33,8 +35,80 @@ const defaultDetails = Object.freeze({
promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails);
const acceptPromise = request.show();
// Abort the request after 2 seconds if it has not rejected. This allows the
// other tests in this file to run even if a non-compliant browser shows the
// payment sheet without user activation.
t.step_timeout(() => {
t.force_timeout();
request.abort();
}, 2000);
await promise_rejects(t, "SecurityError", acceptPromise);
}, `Calling show() without being triggered by user interaction throws`);
promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails);
const [acceptPromise] = await test_driver.bless(
"test: throws if the promise [[state]] is not 'created'",
() => {
const acceptPromise = request.show(); // Sets state to "interactive"
return [acceptPromise];
});
await promise_rejects(t, "InvalidStateError", request.show());
await request.abort();
await promise_rejects(t, "AbortError", acceptPromise);
}, "Throws if the promise [[state]] is not 'created'.");
promise_test(async t => {
const request1 = new PaymentRequest(defaultMethods, defaultDetails);
const request2 = new PaymentRequest(defaultMethods, defaultDetails);
const [acceptPromise1] = await test_driver.bless(
`test: reject promise with "AbortedError" if payment request is already showing`,
async () => {
const acceptPromise1 = request1.show();
const acceptPromise2 = request2.show();
await promise_rejects(t, "AbortError", acceptPromise2);
return [acceptPromise1];
});
await request1.abort();
await promise_rejects(t, "AbortError", acceptPromise1);
}, `If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException.`);
promise_test(async t => {
const request = new PaymentRequest(
[{ supportedMethods: "this-is-not-supported" }],
defaultDetails
);
const [acceptPromise] = await test_driver.bless(
`test: reject promise with "NotSupportedError"`,
() => {
const acceptPromise = request.show();
return [acceptPromise];
});
await promise_rejects(t, "NotSupportedError", acceptPromise);
}, `If payment method consultation produces no supported method of payment, then return a promise rejected with a "NotSupportedError" DOMException.`);
promise_test(async t => {
const request = new PaymentRequest(defaultMethods, defaultDetails);
const [p1, p2, p3] = await test_driver.bless(
`test: calling show() multiple times always returns a new promise`,
() => {
const p1 = request.show();
const p2 = request.show();
const p3 = request.show();
return [p1, p2, p3];
});
const promises = new Set([p1, p2, p3]);
assert_equals(promises.size, 3, "Must have three unique objects");
await promise_rejects(t, "InvalidStateError", p2);
await promise_rejects(t, "InvalidStateError", p3);
await request.abort();
await promise_rejects(t, "AbortError", p1);
}, "Calling show() multiple times always returns a new promise.");
</script>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>

View file

@ -199,25 +199,68 @@
window.test_driver_internal = {
/**
* Triggers a user-initiated click
* This flag should be set to `true` by any code which implements the
* internal methods defined below for automation purposes. Doing so
* allows the library to signal failure immediately when an automated
* implementation of one of the methods is not available.
*/
in_automation: false,
/**
* Waits for a user-initiated click
*
* @param {Element} element - element to be clicked
* @param {{x: number, y: number} coords - viewport coordinates to click at
* @returns {Promise} fulfilled after click occurs or rejected if click fails
* @returns {Promise} fulfilled after click occurs
*/
click: function(element, coords) {
return Promise.reject(new Error("unimplemented"));
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
}
return new Promise(function(resolve, reject) {
element.addEventListener("click", resolve);
});
},
/**
* Triggers a user-initiated click
* Waits for an element to receive a series of key presses
*
* @param {Element} element - element to be clicked
* @param {String} keys - keys to send to the element
* @returns {Promise} fulfilled after keys are sent or rejected if click fails
* @param {Element} element - element which should receve key presses
* @param {String} keys - keys to expect
* @returns {Promise} fulfilled after keys are received or rejected if
* an incorrect key sequence is received
*/
send_keys: function(element, keys) {
return Promise.reject(new Error("unimplemented"));
if (this.in_automation) {
return Promise.reject(new Error('Not implemented'));
}
return new Promise(function(resolve, reject) {
var seen = "";
function remove() {
element.removeEventListener("keydown", onKeyDown);
}
function onKeyDown(event) {
if (event.key.length > 1) {
return;
}
seen += event.key;
if (keys.indexOf(seen) !== 0) {
reject(new Error("Unexpected key sequence: " + seen));
remove();
} else if (seen === keys) {
resolve();
remove();
}
}
element.addEventListener("keydown", onKeyDown);
});
},
/**

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<meta charset=utf-8>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=/common/get-host-info.sub.js></script>
<script src=/feature-policy/resources/featurepolicy.js></script>
<script>
'use strict';
async function gDM({audio, video}) {
let stream;
try {
stream = await navigator.mediaDevices.getDisplayMedia({audio, video});
if (stream.getVideoTracks().length == 0) {
throw {name: `requested video track must be present with ` +
`audio ${audio} and video ${video}, or fail`};
}
} finally {
if (stream) {
stream.getTracks().forEach(track => track.stop());
}
}
}
const cross_domain = get_host_info().HTTPS_REMOTE_ORIGIN;
run_all_fp_tests_allow_self(
cross_domain,
'display-capture',
'NotAllowedError',
async () => {
await gDM({video: true});
await gDM({audio: true, video: true});
await gDM({audio: true});
}
);
</script>
</body>

View file

@ -6,6 +6,7 @@ import logging
import os
import shutil
import subprocess
import sys
browser_specific_args = {
"firefox": ["--install-browser"]
@ -38,8 +39,7 @@ def main(product, commit_range, wpt_args):
)
logger.addHandler(handler)
child = subprocess.Popen(['python', './wpt', 'manifest-download'])
child.wait()
subprocess.call(['python', './wpt', 'manifest-download'])
if commit_range:
logger.info(
@ -65,7 +65,9 @@ def main(product, commit_range, wpt_args):
logger.info("Executing command: %s" % " ".join(command))
subprocess.check_call(command)
retcode = subprocess.call(command)
if retcode != 0:
sys.exit(retcode)
wptreport = find_wptreport(wpt_args)
if wptreport:

View file

@ -51,6 +51,8 @@
return selector;
};
window.test_driver_internal.in_automation = true;
window.test_driver_internal.click = function(element) {
const selector = get_selector(element);
const pending_promise = new Promise(function(resolve, reject) {

View file

@ -0,0 +1,127 @@
from tests.support.asserts import assert_error, assert_success
def execute_async_script(session, script, args=None):
if args is None:
args = []
body = {"script": script, "args": args}
return session.transport.send(
"POST", "/session/{session_id}/execute/async".format(**vars(session)),
body)
def test_promise_resolve(session):
response = execute_async_script(session, """
let resolve = arguments[0];
resolve(Promise.resolve('foobar'));
""")
assert_success(response, "foobar")
def test_promise_resolve_delayed(session):
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = new Promise(
(resolve) => setTimeout(
() => resolve('foobar'),
50
)
);
resolve(promise);
""")
assert_success(response, "foobar")
def test_promise_all_resolve(session):
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = Promise.all([
Promise.resolve(1),
Promise.resolve(2)
]);
resolve(promise);
""")
assert_success(response, [1, 2])
def test_await_promise_resolve(session):
response = execute_async_script(session, """
let resolve = arguments[0];
let res = await Promise.resolve('foobar');
resolve(res);
""")
assert_success(response, "foobar")
def test_promise_resolve_timeout(session):
session.timeouts.script = .1
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = new Promise(
(resolve) => setTimeout(
() => resolve(),
1000
)
);
resolve(promise);
""")
assert_error(response, "script timeout")
def test_promise_reject(session):
response = execute_async_script(session, """
let resolve = arguments[0];
resolve(Promise.reject(new Error('my error')));
""")
assert_error(response, "javascript error")
def test_promise_reject_delayed(session):
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = new Promise(
(resolve, reject) => setTimeout(
() => reject(new Error('my error')),
50
)
);
resolve(promise);
""")
assert_error(response, "javascript error")
def test_promise_all_reject(session):
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = Promise.all([
Promise.resolve(1),
Promise.reject(new Error('error'))
]);
resolve(promise);
""")
assert_error(response, "javascript error")
def test_await_promise_reject(session):
response = execute_async_script(session, """
let resolve = arguments[0];
await Promise.reject(new Error('my error'));
resolve('foo');
""")
assert_error(response, "javascript error")
def test_promise_reject_timeout(session):
session.timeouts.script = .1
response = execute_async_script(session, """
let resolve = arguments[0];
let promise = new Promise(
(resolve, reject) => setTimeout(
() => reject(new Error('my error')),
1000
)
);
resolve(promise);
""")
assert_error(response, "script timeout")

View file

@ -1,6 +1,4 @@
import pytest
from tests.support.asserts import assert_dialog_handled, assert_error, assert_success
from tests.support.asserts import assert_error, assert_success
def execute_script(session, script, args=None):
@ -45,12 +43,25 @@ def test_promise_all_resolve(session):
def test_await_promise_resolve(session):
response = execute_script(session, """
const res = await Promise.resolve('foobar');
let res = await Promise.resolve('foobar');
return res;
""")
assert_success(response, "foobar")
def test_promise_resolve_timeout(session):
session.timeouts.script = .1
response = execute_script(session, """
return new Promise(
(resolve) => setTimeout(
() => resolve(),
1000
)
);
""")
assert_error(response, "script timeout")
def test_promise_reject(session):
response = execute_script(session, """
return Promise.reject(new Error('my error'));
@ -88,19 +99,6 @@ def test_await_promise_reject(session):
assert_error(response, "javascript error")
def test_promise_resolve_timeout(session):
session.timeouts.script = .1
response = execute_script(session, """
return new Promise(
(resolve) => setTimeout(
() => resolve(),
1000
)
);
""")
assert_error(response, "timeout error")
def test_promise_reject_timeout(session):
session.timeouts.script = .1
response = execute_script(session, """
@ -111,4 +109,4 @@ def test_promise_reject_timeout(session):
)
);
""")
assert_error(response, "timeout error")
assert_error(response, "script timeout")

View file

@ -1,5 +1,6 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: timeout=long
// https://www.khronos.org/registry/webgl/specs/latest/1.0/

View file

@ -1,5 +1,6 @@
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js
// META: timeout=long
// https://www.khronos.org/registry/webgl/specs/latest/1.0/