Auto merge of #21867 - servo-wpt-sync:wpt_update_03-10-2018, r=jdm

Sync WPT with upstream (03-10-2018)

Automated downstream sync of changes from upstream as of 03-10-2018.
[no-wpt-sync]

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/21867)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-10-04 03:15:13 -04:00 committed by GitHub
commit caa4d190af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 1403 additions and 821 deletions

View file

@ -125643,6 +125643,42 @@
{} {}
] ]
], ],
"css/css-masking/clip-path/clip-path-inline-001.html": [
[
"/css/css-masking/clip-path/clip-path-inline-001.html",
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"css/css-masking/clip-path/clip-path-inline-002.html": [
[
"/css/css-masking/clip-path/clip-path-inline-002.html",
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"css/css-masking/clip-path/clip-path-inline-003.html": [
[
"/css/css-masking/clip-path/clip-path-inline-003.html",
[
[
"/css/reference/ref-filled-green-100px-square.xht",
"=="
]
],
{}
]
],
"css/css-masking/clip-path/clip-path-path-001.html": [ "css/css-masking/clip-path/clip-path-path-001.html": [
[ [
"/css/css-masking/clip-path/clip-path-path-001.html", "/css/css-masking/clip-path/clip-path-path-001.html",
@ -137395,6 +137431,18 @@
{} {}
] ]
], ],
"css/css-text/overflow-wrap/overflow-wrap-break-word-004.html": [
[
"/css/css-text/overflow-wrap/overflow-wrap-break-word-004.html",
[
[
"/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html",
"=="
]
],
{}
]
],
"css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [ "css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [
[ [
"/css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html", "/css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html",
@ -139231,6 +139279,18 @@
{} {}
] ]
], ],
"css/css-text/white-space/pre-wrap-015.html": [
[
"/css/css-text/white-space/pre-wrap-015.html",
[
[
"/css/css-text/white-space/reference/pre-wrap-001-ref.html",
"=="
]
],
{}
]
],
"css/css-text/white-space/textarea-break-spaces-001.html": [ "css/css-text/white-space/textarea-break-spaces-001.html": [
[ [
"/css/css-text/white-space/textarea-break-spaces-001.html", "/css/css-text/white-space/textarea-break-spaces-001.html",
@ -139555,6 +139615,42 @@
{} {}
] ]
], ],
"css/css-text/word-break/word-break-break-all-010.html": [
[
"/css/css-text/word-break/word-break-break-all-010.html",
[
[
"/css/css-text/word-break/reference/word-break-break-all-010-ref.html",
"=="
]
],
{}
]
],
"css/css-text/word-break/word-break-break-all-011.html": [
[
"/css/css-text/word-break/word-break-break-all-011.html",
[
[
"/css/css-text/word-break/reference/word-break-break-all-010-ref.html",
"=="
]
],
{}
]
],
"css/css-text/word-break/word-break-break-all-014.html": [
[
"/css/css-text/word-break/word-break-break-all-014.html",
[
[
"/css/css-text/word-break/reference/word-break-break-all-014-ref.html",
"=="
]
],
{}
]
],
"css/css-text/word-break/word-break-keep-all-000.html": [ "css/css-text/word-break/word-break-keep-all-000.html": [
[ [
"/css/css-text/word-break/word-break-keep-all-000.html", "/css/css-text/word-break/word-break-keep-all-000.html",
@ -198767,11 +198863,6 @@
{} {}
] ]
], ],
"beacon/navigate.iFrame.sub.html": [
[
{}
]
],
"beacon/resources/beacon.py": [ "beacon/resources/beacon.py": [
[ [
{} {}
@ -265762,6 +265853,16 @@
{} {}
] ]
], ],
"css/css-text/word-break/reference/word-break-break-all-010-ref.html": [
[
{}
]
],
"css/css-text/word-break/reference/word-break-break-all-014-ref.html": [
[
{}
]
],
"css/css-text/word-break/reference/word-break-break-all-ref-000.html": [ "css/css-text/word-break/reference/word-break-break-all-ref-000.html": [
[ [
{} {}
@ -283657,6 +283758,21 @@
{} {}
] ]
], ],
"html/browsers/offline/appcache/resources/appcache-data.py": [
[
{}
]
],
"html/browsers/offline/appcache/resources/appcache-iframe.manifest": [
[
{}
]
],
"html/browsers/offline/appcache/resources/appcache-iframe.py": [
[
{}
]
],
"html/browsers/offline/appcache/workers/resources/appcache-dedicated-worker-not-in-cache.js": [ "html/browsers/offline/appcache/workers/resources/appcache-dedicated-worker-not-in-cache.js": [
[ [
{} {}
@ -294027,6 +294143,11 @@
{} {}
] ]
], ],
"interfaces/wasm-web-api.idl": [
[
{}
]
],
"interfaces/web-animations.idl": [ "interfaces/web-animations.idl": [
[ [
{} {}
@ -358201,6 +358322,12 @@
{} {}
] ]
], ],
"html/browsers/browsing-the-web/history-traversal/scroll-restoration-order.html": [
[
"/html/browsers/browsing-the-web/history-traversal/scroll-restoration-order.html",
{}
]
],
"html/browsers/browsing-the-web/history-traversal/unset_context_name-1.html": [ "html/browsers/browsing-the-web/history-traversal/unset_context_name-1.html": [
[ [
"/html/browsers/browsing-the-web/history-traversal/unset_context_name-1.html", "/html/browsers/browsing-the-web/history-traversal/unset_context_name-1.html",
@ -359291,6 +359418,12 @@
{} {}
] ]
], ],
"html/browsers/offline/appcache/appcache-iframe.https.html": [
[
"/html/browsers/offline/appcache/appcache-iframe.https.html",
{}
]
],
"html/browsers/offline/appcache/workers/appcache-worker.https.html": [ "html/browsers/offline/appcache/workers/appcache-worker.https.html": [
[ [
"/html/browsers/offline/appcache/workers/appcache-worker.https.html", "/html/browsers/offline/appcache/workers/appcache-worker.https.html",
@ -372885,6 +373018,12 @@
{} {}
] ]
], ],
"mediacapture-streams/MediaStream-clone.https.html": [
[
"/mediacapture-streams/MediaStream-clone.https.html",
{}
]
],
"mediacapture-streams/MediaStream-default-feature-policy.https.html": [ "mediacapture-streams/MediaStream-default-feature-policy.https.html": [
[ [
"/mediacapture-streams/MediaStream-default-feature-policy.https.html", "/mediacapture-streams/MediaStream-default-feature-policy.https.html",
@ -402043,6 +402182,24 @@
{} {}
] ]
], ],
"wasm/webapi/contenttype.any.js": [
[
"/wasm/webapi/contenttype.any.html",
{}
],
[
"/wasm/webapi/contenttype.any.serviceworker.html",
{}
],
[
"/wasm/webapi/contenttype.any.sharedworker.html",
{}
],
[
"/wasm/webapi/contenttype.any.worker.html",
{}
]
],
"web-animations/animation-model/animation-types/accumulation-per-property.html": [ "web-animations/animation-model/animation-types/accumulation-per-property.html": [
[ [
"/web-animations/animation-model/animation-types/accumulation-per-property.html", "/web-animations/animation-model/animation-types/accumulation-per-property.html",
@ -442447,11 +442604,11 @@
"testharness" "testharness"
], ],
"beacon/beacon-common.sub.js": [ "beacon/beacon-common.sub.js": [
"0a36283b26379e16ccfd2c33cf05e0395dc18331", "ae2f169f272e9efbbea3b7464ea77c34fe65c6e1",
"support" "support"
], ],
"beacon/beacon-cors.sub.window.js": [ "beacon/beacon-cors.sub.window.js": [
"f4bccf177e3b4585a5efe0b6cd0d6edc24fe48f9", "411cd1c94924127ce95c27707d283e7ca342f367",
"testharness" "testharness"
], ],
"beacon/beacon-error.window.js": [ "beacon/beacon-error.window.js": [
@ -442467,7 +442624,7 @@
"testharness" "testharness"
], ],
"beacon/beacon-redirect.window.js": [ "beacon/beacon-redirect.window.js": [
"659759baa3f5c58b26b9ed042047348b67a23e44", "53f229abff1744b5766efe808c00f9b656296391",
"testharness" "testharness"
], ],
"beacon/headers/header-content-type.html": [ "beacon/headers/header-content-type.html": [
@ -442514,10 +442671,6 @@
"958daf4865d1d7c9dfb621a163e15a8862330d2b", "958daf4865d1d7c9dfb621a163e15a8862330d2b",
"testharness" "testharness"
], ],
"beacon/navigate.iFrame.sub.html": [
"f4c7846e522b553985cc0ad253e439bd6d315975",
"support"
],
"beacon/resources/beacon.py": [ "beacon/resources/beacon.py": [
"5f2553d3c4d506f7e292cfb73d81930a83a12d76", "5f2553d3c4d506f7e292cfb73d81930a83a12d76",
"support" "support"
@ -549246,6 +549399,18 @@
"12df558fd2c2fa64783720cb9d1be07fa7f85572", "12df558fd2c2fa64783720cb9d1be07fa7f85572",
"reftest" "reftest"
], ],
"css/css-masking/clip-path/clip-path-inline-001.html": [
"343646464a98b761fa3eee2f37260c9848ef067a",
"reftest"
],
"css/css-masking/clip-path/clip-path-inline-002.html": [
"d56117e22b87975d5367b0af18ebd5ad25cc744a",
"reftest"
],
"css/css-masking/clip-path/clip-path-inline-003.html": [
"4c907a46120da6a774193f83a6c1c89e5bd9b2f2",
"reftest"
],
"css/css-masking/clip-path/clip-path-path-001.html": [ "css/css-masking/clip-path/clip-path-path-001.html": [
"ebdfc2297bbcc8225f92ba9dfa2ed33819f2f9a9", "ebdfc2297bbcc8225f92ba9dfa2ed33819f2f9a9",
"reftest" "reftest"
@ -549595,7 +549760,7 @@
"support" "support"
], ],
"css/css-masking/mask-svg-content/reference/mask-text-001-ref.svg": [ "css/css-masking/mask-svg-content/reference/mask-text-001-ref.svg": [
"48737c03d1e9d8be22b67c990be0d3ff9b420160", "3fabeb01d762fc1eda9eb198b3051d7ad6128361",
"support" "support"
], ],
"css/css-masking/parsing/clip-invalid.html": [ "css/css-masking/parsing/clip-invalid.html": [
@ -550523,7 +550688,7 @@
"reftest" "reftest"
], ],
"css/css-multicol/multicol-span-none-001-ref.xht": [ "css/css-multicol/multicol-span-none-001-ref.xht": [
"5472e779c8d180151a1959f9650b7398dbee50e2", "4fcc57a658894e9ea8b75d80ee96f32353a27637",
"support" "support"
], ],
"css/css-multicol/multicol-span-none-001.xht": [ "css/css-multicol/multicol-span-none-001.xht": [
@ -559570,6 +559735,10 @@
"6203b55e9c6fe73cd317c3d4968c56609209b38d", "6203b55e9c6fe73cd317c3d4968c56609209b38d",
"reftest" "reftest"
], ],
"css/css-text/overflow-wrap/overflow-wrap-break-word-004.html": [
"560ef63b2f94c5eeca83ee5ef63cdfc15fbdfe34",
"reftest"
],
"css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [ "css/css-text/overflow-wrap/overflow-wrap-break-word-fit-content-001.html": [
"bce6c68389c32960d79e8fbbf61f9fa28c733165", "bce6c68389c32960d79e8fbbf61f9fa28c733165",
"reftest" "reftest"
@ -560974,6 +561143,10 @@
"5da564d4b73ed3c7442160bae701e38d6b7fb66a", "5da564d4b73ed3c7442160bae701e38d6b7fb66a",
"reftest" "reftest"
], ],
"css/css-text/white-space/pre-wrap-015.html": [
"f9063c98767e70c3899bc9a59b50b42a61240ae4",
"reftest"
],
"css/css-text/white-space/reference/pre-wrap-001-ref.html": [ "css/css-text/white-space/reference/pre-wrap-001-ref.html": [
"8a8b5132db197bb9a76b1b44e461405f4cd9d1bc", "8a8b5132db197bb9a76b1b44e461405f4cd9d1bc",
"support" "support"
@ -561158,6 +561331,14 @@
"0768b857d96624a63129f002d317019674d1ef0d", "0768b857d96624a63129f002d317019674d1ef0d",
"support" "support"
], ],
"css/css-text/word-break/reference/word-break-break-all-010-ref.html": [
"0e0300a72dc920a5ffb54cda6fbe84a2f517d010",
"support"
],
"css/css-text/word-break/reference/word-break-break-all-014-ref.html": [
"a8720a101c3b2d2616b661e51c60b55b85d2d667",
"support"
],
"css/css-text/word-break/reference/word-break-break-all-ref-000.html": [ "css/css-text/word-break/reference/word-break-break-all-ref-000.html": [
"579c2dc6a06c69bbb7384e51ad4b851e7d7b4410", "579c2dc6a06c69bbb7384e51ad4b851e7d7b4410",
"support" "support"
@ -561334,6 +561515,18 @@
"9a7a591dafd4352f7df11dc9396608027ef80cd6", "9a7a591dafd4352f7df11dc9396608027ef80cd6",
"manual" "manual"
], ],
"css/css-text/word-break/word-break-break-all-010.html": [
"1ab97fb146a984da98a2400af0392187531edadc",
"reftest"
],
"css/css-text/word-break/word-break-break-all-011.html": [
"ed07aeb7368da2273e394011f426c1ee65fe2b25",
"reftest"
],
"css/css-text/word-break/word-break-break-all-014.html": [
"6885553ad685700e89d4d83ded7bc65269aa1123",
"reftest"
],
"css/css-text/word-break/word-break-keep-all-000.html": [ "css/css-text/word-break/word-break-keep-all-000.html": [
"fce7487c33ad47aaeeb20fe5ccb1bc5180192329", "fce7487c33ad47aaeeb20fe5ccb1bc5180192329",
"reftest" "reftest"
@ -599987,7 +600180,7 @@
"support" "support"
], ],
"generic-sensor/generic-sensor-iframe-tests.sub.js": [ "generic-sensor/generic-sensor-iframe-tests.sub.js": [
"97defcba4b2c73544e4842a90dd92ad5294d7791", "c4195fee5f5ed10c4c30f1556e8ad8284f106a8d",
"support" "support"
], ],
"generic-sensor/generic-sensor-tests.js": [ "generic-sensor/generic-sensor-tests.js": [
@ -600598,6 +600791,10 @@
"d7037343d7daae486ba75570ad2dba376b6fd0ef", "d7037343d7daae486ba75570ad2dba376b6fd0ef",
"testharness" "testharness"
], ],
"html/browsers/browsing-the-web/history-traversal/scroll-restoration-order.html": [
"8fe7d9f9770b25177b8eddc3eff9e7ecbcddd0c0",
"testharness"
],
"html/browsers/browsing-the-web/history-traversal/support/window-name-after-cross-origin-main-frame-navigation-popup.sub.html": [ "html/browsers/browsing-the-web/history-traversal/support/window-name-after-cross-origin-main-frame-navigation-popup.sub.html": [
"e13d191658046bd584b1cd5ded7fb8d3aa4604db", "e13d191658046bd584b1cd5ded7fb8d3aa4604db",
"support" "support"
@ -602010,6 +602207,22 @@
"1c45fada5a352f01bb2174cb0ce42e75e5f3d288", "1c45fada5a352f01bb2174cb0ce42e75e5f3d288",
"support" "support"
], ],
"html/browsers/offline/appcache/appcache-iframe.https.html": [
"8e72664371540fe84f8e3d32df3912f8bee28fb3",
"testharness"
],
"html/browsers/offline/appcache/resources/appcache-data.py": [
"f92c5116c0839c344ed02d951d932dc57708b36d",
"support"
],
"html/browsers/offline/appcache/resources/appcache-iframe.manifest": [
"7221e909c6fe6db848c202f8c46544b213eea7aa",
"support"
],
"html/browsers/offline/appcache/resources/appcache-iframe.py": [
"bc82788045fcaf6d841bb58cf905be9a6fa6f767",
"support"
],
"html/browsers/offline/appcache/workers/appcache-worker.https.html": [ "html/browsers/offline/appcache/workers/appcache-worker.https.html": [
"96fe5f2b7d22c1cc208ccb61e25582a24489de0d", "96fe5f2b7d22c1cc208ccb61e25582a24489de0d",
"testharness" "testharness"
@ -602035,7 +602248,7 @@
"support" "support"
], ],
"html/browsers/offline/appcache/workers/resources/appcache-worker.py": [ "html/browsers/offline/appcache/workers/resources/appcache-worker.py": [
"00281a2be72c0b39be4b466e310e850e63ad9ddb", "106432191993d15d04ded140407fee7b52ec68e1",
"support" "support"
], ],
"html/browsers/offline/application-cache-api/api_status_checking-manual.html": [ "html/browsers/offline/application-cache-api/api_status_checking-manual.html": [
@ -619747,7 +619960,7 @@
"support" "support"
], ],
"interfaces/payment-request.idl": [ "interfaces/payment-request.idl": [
"d930b57291e5301e4056d30192726023e9306512", "843c66107b34bbb90aa64411487a09b2fa95e508",
"support" "support"
], ],
"interfaces/performance-timeline.idl": [ "interfaces/performance-timeline.idl": [
@ -619882,6 +620095,10 @@
"6de14fb8f0895a72b69f37b9dd8b72e2ab1604e0", "6de14fb8f0895a72b69f37b9dd8b72e2ab1604e0",
"support" "support"
], ],
"interfaces/wasm-web-api.idl": [
"1cc2f17679b2e89604e0d4a901f0dabbaa6917e5",
"support"
],
"interfaces/web-animations.idl": [ "interfaces/web-animations.idl": [
"7dce1002e666d3efa9b18531e05b087f0f4adc0d", "7dce1002e666d3efa9b18531e05b087f0f4adc0d",
"support" "support"
@ -621630,6 +621847,10 @@
"faa2c39b30f54d5f3a8a38f9a6eeb46e32e722d7", "faa2c39b30f54d5f3a8a38f9a6eeb46e32e722d7",
"testharness" "testharness"
], ],
"mediacapture-streams/MediaStream-clone.https.html": [
"134918815c3d08e20771d6177021cd24c89b4ccb",
"testharness"
],
"mediacapture-streams/MediaStream-default-feature-policy.https.html": [ "mediacapture-streams/MediaStream-default-feature-policy.https.html": [
"21e3f5b9af8567cb015604bbcb021cc04216e4c2", "21e3f5b9af8567cb015604bbcb021cc04216e4c2",
"testharness" "testharness"
@ -621647,7 +621868,7 @@
"manual" "manual"
], ],
"mediacapture-streams/MediaStream-idl.https.html": [ "mediacapture-streams/MediaStream-idl.https.html": [
"8e60709cf1b5f1381bdcd5c4deb5bef3703fea2a", "32e34f2b4b666700aa1879dac251787cf1024ee0",
"testharness" "testharness"
], ],
"mediacapture-streams/MediaStream-removetrack.https.html": [ "mediacapture-streams/MediaStream-removetrack.https.html": [
@ -631883,7 +632104,7 @@
"testharness" "testharness"
], ],
"payment-request/payment-request-id-attribute.https.html": [ "payment-request/payment-request-id-attribute.https.html": [
"455b65a7da32d5e2d7231d4c5bf692826efbf4a4", "e5d0c7a66eee67f529cd48fa640f08481f5e5a38",
"testharness" "testharness"
], ],
"payment-request/payment-request-insecure.http.html": [ "payment-request/payment-request-insecure.http.html": [
@ -647079,7 +647300,7 @@
"testharness" "testharness"
], ],
"speech-api/idlharness.window.js": [ "speech-api/idlharness.window.js": [
"2f9702878a3037c6a6e4df3d6d329827740bf41e", "6cfcbb2e95fd7e3e7d32aab6faae7cb231c6fec6",
"testharness" "testharness"
], ],
"speech-api/webspeech.js": [ "speech-api/webspeech.js": [
@ -656887,7 +657108,7 @@
"support" "support"
], ],
"tools/wptrunner/wptrunner/browsers/fennec.py": [ "tools/wptrunner/wptrunner/browsers/fennec.py": [
"db271acc50ea08e61efd09848a9ff78b53b8ed1e", "ddb1667a22fe39217d4488de6d44a51177a39c32",
"support" "support"
], ],
"tools/wptrunner/wptrunner/browsers/firefox.py": [ "tools/wptrunner/wptrunner/browsers/firefox.py": [
@ -656931,7 +657152,7 @@
"support" "support"
], ],
"tools/wptrunner/wptrunner/browsers/webkit.py": [ "tools/wptrunner/wptrunner/browsers/webkit.py": [
"9482f2f774332476150d3e1bbb452d5545e2ef69", "b09114a9a5444717157edb37c24add6ba99cf421",
"support" "support"
], ],
"tools/wptrunner/wptrunner/config.py": [ "tools/wptrunner/wptrunner/config.py": [
@ -656979,7 +657200,7 @@
"support" "support"
], ],
"tools/wptrunner/wptrunner/executors/executorservo.py": [ "tools/wptrunner/wptrunner/executors/executorservo.py": [
"caa97145560ec1c1d0e78d38cdd7a857c3972d40", "49b682c749f897eb234c6bf4bb7ade3ed021dd7b",
"support" "support"
], ],
"tools/wptrunner/wptrunner/executors/executorservodriver.py": [ "tools/wptrunner/wptrunner/executors/executorservodriver.py": [
@ -657459,7 +657680,7 @@
"support" "support"
], ],
"tools/wptserve/tests/functional/test_pipes.py": [ "tools/wptserve/tests/functional/test_pipes.py": [
"83b2c621641ca17b670eb5a8c08b38f8d37cc2a7", "0299ea0e62b2d97f20054f7aa8f52a497361e472",
"support" "support"
], ],
"tools/wptserve/tests/functional/test_request.py": [ "tools/wptserve/tests/functional/test_request.py": [
@ -657495,7 +657716,7 @@
"support" "support"
], ],
"tools/wptserve/wptserve/constants.py": [ "tools/wptserve/wptserve/constants.py": [
"ec150ba5c8f7a3b89a63903b7dc757c96dfff1a9", "e248280ef36e93832b4c481a102c3177e618c42d",
"support" "support"
], ],
"tools/wptserve/wptserve/handlers.py": [ "tools/wptserve/wptserve/handlers.py": [
@ -657519,7 +657740,7 @@
"support" "support"
], ],
"tools/wptserve/wptserve/response.py": [ "tools/wptserve/wptserve/response.py": [
"44299cc994ef43ebe72053e1444f5af7cd7f9598", "00a609b2950ddbb696bf80f2ec0038f427f8f465",
"support" "support"
], ],
"tools/wptserve/wptserve/router.py": [ "tools/wptserve/wptserve/router.py": [
@ -660026,6 +660247,10 @@
"6f2ccf465e93a160c73df548fc58774a5040f0e6", "6f2ccf465e93a160c73df548fc58774a5040f0e6",
"testharness" "testharness"
], ],
"wasm/webapi/contenttype.any.js": [
"78069c03c9ff44c4b32621f38691d8238c1972e1",
"testharness"
],
"web-animations/META.yml": [ "web-animations/META.yml": [
"bf92f7a7516302641aabcefe3c482ba6889c2c23", "bf92f7a7516302641aabcefe3c482ba6889c2c23",
"support" "support"
@ -660287,7 +660512,7 @@
"testharness" "testharness"
], ],
"web-animations/timing-model/animations/play-states.html": [ "web-animations/timing-model/animations/play-states.html": [
"5d8fdeac6ecc5c2908a2cfe1af9d2176359af0ad", "ec7d8c842fc9329c3508c22916ce59a236006296",
"testharness" "testharness"
], ],
"web-animations/timing-model/animations/playing-an-animation.html": [ "web-animations/timing-model/animations/playing-an-animation.html": [
@ -663067,7 +663292,7 @@
"support" "support"
], ],
"webrtc/RTCIceTransport-extension.https.html": [ "webrtc/RTCIceTransport-extension.https.html": [
"5adee9fbe61eb9a8f7235b7faa6670eaea45cc89", "7803bde9b3aa61f6ac500d62c8a3aed79b1a1412",
"testharness" "testharness"
], ],
"webrtc/RTCIceTransport.html": [ "webrtc/RTCIceTransport.html": [
@ -663087,7 +663312,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-addTransceiver.https.html": [ "webrtc/RTCPeerConnection-addTransceiver.https.html": [
"c0c5d782c2fa365052d08d63eb14954a756c8bc0", "6df056117d02452e040b153147dbdad7bf8fa9bb",
"testharness" "testharness"
], ],
"webrtc/RTCPeerConnection-canTrickleIceCandidates.html": [ "webrtc/RTCPeerConnection-canTrickleIceCandidates.html": [
@ -663235,15 +663460,15 @@
"testharness" "testharness"
], ],
"webrtc/RTCQuicStream.https.html": [ "webrtc/RTCQuicStream.https.html": [
"33025451b252e1bdf2491fa118e072f4b8711d12", "68c88e2757c2ab35736d3480dfbc6095580b06d3",
"testharness" "testharness"
], ],
"webrtc/RTCQuicTransport-helper.js": [ "webrtc/RTCQuicTransport-helper.js": [
"3ea19d7a78e4a3788e97d0fa537d51d4b9e6b4fc", "7e28feae0937d4a28710be5f0e807c4af0f7c039",
"support" "support"
], ],
"webrtc/RTCQuicTransport.https.html": [ "webrtc/RTCQuicTransport.https.html": [
"ec79bc228ad21de3a9ce3c2ee812a7d50e57571b", "3bcc93d95375ccf0bbaa8ba892606099ec8f0bf4",
"testharness" "testharness"
], ],
"webrtc/RTCRtpCapabilities-helper.js": [ "webrtc/RTCRtpCapabilities-helper.js": [
@ -663259,7 +663484,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCRtpParameters-encodings.html": [ "webrtc/RTCRtpParameters-encodings.html": [
"b4a60c8a6d406cd820524679be172aed6cad900b", "b446dde230efbbdb197c7f24f16e2490271563c4",
"testharness" "testharness"
], ],
"webrtc/RTCRtpParameters-headerExtensions.html": [ "webrtc/RTCRtpParameters-headerExtensions.html": [
@ -663267,7 +663492,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCRtpParameters-helper.js": [ "webrtc/RTCRtpParameters-helper.js": [
"9c4b6cd412e451a57318b507f264235ea827fa82", "c4105decdfcb12286d4b153ab07f7be25baf1aad",
"support" "support"
], ],
"webrtc/RTCRtpParameters-rtcp.html": [ "webrtc/RTCRtpParameters-rtcp.html": [
@ -663287,7 +663512,7 @@
"testharness" "testharness"
], ],
"webrtc/RTCRtpReceiver-getParameters.html": [ "webrtc/RTCRtpReceiver-getParameters.html": [
"8b6d648bf616c847d9d8300a09f8ab078ac026ce", "97e5d10d1e53b18d3c9deca969d2046881418569",
"testharness" "testharness"
], ],
"webrtc/RTCRtpReceiver-getStats.https.html": [ "webrtc/RTCRtpReceiver-getStats.https.html": [

View file

@ -0,0 +1,2 @@
[overflow-wrap-break-word-004.html]
expected: FAIL

View file

@ -0,0 +1,2 @@
[word-break-break-all-010.html]
expected: FAIL

View file

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

View file

@ -41,9 +41,6 @@
[outline-width intermediate] [outline-width intermediate]
expected: FAIL expected: FAIL
[outline-width end]
expected: FAIL
[min-width intermediate] [min-width intermediate]
expected: FAIL expected: FAIL
@ -71,9 +68,6 @@
[bottom intermediate] [bottom intermediate]
expected: FAIL expected: FAIL
[right end] [text-indent intermediate]
expected: FAIL
[padding-left intermediate]
expected: FAIL expected: FAIL

View file

@ -1,4 +1,5 @@
[fetch-in-iframe.html] [fetch-in-iframe.html]
expected: CRASH
[Untitled] [Untitled]
expected: FAIL expected: FAIL

View file

@ -0,0 +1,4 @@
[scroll-restoration-order.html]
[Traversing history should restore scroll position after dispatching popstate and before dispatching hashchange]
expected: FAIL

View file

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

View file

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

View file

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

View file

@ -0,0 +1,16 @@
[location-protocol-setter-non-broken-weird.html]
[Set location.protocol to data]
expected: FAIL
[Set location.protocol to ftp]
expected: FAIL
[Set location.protocol to gopher]
expected: FAIL
[Set location.protocol to x]
expected: FAIL
[Set location.protocol to http+x]
expected: FAIL

View file

@ -5,11 +5,29 @@
expected: TIMEOUT expected: TIMEOUT
[picture: source (max-width:500px) valid image, img valid image, resize to wide] [picture: source (max-width:500px) valid image, img valid image, resize to wide]
expected: TIMEOUT expected: FAIL
[picture: source (max-width:500px) valid image, img broken image, resize to narrow] [picture: source (max-width:500px) valid image, img broken image, resize to narrow]
expected: TIMEOUT expected: TIMEOUT
[picture: source (max-width:500px) valid image, img valid image, resize to narrow] [picture: source (max-width:500px) valid image, img valid image, resize to narrow]
expected: TIMEOUT expected: FAIL
[picture: source (max-width:500px) broken image, img valid image, resize to narrow]
expected: FAIL
[img (srcset 1 cand) valid image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to wide]
expected: FAIL
[img (srcset 1 cand) valid image, resize to narrow]
expected: FAIL
[picture: source (max-width:500px) valid image, img broken image, resize to wide]
expected: FAIL
[picture: same URL in source (max-width:500px) and img, resize to narrow]
expected: FAIL

View file

@ -0,0 +1,4 @@
[DOMContentLoaded-defer.html]
[The end: DOMContentLoaded and defer scripts]
expected: FAIL

View file

@ -0,0 +1,4 @@
[aborted-parser.window.html]
[document.open() after parser is aborted]
expected: FAIL

View file

@ -12,3 +12,6 @@
[document.open should throw a SecurityError with cross-origin document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)] [document.open should throw a SecurityError with cross-origin document even when the ignore-opens-during-unload counter is greater than 0 (during pagehide event)]
expected: FAIL expected: FAIL
[document.open should throw a SecurityError with cross-origin document even when there is an active parser executing script]
expected: FAIL

View file

@ -1,283 +0,0 @@
[quirks.html]
[top: -\\31 .5]
expected: FAIL
[bottom: -1A]
expected: FAIL
[bottom: -1a]
expected: FAIL
[top: @1]
expected: FAIL
[top: "1a"]
expected: FAIL
[top: @a]
expected: FAIL
[bottom: "1"]
expected: FAIL
[bottom: -/**/1]
expected: FAIL
[top: +/**/1]
expected: FAIL
[bottom: @1a]
expected: FAIL
[top: 1\\31 ]
expected: FAIL
[top: url('1')]
expected: FAIL
[bottom: -\\31 ]
expected: FAIL
[top: calc(1)]
expected: FAIL
[top: \\31 ]
expected: FAIL
[bottom: +1\\31 ]
expected: FAIL
[bottom: 1\\31 .5]
expected: FAIL
[bottom: #0001]
expected: FAIL
[top: calc(2 * 2px)]
expected: FAIL
[bottom: 1a]
expected: FAIL
[bottom: A]
expected: FAIL
[bottom: #01]
expected: FAIL
[top: +\\31 .5]
expected: FAIL
[bottom: #1]
expected: FAIL
[top: -/**/1]
expected: FAIL
[bottom: +\\31 .5]
expected: FAIL
[bottom: \\31 ]
expected: FAIL
[bottom: calc(1)]
expected: FAIL
[top: #001]
expected: FAIL
[top: +\\31 ]
expected: FAIL
[bottom: +\\31 ]
expected: FAIL
[top: +1.5]
expected: FAIL
[top: +1\\31 ]
expected: FAIL
[bottom: @a]
expected: FAIL
[bottom: @1]
expected: FAIL
[top: #1]
expected: FAIL
[top: 1a]
expected: FAIL
[bottom: +1a]
expected: FAIL
[bottom: +1A]
expected: FAIL
[bottom: "a"]
expected: FAIL
[top: #00001]
expected: FAIL
[bottom: -1\\31 .5]
expected: FAIL
[top: "1"]
expected: FAIL
[bottom: 1.5]
expected: FAIL
[bottom: -\\31 .5]
expected: FAIL
[bottom: url('1')]
expected: FAIL
[bottom: -1.5]
expected: FAIL
[top: \\31 .5]
expected: FAIL
[bottom: "1a"]
expected: FAIL
[bottom: calc(2 * 2px)]
expected: FAIL
[bottom: +1\\31 .5]
expected: FAIL
[bottom: 1\\31 ]
expected: FAIL
[bottom: +/**/1]
expected: FAIL
[bottom: #00001]
expected: FAIL
[top: url(1)]
expected: FAIL
[bottom: #001]
expected: FAIL
[top: +1\\31 .5]
expected: FAIL
[top: -1a]
expected: FAIL
[top: -1A]
expected: FAIL
[bottom: url(1)]
expected: FAIL
[top: a]
expected: FAIL
[top: A]
expected: FAIL
[top: #000001]
expected: FAIL
[top: 1]
expected: FAIL
[top: 1\\31 .5]
expected: FAIL
[bottom: a]
expected: FAIL
[bottom: 1]
expected: FAIL
[bottom: +1]
expected: FAIL
[bottom: #000001]
expected: FAIL
[bottom: +a]
expected: FAIL
[bottom: +A]
expected: FAIL
[top: 1.5]
expected: FAIL
[top: +A]
expected: FAIL
[top: +a]
expected: FAIL
[top: +1]
expected: FAIL
[top: -1.5]
expected: FAIL
[top: -1\\31 .5]
expected: FAIL
[top: +1a]
expected: FAIL
[top: +1A]
expected: FAIL
[top: @1a]
expected: FAIL
[bottom: \\31 .5]
expected: FAIL
[top: "a"]
expected: FAIL
[top: #01]
expected: FAIL
[bottom: +1.5]
expected: FAIL
[bottom: -A]
expected: FAIL
[bottom: -a]
expected: FAIL
[bottom: -1\\31 ]
expected: FAIL
[top: #0001]
expected: FAIL
[bottom: -1]
expected: FAIL
[top: -\\31 ]
expected: FAIL
[top: -A]
expected: FAIL
[top: -a]
expected: FAIL
[top: -1]
expected: FAIL
[top: -1\\31 ]
expected: FAIL

View file

@ -1,26 +1,20 @@
[urlencoded-parser.any.html] [urlencoded-parser.any.html]
[request.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a&b&c] [response.formData() with input: a&b&c]
expected: FAIL expected: FAIL
[request.formData() with input: a&b&c] [request.formData() with input: a&b&c]
expected: FAIL expected: FAIL
[response.formData() with input: a=b&c=d&]
expected: FAIL
[request.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x] [response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&] [response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL expected: FAIL
[response.formData() with input: a=b&c=d] [request.formData() with input: a=b&c=d]
expected: FAIL
[request.formData() with input: a=b&c=d&]
expected: FAIL expected: FAIL
@ -28,15 +22,18 @@
[request.formData() with input: a&b&c] [request.formData() with input: a&b&c]
expected: FAIL expected: FAIL
[response.formData() with input: a&b&c]
expected: FAIL
[request.formData() with input: a=b&c=d&] [request.formData() with input: a=b&c=d&]
expected: FAIL expected: FAIL
[request.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL
[response.formData() with input: _charset_=windows-1252&test=%C2x] [response.formData() with input: _charset_=windows-1252&test=%C2x]
expected: FAIL expected: FAIL
[response.formData() with input: a=b&c=d&]
expected: FAIL
[response.formData() with input: &&&a=b&&&&c=d&]
expected: FAIL
[response.formData() with input: a=b&c=d]
expected: FAIL

View file

@ -0,0 +1,95 @@
[contenttype.any.worker.html]
[Response with Content-Type "text/wasm": instantiateStreaming]
expected: FAIL
[Response with Content-Type "": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/octet-stream": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;x": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;x": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;": compileStreaming]
expected: FAIL
[Response with Content-Type "application/octet-stream": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/javascript": instantiateStreaming]
expected: FAIL
[Response with Content-Type "text/wasm": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;charset=UTF-8": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;charset=UTF-8": compileStreaming]
expected: FAIL
[Response with Content-Type "application/javascript": compileStreaming]
expected: FAIL
[Response with Content-Type "": compileStreaming]
expected: FAIL
[contenttype.any.sharedworker.html]
[contenttype]
expected: FAIL
[contenttype.any.html]
[Response with Content-Type "text/wasm": instantiateStreaming]
expected: FAIL
[Response with Content-Type "": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/octet-stream": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;x": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;x": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;": compileStreaming]
expected: FAIL
[Response with Content-Type "application/octet-stream": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/javascript": instantiateStreaming]
expected: FAIL
[Response with Content-Type "text/wasm": compileStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;charset=UTF-8": instantiateStreaming]
expected: FAIL
[Response with Content-Type "application/wasm;charset=UTF-8": compileStreaming]
expected: FAIL
[Response with Content-Type "application/javascript": compileStreaming]
expected: FAIL
[Response with Content-Type "": compileStreaming]
expected: FAIL
[contenttype.any.serviceworker.html]
expected: TIMEOUT

View file

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

View file

@ -1,5 +1,4 @@
[import-in-moduleworker.html] [import-in-moduleworker.html]
expected: ERROR
[Base URL in module dedicated workers: import] [Base URL in module dedicated workers: import]
expected: FAIL expected: FAIL

View file

@ -1,5 +1,4 @@
[sharedworker-in-worker.html] [sharedworker-in-worker.html]
expected: ERROR
[Base URL in workers: new SharedWorker()] [Base URL in workers: new SharedWorker()]
expected: FAIL expected: FAIL

View file

@ -138,33 +138,23 @@ function initSession(testCases) {
// Schedules async_test's for each of the test cases, treating them as a single session, // Schedules async_test's for each of the test cases, treating them as a single session,
// and wires up the continueAfterSendingBeacon() and waitForResults() calls. // and wires up the continueAfterSendingBeacon() and waitForResults() calls.
// The method looks for several "extension" functions in the global scope: // The method looks for several "extension" functions in the global scope:
// - self.buildId: if present, can change the display name of a test.
// - self.buildBaseUrl: if present, can change the base URL of a beacon target URL (this // - self.buildBaseUrl: if present, can change the base URL of a beacon target URL (this
// is the scheme, hostname, and port). // is the scheme, hostname, and port).
// - self.buildTargetUrl: if present, can modify a beacon target URL (for example wrap it). // - self.buildTargetUrl: if present, can modify a beacon target URL (for example wrap it).
// Parameters: // Parameters:
// testCases: An array of test cases. // testCases: An array of test cases.
function runTests(testCases) { // sendData [optional]: A function that sends the beacon.
var session = initSession(testCases); function runTests(testCases, sendData = self.sendData) {
const session = initSession(testCases);
testCases.forEach(function(testCase, testIndex) { testCases.forEach(function(testCase, testIndex) {
// Make a copy of the test case as we'll be storing some metadata on it, // Make a copy of the test case as we'll be storing some metadata on it,
// such as which session it belongs to. // such as which session it belongs to.
var testCaseCopy = Object.assign({ session: session }, testCase); const testCaseCopy = Object.assign({ session: session }, testCase);
// Extension point: generate the test id.
var testId = testCase.id;
if (self.buildId) {
testId = self.buildId(testId);
}
testCaseCopy.origId = testCaseCopy.id;
testCaseCopy.id = testId;
testCaseCopy.index = testIndex; testCaseCopy.index = testIndex;
session.add(testCaseCopy); async_test((test) => {
// Schedule the sendbeacon in an async test.
async_test(function(test) {
// Save the testharness.js 'test' object, so that we only have one object // Save the testharness.js 'test' object, so that we only have one object
// to pass around. // to pass around.
testCaseCopy.test = test; testCaseCopy.test = test;
@ -174,22 +164,15 @@ function runTests(testCases) {
if (self.buildBaseUrl) { if (self.buildBaseUrl) {
baseUrl = self.buildBaseUrl(baseUrl); baseUrl = self.buildBaseUrl(baseUrl);
} }
var targetUrl = `${baseUrl}/beacon/resources/beacon.py?cmd=store&sid=${session.id}&tid=${testId}&tidx=${testIndex}`; var targetUrl = `${baseUrl}/beacon/resources/beacon.py?cmd=store&sid=${session.id}&tid=${testCaseCopy.id}&tidx=${testIndex}`;
if (self.buildTargetUrl) { if (self.buildTargetUrl) {
targetUrl = self.buildTargetUrl(targetUrl); targetUrl = self.buildTargetUrl(targetUrl);
} }
// Attach the URL to the test object for debugging purposes. // Attach the URL to the test object for debugging purposes.
testCaseCopy.url = targetUrl; testCaseCopy.url = targetUrl;
// Extension point: send the beacon immediately, or defer. assert_true(sendData(testCaseCopy), 'sendBeacon should succeed');
var sendFunc = test.step_func(function sendImmediately(testCase) { waitForResult(testCaseCopy).then(() => test.done(), test.step_func((e) => {throw e;}));
var sendResult = sendData(testCase);
continueAfterSendingBeacon(sendResult, testCase);
});
if (self.sendFunc) {
sendFunc = test.step_func(self.sendFunc);
}
sendFunc(testCaseCopy);
}, `Verify 'navigator.sendbeacon()' successfully sends for variant: ${testCaseCopy.id}`); }, `Verify 'navigator.sendbeacon()' successfully sends for variant: ${testCaseCopy.id}`);
}); });
} }
@ -201,161 +184,54 @@ function runTests(testCases) {
// the test. // the test.
// Returns the result of the 'sendbeacon()' function call, true or false. // Returns the result of the 'sendbeacon()' function call, true or false.
function sendData(testCase) { function sendData(testCase) {
var sent = false; return self.navigator.sendBeacon(testCase.url, testCase.data);
if (testCase.data) {
sent = self.navigator.sendBeacon(testCase.url, testCase.data);
} else {
sent = self.navigator.sendBeacon(testCase.url)
}
return sent;
} }
// Continues a single test after the beacon has been sent for that test. // Poll the server for the test result.
// Will trigger waitForResults() for the session if this is the last test async function waitForResult(testCase) {
// in the session to send its beacon. const session = testCase.session;
// Assumption: will be called on the test's step_func so that assert's do const index = testCase.index;
// not have to be wrapped. const url = `resources/beacon.py?cmd=stat&sid=${session.id}&tidx_min=${index}&tidx_max=${index}`;
function continueAfterSendingBeacon(sendResult, testCase) { for (let i = 0; i < 30; ++i) {
var session = testCase.session; const response = await fetch(url);
const text = await response.text();
const results = JSON.parse(text);
// Recaclulate the sent vs. total counts. if (results.length === 0) {
if (sendResult) { await new Promise(resolve => step_timeout(resolve, 100));
session.sentCount++; continue;
} else {
session.totalCount--;
} }
assert_equals(results.length, 1, `bad response: '${text}'`);;
// If this was the last test in the session to send its beacon, start polling for results. // null JSON values parse as null, not undefined
// Note that we start polling even if just one test in the session sends successfully, assert_equals(results[0].error, null, "'sendbeacon' data must not fail validation");
// so that if any of the others fail, we still get results from the tests that did send.
if (session.sentCount == session.totalCount) {
// Exit the current test's execution context in order to run the poll
// loop from the harness context.
step_timeout(waitForResults.bind(this, session), 0);
}
// Now fail this test if the beacon did not send. It will be excluded from the poll
// loop because of the calculation adjustment above.
assert_true(sendResult, "'sendbeacon' function call must succeed");
}
// Kicks off an asynchronous monitor to poll the server for test results. As we
// verify that the server has received and validated a beacon, we will complete
// its testharness test.
function waitForResults(session) {
// Poll for status until all of the results come in.
fetch(`resources/beacon.py?cmd=stat&sid=${session.id}&tidx_min=0&tidx_max=${session.totalCount-1}`).then(
function(response) {
// Parse as text(), not json(), so that we can log the raw response if
// it's invalid.
response.text().then(function(rawResponse) {
// Check that we got a response we expect and know how to handle.
var results;
var failure;
try {
results = JSON.parse(rawResponse);
if (results.length === undefined) {
failure = `bad validation response schema: rawResponse='${rawResponse}'`;
}
} catch (e) {
failure = `bad validation response: rawResponse='${rawResponse}', got parse error '${e}'`;
}
if (failure) {
// At this point we can't deterministically get results for all of the
// tests in the session, so fail the entire session.
failSession(session, failure);
return; return;
} }
assert_true(false, 'timeout');
// The 'stat' call will return an array of zero or more results
// of sendbeacon() calls that the server has received and validated.
results.forEach(function(result) {
var testCase = session.testCaseLookup[result.id];
// While stash.take on the server is supposed to honor read-once, since we're
// polling so frequently it is possible that we will receive the same test result
// more than once.
if (!testCase.done) {
testCase.done = true;
session.doneCount++;
}
// Validate that the sendbeacon() was actually sent to the server.
var test = testCase.test;
test.step(function() {
// null JSON values parse as null, not undefined
assert_equals(result.error, null, "'sendbeacon' data must not fail validation");
});
test.done();
});
// Continue polling until all of the results come in.
if (session.doneCount < session.sentCount) {
// testharness.js frowns upon the use of explicit timeouts, but there is no way
// around the need to poll for these tests, and there is no use spamming the server
// with requestAnimationFrame() just to avoid the use of step_timeout.
step_timeout(waitForResults.bind(this, session), 100);
}
}).catch(function(error) {
failSession(session, `unexpected error reading response, error='${error}'`);
});
}
);
}
// Fails all of the tests in the session, meant to be called when an infrastructural
// issue prevents us from deterministically completing the individual tests.
function failSession(session, reason) {
session.testCases.forEach(function(testCase) {
var test = testCase.test;
test.unreached_func(reason)();
});
} }
// Creates an iframe on the document's body and runs the sample tests from the iframe. // Creates an iframe on the document's body and runs the sample tests from the iframe.
// The iframe is navigated immediately after it sends the data, and the window verifies // The iframe is navigated immediately after it sends the data, and the window verifies
// that the data is still successfully sent. // that the data is still successfully sent.
// funcName: "beacon" to send the data via navigator.sendBeacon(), function runSendInIframeAndNavigateTests() {
// "fetch" to send the data via fetch() with the keepalive flag.
function runSendInIframeAndNavigateTests(funcName) {
var iframe = document.createElement("iframe"); var iframe = document.createElement("iframe");
iframe.id = "iframe"; iframe.id = "iframe";
iframe.onload = function() { iframe.onload = function() {
var tests = Array();
// Clear our onload handler to prevent re-running the tests as we navigate away. // Clear our onload handler to prevent re-running the tests as we navigate away.
this.onload = null; iframe.onload = null;
function sendData(testCase) {
// Implement the self.buildId extension to identify the parameterized return iframe.contentWindow.navigator.sendBeacon(testCase.url, testCase.data);
// test in the report. }
self.buildId = function(baseId) { const tests = [];
return `${baseId}-${funcName}-NAVIGATE`; for (const test of sampleTests) {
const copy = Object.assign({}, test);
copy.id = `${test.id}-NAVIGATE`;
tests.push(copy);
}
runTests(tests, sendData);
// Now navigate ourselves.
iframe.contentWindow.location = "http://{{host}}:{{ports[http][0]}}/";
}; };
window.onmessage = function(e) { iframe.srcdoc = '<html></html>';
// The iframe will execute sendData() for us and return the result.
var testCase = tests[e.data];
continueAfterSendingBeacon(true /* sendResult */, testCase);
};
// Implement the self.sendFunc extension to send the beacon indirectly,
// from an iFrame that we can then navigate.
self.sendFunc = function(testCase) {
var iframeWindow = document.getElementById("iframe").contentWindow;
// We run into problems passing the testCase over the document boundary,
// because of structured cloning constraints. Instead we'll send over the
// test case id, and the iFrame can load the static test case by including
// beacon-common.js.
tests[testCase.origId] = testCase;
iframeWindow.postMessage([testCase.origId, testCase.url, funcName], "*");
};
runTests(sampleTests);
};
iframe.src = "navigate.iFrame.sub.html";
document.body.appendChild(iframe); document.body.appendChild(iframe);
} }

View file

@ -7,12 +7,6 @@
// the beacon handler will return CORS headers. This test ensures that the // the beacon handler will return CORS headers. This test ensures that the
// sendBeacon() succeeds in either case. // sendBeacon() succeeds in either case.
[true, false].forEach(function(allowCors) { [true, false].forEach(function(allowCors) {
// Implement the self.buildId extension to identify the parameterized
// test in the report.
self.buildId = function(baseId) {
return `${baseId}-${allowCors ? "CORS-ALLOW" : "CORS-FORBID"}`;
};
// Implement the self.buildBaseUrl and self.buildTargetUrl extensions // Implement the self.buildBaseUrl and self.buildTargetUrl extensions
// to change the target URL to use a cross-origin domain name. // to change the target URL to use a cross-origin domain name.
self.buildBaseUrl = function(baseUrl) { self.buildBaseUrl = function(baseUrl) {
@ -35,7 +29,13 @@
return allowCors ? `${targetUrl}&origin=http://{{host}}:{{ports[http][0]}}&credentials=true` : targetUrl; return allowCors ? `${targetUrl}&origin=http://{{host}}:{{ports[http][0]}}&credentials=true` : targetUrl;
} }
runTests(sampleTests); const tests = [];
for (const test of sampleTests) {
const copy = Object.assign({}, test);
copy.id = `${test.id}-${allowCors ? "CORS-ALLOW" : "CORS-FORBID"}`;
tests.push(copy);
}
runTests(tests);
}); });
// Now test a cross-origin request that doesn't use a safelisted Content-Type and ensure // Now test a cross-origin request that doesn't use a safelisted Content-Type and ensure
@ -43,12 +43,6 @@
// header is used there should be a preflight/options request and we should only succeed // header is used there should be a preflight/options request and we should only succeed
// send the payload if the proper CORS headers are used. // send the payload if the proper CORS headers are used.
{ {
// Implement the self.buildId extension to identify the parameterized
// test in the report.
self.buildId = function (baseId) {
return `${baseId}-PREFLIGHT-ALLOW`;
};
// Implement the self.buildBaseUrl and self.buildTargetUrl extensions // Implement the self.buildBaseUrl and self.buildTargetUrl extensions
// to change the target URL to use a cross-origin domain name. // to change the target URL to use a cross-origin domain name.
self.buildBaseUrl = function (baseUrl) { self.buildBaseUrl = function (baseUrl) {
@ -60,8 +54,13 @@
self.buildTargetUrl = function (targetUrl) { self.buildTargetUrl = function (targetUrl) {
return `${targetUrl}&origin=http://{{host}}:{{ports[http][0]}}&credentials=true&preflightExpected=true`; return `${targetUrl}&origin=http://{{host}}:{{ports[http][0]}}&credentials=true&preflightExpected=true`;
} }
const tests = [];
runTests(preflightTests); for (const test of preflightTests) {
const copy = Object.assign({}, test);
copy.id = `${test.id}-PREFLIGHT-ALLOW`;
tests.push(copy);
}
runTests(tests);
} }
done(); done();

View file

@ -7,19 +7,18 @@
// Note that status codes 307 and 308 are the only codes that will maintain POST data // Note that status codes 307 and 308 are the only codes that will maintain POST data
// through a redirect. // through a redirect.
[307, 308].forEach(function(status) { [307, 308].forEach(function(status) {
// Implement the self.buildId extension to identify the parameterized
// test in the report.
self.buildId = function(baseId) {
return `${baseId}-${status}`;
};
// Implement the self.buildTargetUrl extension to inject a redirect to // Implement the self.buildTargetUrl extension to inject a redirect to
// the sendBeacon target. // the sendBeacon target.
self.buildTargetUrl = function(targetUrl) { self.buildTargetUrl = function(targetUrl) {
return `/common/redirect.py?status=${status}&location=${encodeURIComponent(targetUrl)}`; return `/common/redirect.py?status=${status}&location=${encodeURIComponent(targetUrl)}`;
}; };
const tests = [];
runTests(sampleTests); for (const test of sampleTests) {
const copy = Object.assign({}, test);
copy.id = `${test.id}-${status}`;
tests.push(copy);
}
runTests(tests);
}); });
done(); done();

View file

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>W3C Beacon As Fetch (Fetch KeepAlive) Navigate Test</title>
</head>
<body>
<script src="beacon-common.sub.js"></script>
<script>
"use strict";
// An array should be passed through postMessage to this iFrame, where
// [0] contains a test case id as defined in beacon-common.js.
// [1] is the URL for the keep alive fetch() or sendBeacon().
// [2] string indicating the function to call - "fetch" to call fetch() or "beacon" to call sendBeacon().
// The testcase id is returned back to the window through postMesage.
var tests = 0;
window.onmessage = function(e) {
var testCaseId = e.data[0];
var url = e.data[1];
var func = e.data[2];
tests++;
// Reconstruct enough of the test case to send the keep alive fetch (data and url).
var testCase = testLookup[testCaseId];
testCase.url = url;
if (func === "beacon") {
// sendData calls sendBeacon
sendData(testCase);
}
else {
throw new Error(func + " is an invalid function");
}
// Let the main page continue the test if we don't immediately throw an exception.
parent.postMessage(testCaseId, "*");
// Now navigate ourselves.
if (tests == sampleTests.length) {
window.location = "http://{{host}}:{{ports[http][0]}}/";
}
}
</script>
</body>
</html>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>clip-path on inline, horizontal-tb writing-mode</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-clip-path" title="5.1 Clipping Shape: the clip-path property">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<meta content="ahem" name="flags">
<style>
.container {
writing-mode: horizontal-tb;
font: 100px/1 Ahem;
line-height: 100px;
color: red;
}
.container::first-letter {
color:green;
}
.container > span {
clip-path: polygon(0% 0%, 50% 0%, 50% 100%, 0% 100%);
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="container">
<span>
XX<br>
XXX
</span>
</div>

View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<title>clip-path on inline, vertical-rl writing-mode</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-clip-path" title="5.1 Clipping Shape: the clip-path property">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<meta content="ahem" name="flags">
<style>
.container {
writing-mode: vertical-rl;
margin-left: -100px;
font: 100px/1 Ahem;
line-height: 100px;
color: red;
}
.container::first-letter {
color:green;
}
.container > span {
clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="container">
<span>
XX<br>
XXX
</span>
</div>

View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>clip-path on inline, vertical-lr writing-mode</title>
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
<link rel="help" href="https://www.w3.org/TR/css-masking-1/#the-clip-path" title="5.1 Clipping Shape: the clip-path property">
<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
<meta content="ahem" name="flags">
<style>
.container {
writing-mode: vertical-lr;
font: 100px/1 Ahem;
line-height: 100px;
color: red;
}
.container::first-letter {
color:green;
}
.container > span {
clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%);
}
</style>
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
<div class="container">
<span>
XX<br>
XXX
</span>
</div>

View file

@ -1,4 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:html="http://www.w3.org/1999/xhtml"
width="100px" height="100px">
<g id="testmeta"> <g id="testmeta">
<title>CSS Masking: Reftest reference</title> <title>CSS Masking: Reftest reference</title>
<html:link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com"/> <html:link rel="author" title="Dirk Schulze" href="mailto:dschulze@adobe.com"/>

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 426 B

Before After
Before After

View file

@ -41,7 +41,7 @@
<div> <div>
<img id="first-blue" src="support/swatch-blue.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="second-blue" src="support/swatch-blue.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="first-pink" src="support/swatch-pink.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="second-pink" src="support/swatch-pink.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="first-blue" src="support/swatch-blue.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="second-blue" src="support/swatch-blue.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="first-pink" src="support/swatch-pink.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="second-pink" src="support/swatch-pink.png" width="40" height="40" alt="Image download support must be enabled" />
<img id="black" src="support/black20x20.png" width="110" height="20" alt="Image download support must be enabled" /> <img id="black" src="support/black20x20.png" width="260" height="20" alt="Image download support must be enabled" />
<img id="first-yellow" src="support/swatch-yellow.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="first-yellow" src="support/swatch-yellow.png" width="40" height="40" alt="Image download support must be enabled" />
<img id="second-yellow" src="support/swatch-yellow.png" width="40" height="40" alt="Image download support must be enabled" /> <img id="second-yellow" src="support/swatch-yellow.png" width="40" height="40" alt="Image download support must be enabled" />

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: overflow-wrap: break-word</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-overflow-wrap-break-word">
<meta name="flags" content="ahem">
<link rel="match" href="reference/overflow-wrap-break-word-001-ref.html">
<meta name="assert" content="A Single leading white-space constitutes a soft breaking opportunity, honoring the 'white-space: pre-wrap' property, that must prevent the word to be broken.">
<style>
div {
position: relative;
font-size: 20px;
font-family: Ahem;
}
.red {
position: absolute;
background: green;
color: red;
width: 100px;
height: 100px;
z-index: -1;
}
.test {
color: green;
line-height: 1em;
width: 5ch;
white-space: pre-wrap;
overflow-wrap: break-word;
}
</style>
<body>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div class="red"><br>XXXXX</div>
<div class="test"> XXXXX </div>
</body>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: white-space: pre-wrap</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-white-space-pre-wrap">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
<meta name="flags" content="ahem">
<link rel="match" href="reference/pre-wrap-001-ref.html">
<meta name="assert" content="The text is broken at the end of the space between the two words, never before, so it hangs and cause an overflow">
<style>
div {
position: relative;
font: 20px/1 Ahem;
}
.ref {
position: absolute;
color: red;
z-index: -1;
}
.test {
color: green;
width: 20px;
white-space: pre-wrap;
word-break: break-word;
}
</style>
<body>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div class="ref">X<span style="color: green">X</span><br>X<span style="color: green">X</span></div>
<div class="test">X X</div>
</body>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Reference File</title>
<link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/">
<style>
div {
position: relative;
width: 100px;
height: 100px;
background: green;
}
</style>
<body>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div></div>
</body>

View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: overflow-wrap: break-all</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<p>Test passes if 2 icons are rendered in a row, matching the reference file.</p>
<div>💖<br>💔</div>

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: overflow-wrap: break-word</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
<meta name="flags" content="ahem">
<link rel="match" href="reference/word-break-break-all-010-ref.html">
<meta name="assert" content="The word is broken even if pre-wrap provides a former breaking opportunity in leading white-space.">
<style>
div {
position: relative;
font-size: 20px;
font-family: Ahem;
}
.red {
position: absolute;
white-space: pre;
background: green;
color: red;
width: 100px;
height: 100px;
z-index: -1;
}
.test {
color: green;
line-height: 1em;
width: 5ch;
white-space: pre-wrap;
word-break: break-all;
}
</style>
<body>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div class="red"> XXXX<br>X</div>
<div class="test"> XXXXX</div>
</body>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: overflow-wrap: break-word</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
<meta name="flags" content="ahem">
<link rel="match" href="reference/word-break-break-all-010-ref.html">
<meta name="assert" content="A single leading white-space should account as soft breaking opportunity, honoring the 'white-space: pre-wrap', on top to the ones provided by 'word-break: break-all'.">
<style>
div {
position: relative;
font-size: 20px;
font-family: Ahem;
}
.red {
position: absolute;
background: green;
color: red;
width: 100px;
height: 100px;
z-index: -1;
}
.test {
color: green;
background: green;
line-height: 1em;
width: 1ch;
white-space: pre-wrap;
word-break: break-all;
}
</style>
<body>
<p>Test passes if there is a <strong>filled green square</strong> and <strong>no red</strong>.</p>
<div class="red">X<br>X<br>X</div>
<div class="test"> XX</div>
</body>

View file

@ -0,0 +1,16 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Text Test: overflow-wrap: break-all</title>
<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all">
<meta name="flags" content="ahem">
<link rel="match" href="reference/word-break-break-all-014-ref.html">
<meta name="assert" content="The text is wrapped after the first character and no unicode unit is broken.">
<style>
div {
width: 1px;
word-break: break-all;
}
</style>
<p>Test passes if 2 icons are rendered in a row, matching the reference file.</p>
<div>💖💔</div>

View file

@ -5,7 +5,6 @@ async function send_message_to_iframe(iframe, message, reply) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let messageHandler = e => { let messageHandler = e => {
if (e.data.command !== message.command) { if (e.data.command !== message.command) {
return; return;
} }
@ -131,4 +130,31 @@ function run_generic_sensor_iframe_tests(sensorName) {
iframe.parentNode.removeChild(iframe); iframe.parentNode.removeChild(iframe);
}, `${sensorName}: sensor is not suspended when focus traverses from\ }, `${sensorName}: sensor is not suspended when focus traverses from\
to same-origin frame`); to same-origin frame`);
sensor_test(async t => {
assert_true(sensorName in self);
const iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
iframe.src = 'https://{{host}}:{{ports[https][0]}}/generic-sensor/resources/iframe_sensor_handler.html';
// Create sensor in the iframe (we do not care whether this is a
// cross-origin nested context in this test).
const iframeLoadWatcher = new EventWatcher(t, iframe, 'load');
document.body.appendChild(iframe);
await iframeLoadWatcher.wait_for('load');
await send_message_to_iframe(iframe, {command: 'create_sensor',
type: sensorName});
iframe.contentWindow.focus();
await send_message_to_iframe(iframe, {command: 'start_sensor'});
// Remove iframe from main document and change focus. When focus changes,
// we need to determine whether a sensor must have its execution suspended
// or resumed (section 4.2.3, "Focused Area" of the Generic Sensor API
// spec). In Blink, this involves querying a frame, which might no longer
// exist at the time of the check.
// Note that we cannot send the "reset_sensor_backend" command because the
// iframe is discarded with the removeChild call.
iframe.parentNode.removeChild(iframe);
window.focus();
}, `${sensorName}: losing a document's frame with an active sensor does not crash`);
} }

View file

@ -0,0 +1,74 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>History restoration order test</title>
<meta name="assert" content="https://html.spec.whatwg.org/multipage/browsing-the-web.html#history-traversal">
<meta name="assert" content="Traversing history should restore scroll position after dispatching popstate and before dispatching hashchange">
<style>
body {
height: 200vh;
width: 200vw;
}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
'use strict';
async_test(function(t) {
window.addEventListener('load', t.step_func(function() {
// Allow 1px epsilon for fractional scrolling.
assert_array_approx_equals(scrollPosition(), [0, 0], 1);
history.pushState('#1', '', '#1');
window.scrollTo(50, 100);
assert_array_approx_equals(scrollPosition(), [50, 100], 1);
history.pushState('#2', '', '#2');
window.scrollTo(100, 200);
assert_array_approx_equals(scrollPosition(), [100, 200], 1);
setTimeout(t.step_func(function(){
history.pushState(null, null, '#done');
window.scrollTo(555, 555);
assert_array_approx_equals(scrollPosition(), [555, 555], 1);
// Kick off the verification.
window.history.back();
}), 0);
}));
window.addEventListener('popstate', t.step_func(function() {
// Verify that scroll position is *not* restored before popstate.
const key = location.hash;
const expected_scroll_position = expectedScrollPositionForKey(key);
assert_not_equals(scrollPosition()[0], expected_scroll_position[0], `scroll is restored before popstate for ${key}`);
assert_not_equals(scrollPosition()[1], expected_scroll_position[1], `scroll is restored before popstate for ${key}`);
if (key == '')
t.done();
else
setTimeout(t.step_func(function(){ window.history.back(); }), 0);
}));
window.addEventListener('hashchange', t.step_func(function() {
// Verify that scroll position is restored before hashchange.
var key = location.hash;
const expected_scroll_position = expectedScrollPositionForKey(key);
assert_array_approx_equals(scrollPosition(), expected_scroll_position, 1, `scroll is restored before hashchange for ${key}`);
}));
function scrollPosition() {
return [window.pageXOffset, window.pageYOffset];
}
function expectedScrollPositionForKey(key) {
switch (key) {
case '#2': return [100, 200];
case '#1': return [50, 100];
case '' : return [0, 0];
default: assert_unreached();
}
}
}, 'Traversing history should restore scroll position after dispatching popstate and before dispatching hashchange');
</script>

View file

@ -0,0 +1,37 @@
<html manifest="resources/appcache-iframe.manifest">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
const initPromise = new Promise(resolve => {
applicationCache.addEventListener('cached', resolve, false);
applicationCache.addEventListener('noupdate', resolve, false);
});
function with_iframe(url) {
return new Promise(resolve => {
let frame = document.createElement('iframe');
frame.src = url;
frame.onload = () => { resolve(frame); };
document.body.appendChild(frame);
add_result_callback(() => frame.remove());
});
}
promise_test(async t => {
await initPromise;
const frame =
await with_iframe('resources/appcache-iframe.py?type=cached');
const msgEvent = await new Promise(r => window.onmessage = r);
assert_equals(msgEvent.data, 'Done: cached');
}, 'iframe should be loaded from application caches.');
promise_test(async t => {
await initPromise;
const frame =
await with_iframe('resources/appcache-iframe.py?type=fallingback');
const msgEvent = await new Promise(r => window.onmessage = r);
assert_equals(msgEvent.data, 'Done: fallbacked');
}, 'iframe should be loaded from application caches for fallback.');
</script>
</html>

View file

@ -0,0 +1,5 @@
def main(request, response):
type = request.GET['type']
if request.GET['type'] == 'fallingback':
return 404, [('Content-Type', 'text/plain')], "Page not found"
return [('Content-Type', 'text/plain')], type

View file

@ -0,0 +1,8 @@
CACHE MANIFEST
appcache-iframe.py?type=cached
appcache-data.py?type=cached
FALLBACK:
appcache-iframe.py?type=fallingback appcache-iframe.py?type=fallbacked
appcache-data.py?type=fallingback appcache-data.py?type=fallbacked

View file

@ -0,0 +1,43 @@
script = '''
<script>
function fetchCachedFileTest() {
return fetch('appcache-data.py?type=cached')
.then(res => res.text(),
_ => { throw new Error('Failed to fetch cached file'); })
.then(text => {
if (text != 'cached') {
throw new Error('cached file missmatch');
}
});
}
function fetchNotInCacheFileTest() {
return fetch('appcache-data.py?type=not-in-cache')
.then(_ => { throw new Error('Fetching not-in-cache file must fail'); },
_ => {});
}
function fetchFallbackFileTest() {
return fetch('appcache-data.py?type=fallingback')
.then(res => res.text(),
_ => { throw new Error('Failed to fetch fallingback file'); })
.then(text => {
if (text != 'fallbacked') {
throw new Error('fallbacked file miss match');
}
});
}
fetchCachedFileTest()
.then(fetchNotInCacheFileTest)
.then(fetchFallbackFileTest)
.then(_ => window.parent.postMessage('Done: %s'),
error => window.parent.postMessage(error.toString()));
</script>
'''
def main(request, response):
type = request.GET['type']
if request.GET['type'] == 'fallingback':
return 404, [('Content-Type', 'text/plain')], "Page not found"
return [('Content-Type', 'text/html')], script % type

View file

@ -91,6 +91,7 @@ initPromise
.then(importFallbackScriptTest) .then(importFallbackScriptTest)
.then(fetchCachedFileTest) .then(fetchCachedFileTest)
.then(fetchNotInCacheFileTest) .then(fetchNotInCacheFileTest)
.then(fetchFallbackFileTest)
.then(_ => postMessage('Done: %s'), .then(_ => postMessage('Done: %s'),
error => postMessage(error.toString())); error => postMessage(error.toString()));
''' '''

View file

@ -49,7 +49,7 @@ dictionary PaymentDetailsUpdate : PaymentDetailsBase {
DOMString error; DOMString error;
PaymentItem total; PaymentItem total;
AddressErrors shippingAddressErrors; AddressErrors shippingAddressErrors;
PayerErrorFields payerErrors; PayerErrors payerErrors;
object paymentMethodErrors; object paymentMethodErrors;
}; };
@ -169,13 +169,13 @@ interface PaymentResponse : EventTarget {
}; };
dictionary PaymentValidationErrors { dictionary PaymentValidationErrors {
PayerErrorFields payer; PayerErrors payer;
AddressErrors shippingAddress; AddressErrors shippingAddress;
DOMString error; DOMString error;
object paymentMethod; object paymentMethod;
}; };
dictionary PayerErrorFields { dictionary PayerErrors {
DOMString email; DOMString email;
DOMString name; DOMString name;
DOMString phone; DOMString phone;

View file

@ -0,0 +1,10 @@
// GENERATED CONTENT - DO NOT EDIT
// Content was automatically extracted by Reffy into reffy-reports
// (https://github.com/tidoust/reffy-reports)
// Source: WebAssembly Web API (https://webassembly.github.io/spec/web-api/)
partial namespace WebAssembly {
Promise<Module> compileStreaming(Promise<Response> source);
Promise<WebAssemblyInstantiatedSource> instantiateStreaming(
Promise<Response> source, optional object importObject);
};

View file

@ -0,0 +1,94 @@
<!doctype html>
<html>
<head>
<title>MediaStream and MediaStreamTrack clone()</title>
<link rel="help" href="https://w3c.github.io/mediacapture-main/#dom-mediastream-clone">
<link rel="help" href="https://w3c.github.io/mediacapture-main/#dom-mediastreamtrack-clone">
</head>
<body>
<p class="instructions">When prompted, accept to give permission to use your audio and video devices.</p>
<h1 class="instructions">Description</h1>
<p class="instructions">This test checks that cloning MediaStreams and MediaStreamTracks works as expected.</p>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script>
promise_test(async t => {
const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
assert_equals(stream.getAudioTracks().length, 1);
assert_equals(stream.getVideoTracks().length, 1);
const clone1 = stream.clone();
assert_equals(clone1.getAudioTracks().length, 1);
assert_equals(clone1.getVideoTracks().length, 1);
assert_not_equals(stream.getAudioTracks()[0].id, clone1.getAudioTracks()[0].id);
assert_not_equals(stream.getVideoTracks()[0].id, clone1.getVideoTracks()[0].id);
stream.getTracks().forEach(track => track.stop());
assert_false(stream.active);
assert_equals(stream.getAudioTracks()[0].readyState, "ended");
assert_equals(stream.getVideoTracks()[0].readyState, "ended");
assert_true(clone1.active);
assert_equals(clone1.getAudioTracks()[0].readyState, "live");
assert_equals(clone1.getVideoTracks()[0].readyState, "live");
clone1.getAudioTracks()[0].stop();
assert_true(clone1.active);
assert_equals(clone1.getAudioTracks()[0].readyState, "ended");
assert_equals(clone1.getVideoTracks()[0].readyState, "live");
const clone2 = clone1.clone();
assert_true(clone2.active);
assert_equals(clone2.getAudioTracks()[0].readyState, "ended");
assert_equals(clone2.getVideoTracks()[0].readyState, "live");
clone1.getVideoTracks()[0].stop();
clone2.getVideoTracks()[0].stop();
const clone3 = clone2.clone();
assert_false(clone3.active);
assert_equals(clone3.getAudioTracks()[0].readyState, "ended");
assert_equals(clone3.getVideoTracks()[0].readyState, "ended");
assert_not_equals(clone1.getAudioTracks()[0].id, clone2.getAudioTracks()[0].id);
assert_not_equals(clone1.getVideoTracks()[0].id, clone2.getVideoTracks()[0].id);
assert_not_equals(clone2.getAudioTracks()[0].id, clone3.getAudioTracks()[0].id);
assert_not_equals(clone2.getVideoTracks()[0].id, clone3.getVideoTracks()[0].id);
assert_not_equals(clone1.getAudioTracks()[0].id, clone3.getAudioTracks()[0].id);
assert_not_equals(clone1.getVideoTracks()[0].id, clone3.getVideoTracks()[0].id);
}, "Tests that cloning MediaStream objects works as expected");
promise_test(async t => {
const stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
assert_equals(stream.getAudioTracks().length, 1);
assert_equals(stream.getVideoTracks().length, 1);
assert_equals(stream.getAudioTracks()[0].readyState, "live");
assert_equals(stream.getVideoTracks()[0].readyState, "live");
assert_true(stream.active);
const audio_clone = stream.getAudioTracks()[0].clone();
const video_clone = stream.getVideoTracks()[0].clone();
assert_equals(audio_clone.readyState, "live");
assert_equals(video_clone.readyState, "live");
assert_not_equals(stream.getAudioTracks()[0].id, audio_clone.id);
assert_not_equals(stream.getVideoTracks()[0].id, video_clone.id);
stream.getTracks().forEach(track => track.stop());
assert_false(stream.active);
assert_equals(stream.getAudioTracks()[0].readyState, "ended");
assert_equals(stream.getVideoTracks()[0].readyState, "ended");
assert_equals(audio_clone.readyState, "live");
assert_equals(video_clone.readyState, "live");
stream.addTrack(audio_clone);
stream.addTrack(video_clone);
assert_true(stream.active);
stream.getTracks().forEach(track => track.stop());
assert_false(stream.active);
assert_equals(audio_clone.readyState, "ended");
assert_equals(video_clone.readyState, "ended");
}, "Tests that cloning MediaStreamTrack objects works as expected");
</script>
</body>
</html>

View file

@ -20,36 +20,45 @@ follows the algorithm set in the spec.</p>
<script src=/resources/testharness.js></script> <script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script> <script src=/resources/testharnessreport.js></script>
<script> <script>
var t = async_test("Tests that a MediaStream constructor follows the algorithm set in the spec", {timeout: 10000}); let t = async_test("Tests that a MediaStream constructor follows the algorithm set in the spec", {timeout: 10000});
t.step(function() { t.step(() => {
navigator.mediaDevices.getUserMedia({video: true, audio:true}) navigator.mediaDevices.getUserMedia({video: true, audio:true})
.then(t.step_func(function (stream) { .then(t.step_func(stream => {
var stream1 = new MediaStream(); let stream1 = new MediaStream();
assert_not_equals(stream.id, stream1.id, "Two different MediaStreams have different ids"); assert_not_equals(stream.id, stream1.id, "Two different MediaStreams have different ids");
var stream2 = new MediaStream(stream); let stream2 = new MediaStream(stream);
assert_not_equals(stream.id, stream2.id, "A MediaStream constructed from another have different ids"); assert_not_equals(stream.id, stream2.id, "A MediaStream constructed from another has a different id");
var audioTrack1 = stream.getAudioTracks()[0]; let audioTrack1 = stream.getAudioTracks()[0];
var videoTrack = stream.getVideoTracks()[0]; let videoTrack = stream.getVideoTracks()[0];
assert_equals(audioTrack1, stream2.getAudioTracks()[0], "A MediaStream constructed from another share the same audio track"); assert_equals(audioTrack1, stream2.getAudioTracks()[0], "A MediaStream constructed from another shares the same audio track");
assert_equals(videoTrack, stream2.getVideoTracks()[0], "A MediaStream constructed from another share the same video track"); assert_equals(videoTrack, stream2.getVideoTracks()[0], "A MediaStream constructed from another shares the same video track");
var stream4 = new MediaStream([audioTrack1]); let stream4 = new MediaStream([audioTrack1]);
assert_equals(stream4.getTrackById(audioTrack1.id), audioTrack1, "a non-ended track gets added via the MediaStream constructor"); assert_equals(stream4.getTrackById(audioTrack1.id), audioTrack1, "a non-ended track gets added via the MediaStream constructor");
var audioTrack2 = audioTrack1.clone(); let audioTrack2 = audioTrack1.clone();
audioTrack2.addEventListener("ended", t.unreached_func("ended event should not be fired by MediaStreamTrack.stop().")); audioTrack2.addEventListener("ended", t.unreached_func("ended event should not be fired by MediaStreamTrack.stop()."));
audioTrack2.stop(); audioTrack2.stop();
assert_equals(audioTrack2.readyState, "ended", "a stopped track is marked ended synchronously"); assert_equals(audioTrack2.readyState, "ended", "a stopped track is marked ended synchronously");
var stream3 = new MediaStream([audioTrack2, videoTrack]); let stream3 = new MediaStream([audioTrack2, videoTrack]);
assert_equals(stream3.getTrackById(audioTrack2.id), audioTrack2, "an ended track gets added via the MediaStream constructor"); assert_equals(stream3.getTrackById(audioTrack2.id), audioTrack2, "an ended track gets added via the MediaStream constructor");
assert_equals(stream3.getTrackById(videoTrack.id), videoTrack, "a non-ended track gets added via the MediaStream constructor even if the previous track was ended"); assert_equals(stream3.getTrackById(videoTrack.id), videoTrack, "a non-ended track gets added via the MediaStream constructor even if the previous track was ended");
var stream5 = new MediaStream([audioTrack2]); let stream5 = new MediaStream([audioTrack2]);
assert_equals(stream5.getTrackById(audioTrack2.id), audioTrack2, "an ended track gets added via the MediaStream constructor"); assert_equals(stream5.getTrackById(audioTrack2.id), audioTrack2, "an ended track gets added via the MediaStream constructor");
assert_false(stream5.active, "a MediaStream created using the MediaStream() constructor whose arguments are lists of MediaStreamTrack objects that are all ended, the MediaStream object MUST be created with its active attribute set to false"); assert_false(stream5.active, "a MediaStream created using the MediaStream() constructor whose arguments are lists of MediaStreamTrack objects that are all ended, the MediaStream object MUST be created with its active attribute set to false");
stream.oninactive = t.step_func(() => {
assert_false(stream.active);
stream.getTracks().forEach(track => {
assert_equals(track.readyState, "ended");
});
// Use a timeout to detect a misfire of the ended event. // Use a timeout to detect a misfire of the ended event.
t.step_timeout(t.step_func_done()); t.step_timeout(t.step_func_done());
});
audioTrack1.stop();
videoTrack.stop();
}) })
); );
}); });

View file

@ -20,7 +20,7 @@ test(() => {
// Test for https://github.com/w3c/payment-request/pull/665 // Test for https://github.com/w3c/payment-request/pull/665
test(() => { test(() => {
const uuidRegExp = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-4][0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$/i; const uuidRegExp = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const request1 = new PaymentRequest(methods, { const request1 = new PaymentRequest(methods, {
total, total,
}); });

View file

@ -3,10 +3,27 @@
'use strict'; 'use strict';
// https://w3c.github.io/speech-api/#dom-speechsynthesis-getvoices can
// return an empty list and a voiceschanged event is fired if the list of
// voices is determined asynchronously.
function getVoices() {
return new Promise(resolve => {
const voices = speechSynthesis.getVoices();
if (voices.length) {
resolve(voices);
} else {
// wait for voiceschanged event
speechSynthesis.addEventListener('voiceschanged', () => {
resolve(speechSynthesis.getVoices());
}, { once: true });
}
});
}
idl_test( idl_test(
['speech-api'], ['speech-api'],
['dom', 'html'], ['dom', 'html'],
idl_array => { (idl_array, t) => {
idl_array.add_objects({ idl_array.add_objects({
SpeechGrammar: ['new SpeechGrammar()'], SpeechGrammar: ['new SpeechGrammar()'],
SpeechGrammarList: ['new SpeechGrammarList()'], SpeechGrammarList: ['new SpeechGrammarList()'],
@ -20,15 +37,14 @@ idl_test(
// TODO: SpeechSynthesisErrorEvent // TODO: SpeechSynthesisErrorEvent
// TODO: SpeechSynthesisEvent // TODO: SpeechSynthesisEvent
SpeechSynthesisUtterance: ['new SpeechSynthesisUtterance()'], SpeechSynthesisUtterance: ['new SpeechSynthesisUtterance()'],
SpeechSynthesisVoice: ['voice'],
Window: ['self'], Window: ['self'],
}); });
// https://w3c.github.io/speech-api/#dom-speechsynthesis-getvoices can const awaitVoice = getVoices().then(voices => self.voice = voices[0]);
// return an empty list, so add SpeechSynthesisVoice conditionally. const timeout = new Promise((_, reject) => {
const voices = speechSynthesis.getVoices(); t.step_timeout(() => reject('Timed out waiting for voice'), 3000);
if (voices.length) { });
self.voice = voices[0]; return Promise.race([awaitVoice, timeout]);
idl_array.add_objects({ SpeechSynthesisVoice: ['voice'] });
}
} }
); );

View file

@ -93,7 +93,7 @@ def browser_kwargs(test_type, run_info_data, config, **kwargs):
"symbols_path": kwargs["symbols_path"], "symbols_path": kwargs["symbols_path"],
"stackwalk_binary": kwargs["stackwalk_binary"], "stackwalk_binary": kwargs["stackwalk_binary"],
"certutil_binary": kwargs["certutil_binary"], "certutil_binary": kwargs["certutil_binary"],
"ca_certificate_path": kwargs["ssl_env"].ca_cert_path(), "ca_certificate_path": config.ssl_config["ca_cert_path"],
"stackfix_dir": kwargs["stackfix_dir"], "stackfix_dir": kwargs["stackfix_dir"],
"binary_args": kwargs["binary_args"], "binary_args": kwargs["binary_args"],
"timeout_multiplier": get_timeout_multiplier(test_type, "timeout_multiplier": get_timeout_multiplier(test_type,

View file

@ -1,7 +1,7 @@
from .base import Browser, ExecutorBrowser, require_arg from .base import Browser, ExecutorBrowser, require_arg
from ..executors import executor_kwargs as base_executor_kwargs from ..executors import executor_kwargs as base_executor_kwargs
from ..executors.executorselenium import (SeleniumTestharnessExecutor, # noqa: F401 from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
SeleniumRefTestExecutor) # noqa: F401 WebDriverRefTestExecutor) # noqa: F401
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401 from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
from ..webdriver_server import WebKitDriverServer from ..webdriver_server import WebKitDriverServer
@ -10,8 +10,8 @@ __wptrunner__ = {"product": "webkit",
"check_args": "check_args", "check_args": "check_args",
"browser": "WebKitBrowser", "browser": "WebKitBrowser",
"browser_kwargs": "browser_kwargs", "browser_kwargs": "browser_kwargs",
"executor": {"testharness": "SeleniumTestharnessExecutor", "executor": {"testharness": "WebDriverTestharnessExecutor",
"reftest": "SeleniumRefTestExecutor", "reftest": "WebDriverRefTestExecutor",
"wdspec": "WebKitDriverWdspecExecutor"}, "wdspec": "WebKitDriverWdspecExecutor"},
"executor_kwargs": "executor_kwargs", "executor_kwargs": "executor_kwargs",
"env_extras": "env_extras", "env_extras": "env_extras",
@ -31,11 +31,12 @@ def browser_kwargs(test_type, run_info_data, config, **kwargs):
def capabilities_for_port(server_config, **kwargs): def capabilities_for_port(server_config, **kwargs):
from selenium.webdriver import DesiredCapabilities
if kwargs["webkit_port"] == "gtk": if kwargs["webkit_port"] == "gtk":
capabilities = dict(DesiredCapabilities.WEBKITGTK.copy()) capabilities = {
capabilities["webkitgtk:browserOptions"] = { "browserName": "MiniBrowser",
"browserVersion": "2.20",
"platformName": "ANY",
"webkitgtk:browserOptions": {
"binary": kwargs["binary"], "binary": kwargs["binary"],
"args": kwargs.get("binary_args", []), "args": kwargs.get("binary_args", []),
"certificates": [ "certificates": [
@ -43,6 +44,8 @@ def capabilities_for_port(server_config, **kwargs):
"certificateFile": kwargs["host_cert_path"]} "certificateFile": kwargs["host_cert_path"]}
] ]
} }
}
return capabilities return capabilities
return {} return {}

View file

@ -8,7 +8,7 @@ import uuid
from mozprocess import ProcessHandler from mozprocess import ProcessHandler
from serve.serve import make_hosts_file from tools.serve.serve import make_hosts_file
from .base import (ConnectionlessProtocol, from .base import (ConnectionlessProtocol,
RefTestImplementation, RefTestImplementation,

View file

@ -144,12 +144,10 @@ class TestTrickle(TestUsingServer):
self.assertEqual(resp.info()["Expires"], "0") self.assertEqual(resp.info()["Expires"], "0")
class TestPipesWithVariousHandlers(TestUsingServer): class TestPipesWithVariousHandlers(TestUsingServer):
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_with_python_file_handler(self): def test_with_python_file_handler(self):
resp = self.request("/test_string.py", query="pipe=slice(null,2)") resp = self.request("/test_string.py", query="pipe=slice(null,2)")
self.assertEqual(resp.read(), "PA") self.assertEqual(resp.read(), b"PA")
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_with_python_func_handler(self): def test_with_python_func_handler(self):
@wptserve.handlers.handler @wptserve.handlers.handler
def handler(request, response): def handler(request, response):
@ -157,9 +155,8 @@ class TestPipesWithVariousHandlers(TestUsingServer):
route = ("GET", "/test/test_pipes_1/", handler) route = ("GET", "/test/test_pipes_1/", handler)
self.server.router.register(*route) self.server.router.register(*route)
resp = self.request(route[1], query="pipe=slice(null,2)") resp = self.request(route[1], query="pipe=slice(null,2)")
self.assertEqual(resp.read(), "PA") self.assertEqual(resp.read(), b"PA")
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_with_python_func_handler_using_response_writer(self): def test_with_python_func_handler_using_response_writer(self):
@wptserve.handlers.handler @wptserve.handlers.handler
def handler(request, response): def handler(request, response):
@ -168,9 +165,8 @@ class TestPipesWithVariousHandlers(TestUsingServer):
self.server.router.register(*route) self.server.router.register(*route)
resp = self.request(route[1], query="pipe=slice(null,2)") resp = self.request(route[1], query="pipe=slice(null,2)")
# slice has not been applied to the response, because response.writer was used. # slice has not been applied to the response, because response.writer was used.
self.assertEqual(resp.read(), "PASS") self.assertEqual(resp.read(), b"PASS")
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_header_pipe_with_python_func_using_response_writer(self): def test_header_pipe_with_python_func_using_response_writer(self):
@wptserve.handlers.handler @wptserve.handlers.handler
def handler(request, response): def handler(request, response):
@ -180,7 +176,7 @@ class TestPipesWithVariousHandlers(TestUsingServer):
resp = self.request(route[1], query="pipe=header(X-TEST,FAIL)") resp = self.request(route[1], query="pipe=header(X-TEST,FAIL)")
# header pipe was ignored, because response.writer was used. # header pipe was ignored, because response.writer was used.
self.assertFalse(resp.info().get("X-TEST")) self.assertFalse(resp.info().get("X-TEST"))
self.assertEqual(resp.read(), "CONTENT") self.assertEqual(resp.read(), b"CONTENT")
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2") @pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_with_json_handler(self): def test_with_json_handler(self):
@ -192,30 +188,27 @@ class TestPipesWithVariousHandlers(TestUsingServer):
resp = self.request(route[1], query="pipe=slice(null,2)") resp = self.request(route[1], query="pipe=slice(null,2)")
self.assertEqual(resp.read(), '"{') self.assertEqual(resp.read(), '"{')
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_slice_with_as_is_handler(self): def test_slice_with_as_is_handler(self):
resp = self.request("/test.asis", query="pipe=slice(null,2)") resp = self.request("/test.asis", query="pipe=slice(null,2)")
self.assertEqual(202, resp.getcode()) self.assertEqual(202, resp.getcode())
self.assertEqual("Giraffe", resp.msg) self.assertEqual("Giraffe", resp.msg)
self.assertEqual("PASS", resp.info()["X-Test"]) self.assertEqual("PASS", resp.info()["X-Test"])
# slice has not been applied to the response, because response.writer was used. # slice has not been applied to the response, because response.writer was used.
self.assertEqual("Content", resp.read()) self.assertEqual(b"Content", resp.read())
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_headers_with_as_is_handler(self): def test_headers_with_as_is_handler(self):
resp = self.request("/test.asis", query="pipe=header(X-TEST,FAIL)") resp = self.request("/test.asis", query="pipe=header(X-TEST,FAIL)")
self.assertEqual(202, resp.getcode()) self.assertEqual(202, resp.getcode())
self.assertEqual("Giraffe", resp.msg) self.assertEqual("Giraffe", resp.msg)
# header pipe was ignored. # header pipe was ignored.
self.assertEqual("PASS", resp.info()["X-TEST"]) self.assertEqual("PASS", resp.info()["X-TEST"])
self.assertEqual("Content", resp.read()) self.assertEqual(b"Content", resp.read())
@pytest.mark.xfail(sys.version_info >= (3,), reason="wptserve only works on Py2")
def test_trickle_with_as_is_handler(self): def test_trickle_with_as_is_handler(self):
t0 = time.time() t0 = time.time()
resp = self.request("/test.asis", query="pipe=trickle(1:d2:5:d1:r2)") resp = self.request("/test.asis", query="pipe=trickle(1:d2:5:d1:r2)")
t1 = time.time() t1 = time.time()
self.assertTrue('Content' in resp.read()) self.assertTrue(b'Content' in resp.read())
self.assertGreater(6, t1-t0) self.assertGreater(6, t1-t0)
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -1,29 +1,32 @@
from . import utils from . import utils
content_types = utils.invert_dict({"text/html": ["htm", "html"], content_types = utils.invert_dict({
"application/json": ["json"], "application/json": ["json"],
"application/wasm": ["wasm"],
"application/xhtml+xml": ["xht", "xhtm", "xhtml"], "application/xhtml+xml": ["xht", "xhtm", "xhtml"],
"application/xml": ["xml"], "application/xml": ["xml"],
"application/x-xpinstall": ["xpi"], "application/x-xpinstall": ["xpi"],
"text/javascript": ["js"], "audio/mp4": ["m4a"],
"text/css": ["css"], "audio/mpeg": ["mp3"],
"text/plain": ["txt", "md"], "audio/ogg": ["oga"],
"image/svg+xml": ["svg"], "audio/webm": ["weba"],
"audio/x-wav": ["wav"],
"image/bmp": ["bmp"],
"image/gif": ["gif"], "image/gif": ["gif"],
"image/jpeg": ["jpg", "jpeg"], "image/jpeg": ["jpg", "jpeg"],
"image/png": ["png"], "image/png": ["png"],
"image/bmp": ["bmp"], "image/svg+xml": ["svg"],
"text/event-stream": ["event_stream"],
"text/cache-manifest": ["manifest"], "text/cache-manifest": ["manifest"],
"text/css": ["css"],
"text/event-stream": ["event_stream"],
"text/html": ["htm", "html"],
"text/javascript": ["js"],
"text/plain": ["txt", "md"],
"text/vtt": ["vtt"],
"video/mp4": ["mp4", "m4v"], "video/mp4": ["mp4", "m4v"],
"audio/mp4": ["m4a"],
"audio/mpeg": ["mp3"],
"video/webm": ["webm"],
"audio/webm": ["weba"],
"video/ogg": ["ogg", "ogv"], "video/ogg": ["ogg", "ogv"],
"audio/ogg": ["oga"], "video/webm": ["webm"],
"audio/x-wav": ["wav"], })
"text/vtt": ["vtt"],})
response_codes = { response_codes = {
100: ('Continue', 'Request received, please continue'), 100: ('Continue', 'Request received, please continue'),

View file

@ -183,8 +183,10 @@ class Response(object):
True, the entire content of the file will be returned as a string facilitating True, the entire content of the file will be returned as a string facilitating
non-streaming operations like template substitution. non-streaming operations like template substitution.
""" """
if isinstance(self.content, (binary_type, text_type)): if isinstance(self.content, binary_type):
yield self.content yield self.content
elif isinstance(self.content, text_type):
yield self.content.encode(self.encoding)
elif hasattr(self.content, "read"): elif hasattr(self.content, "read"):
if read_file: if read_file:
yield self.content.read() yield self.content.read()

View file

@ -0,0 +1,23 @@
// META: global=window,worker
const contenttypes = [
"",
"application/javascript",
"application/octet-stream",
"text/wasm",
"application/wasm;",
"application/wasm;x",
"application/wasm;charset=UTF-8",
];
for (const contenttype of contenttypes) {
promise_test(t => {
const response = fetch(`/wasm/incrementer.wasm?pipe=header(Content-Type,${encodeURIComponent(contenttype)})`);
return promise_rejects(t, new TypeError(), WebAssembly.compileStreaming(response));
}, `Response with Content-Type ${format_value(contenttype)}: compileStreaming`);
promise_test(t => {
const response = fetch(`/wasm/incrementer.wasm?pipe=header(Content-Type,${encodeURIComponent(contenttype)})`);
return promise_rejects(t, new TypeError(), WebAssembly.instantiateStreaming(response));
}, `Response with Content-Type ${format_value(contenttype)}: instantiateStreaming`);
}

View file

@ -22,8 +22,7 @@ test(t => {
+ ' and no pending tasks') + ' and no pending tasks')
test(t => { test(t => {
const div = createDiv(t); const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
const animation = div.animate({}, 100 * MS_PER_SEC);
animation.pause(); animation.pause();
@ -134,8 +133,7 @@ test(t => {
+ ' current time = 0'); + ' current time = 0');
test(t => { test(t => {
const div = createDiv(t); const animation = createDiv(t).animate({}, 0);
const animation = div.animate({}, 0);
assert_equals(animation.startTime, null, assert_equals(animation.startTime, null,
'Sanity check: start time should be unresolved'); 'Sanity check: start time should be unresolved');
@ -144,8 +142,7 @@ test(t => {
+ ' current time = target effect end and there is a pending play task'); + ' current time = target effect end and there is a pending play task');
test(t => { test(t => {
const div = createDiv(t); const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
const animation = div.animate({}, 100 * MS_PER_SEC);
assert_equals(animation.startTime, null, assert_equals(animation.startTime, null,
'Sanity check: start time should be unresolved'); 'Sanity check: start time should be unresolved');
@ -153,5 +150,36 @@ test(t => {
}, 'reports \'running\' when playback rate > 0 and' }, 'reports \'running\' when playback rate > 0 and'
+ ' current time < target effect end and there is a pending play task'); + ' current time < target effect end and there is a pending play task');
test(t => {
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
assert_equals(animation.playState, 'running');
assert_true(animation.pending);
}, 'reports \'running\' for a play-pending animation');
test(t => {
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
animation.pause();
assert_equals(animation.playState, 'paused');
assert_true(animation.pending);
}, 'reports \'paused\' for a pause-pending animation');
test(t => {
const animation = createDiv(t).animate({}, 0);
assert_equals(animation.playState, 'finished');
assert_true(animation.pending);
}, 'reports \'finished\' for a finished-pending animation');
test(t => {
const animation = createDiv(t).animate({}, 100 * MS_PER_SEC);
// Set up the pending playback rate
animation.updatePlaybackRate(-1);
// Call play again so that we seek to the end while remaining play-pending
animation.play();
// For a pending animation, the play state should always report what the
// play state _will_ be once we finish pending.
assert_equals(animation.playState, 'running');
assert_true(animation.pending);
}, 'reports the play state based on the pending playback rate');
</script> </script>
</body> </body>

View file

@ -15,12 +15,6 @@
// makeIceTransport // makeIceTransport
// makeGatherAndStartTwoIceTransports // makeGatherAndStartTwoIceTransports
function makeIceTransport(t) {
const iceTransport = new RTCIceTransport();
t.add_cleanup(() => iceTransport.stop());
return iceTransport;
}
test(() => { test(() => {
const iceTransport = new RTCIceTransport(); const iceTransport = new RTCIceTransport();
}, 'RTCIceTransport constructor does not throw'); }, 'RTCIceTransport constructor does not throw');
@ -260,4 +254,49 @@ promise_test(async t => {
]); ]);
}, 'Two RTCIceTransports connect to each other'); }, 'Two RTCIceTransports connect to each other');
promise_test(async t => {
async function waitForConnectedThenSelectedCandidatePairChange(t, transport,
transportName) {
const watcher = new EventWatcher(t, transport,
[ 'statechange', 'selectedcandidatepairchange' ]);
await watcher.wait_for('statechange');
assert_equals(transport.state, 'connected',
`${transportName} state should be 'connected'`);
await watcher.wait_for('selectedcandidatepairchange');
const selectedCandidatePair = transport.getSelectedCandidatePair();
assert_not_equals(selectedCandidatePair, null,
`${transportName} selected candidate pair should not be null once ` +
'the selectedcandidatepairchange event fires');
assert_true(
transport.getLocalCandidates().some(
({ candidate }) =>
candidate === selectedCandidatePair.local.candidate),
`${transportName} selected candidate pair local should be in the ` +
'list of local candidates');
assert_true(
transport.getRemoteCandidates().some(
({ candidate }) =>
candidate === selectedCandidatePair.remote.candidate),
`${transportName} selected candidate pair local should be in the ` +
'list of remote candidates');
}
const [ localTransport, remoteTransport ] =
makeGatherAndStartTwoIceTransports(t);
await Promise.all([
waitForConnectedThenSelectedCandidatePairChange(t, localTransport,
'local transport'),
waitForConnectedThenSelectedCandidatePairChange(t, remoteTransport,
'remote transport'),
]);
}, 'Selected candidate pair changes once the RTCIceTransports connect.');
promise_test(async t => {
const [ transport, ] = makeGatherAndStartTwoIceTransports(t);
const watcher = new EventWatcher(t, transport, 'selectedcandidatepairchange');
await watcher.wait_for('selectedcandidatepairchange');
transport.stop();
assert_equals(transport.getSelectedCandidatePair(), null);
}, 'getSelectedCandidatePair() returns null once the RTCIceTransport is ' +
'stopped.');
</script> </script>

View file

@ -354,56 +354,6 @@
}); });
}, `addTransceiver() with valid rid value should succeed`); }, `addTransceiver() with valid rid value should succeed`);
/*
5.1. addTransceiver
7. If any RTCRtpEncodingParameters dictionary in sendEncodings contains a
read-only parameter other than rid, throw an InvalidAccessError.
- The sendEncodings argument can be used to specify the number of offered
simulcast encodings, and optionally their RIDs and encoding parameters.
Aside from rid , all read-only parameters in the RTCRtpEncodingParameters
dictionaries, such as ssrc, must be left unset, or an error will be thrown.
*/
test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws('InvalidAccessError', () =>
pc.addTransceiver('audio', {
sendEncodings: [{
ssrc: 2
}]
}));
}, `addTransceiver() with readonly ssrc set should throw InvalidAccessError`);
test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws('InvalidAccessError', () =>
pc.addTransceiver('audio', {
sendEncodings: [{
rtx: {
ssrc: 2
}
}]
}));
}, `addTransceiver() with readonly rtx set should throw InvalidAccessError`);
test(t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
assert_throws('InvalidAccessError', () =>
pc.addTransceiver('audio', {
sendEncodings: [{
fec: {
ssrc: 2
}
}]
}));
}, `addTransceiver() with readonly fec set should throw InvalidAccessError`);
test(t => { test(t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close()); t.add_cleanup(() => pc.close());

View file

@ -13,19 +13,25 @@
// The following helper functions are called from RTCQuicTransport-helper.js: // The following helper functions are called from RTCQuicTransport-helper.js:
// makeStandaloneQuicTransport // makeStandaloneQuicTransport
// makeTwoConnectedQuicTransports
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const quicStream = quicTransport.createStream(); const quicStream = quicTransport.createStream();
assert_equals(quicStream.transport, quicTransport, assert_equals(quicStream.transport, quicTransport,
'Expect transport to be set to the creating RTCQuicTransport.'); 'Expect transport to be set to the creating RTCQuicTransport.');
assert_equals(quicStream.state, 'new', `Expect state to be 'new'.`); assert_equals(quicStream.state, 'open', `Expect state to be 'open'.`);
assert_equals(quicStream.readBufferedAmount, 0, assert_equals(quicStream.readBufferedAmount, 0,
'Expect read buffered amount to be 0.'); 'Expect read buffered amount to be 0.');
assert_equals(quicStream.writeBufferedAmount, 0, assert_equals(quicStream.writeBufferedAmount, 0,
'Expect write buffered amount to be 0.'); 'Expect write buffered amount to be 0.');
}, 'createStream() returns an RTCQuicStream with initial properties set.'); }, 'createStream() returns an RTCQuicStream with initial properties set.');
promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t);
assert_throws('InvalidStateError', () => quicTransport.createStream());
}, 'createStream() throws if the transport is not connected.');
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const quicTransport = await makeStandaloneQuicTransport(t);
quicTransport.stop(); quicTransport.stop();
@ -33,12 +39,120 @@ promise_test(async t => {
}, 'createStream() throws if the transport is closed.'); }, 'createStream() throws if the transport is closed.');
promise_test(async t => { promise_test(async t => {
const quicTransport = await makeStandaloneQuicTransport(t); const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
const firstQuicStream = quicTransport.createStream(); const firstQuicStream = quicTransport.createStream();
const secondQuicStream = quicTransport.createStream(); const secondQuicStream = quicTransport.createStream();
quicTransport.stop(); quicTransport.stop();
assert_equals(firstQuicStream.state, 'closed'); assert_equals(firstQuicStream.state, 'closed');
assert_equals(secondQuicStream.state, 'closed'); assert_equals(secondQuicStream.state, 'closed');
}, 'RTCQuicTransport.stop() closes all streams.'); }, 'RTCQuicTransport.stop() closes all local streams.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const firstLocalStream = localQuicTransport.createStream();
firstLocalStream.finish();
const secondLocalStream = localQuicTransport.createStream();
secondLocalStream.finish();
const remoteWatcher =
new EventWatcher(t, remoteQuicTransport, [ 'quicstream', 'statechange' ]);
const { stream: firstRemoteStream } =
await remoteWatcher.wait_for('quicstream');
const { stream: secondRemoteStream } =
await remoteWatcher.wait_for('quicstream');
localQuicTransport.stop();
await remoteWatcher.wait_for('statechange');
assert_equals(firstRemoteStream.state, 'closed');
assert_equals(secondRemoteStream.state, 'closed');
}, 'RTCQuicTransport.stop() closes all remote streams.');
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
assert_equals(localStream.state, 'closing');
}, `finish() changes state to 'closing'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.finish();
assert_equals(localStream.state, 'closing');
}, `finish() twice does not change state.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.reset();
assert_equals(localStream.state, 'closed');
}, `reset() changes state to 'closed'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.reset();
assert_equals(localStream.state, 'closed');
}, `reset() following finish() changes state to 'closed'.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
assert_equals(remoteStream.state, 'open');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closing');
}, 'createStream() followed by finish() fires a quicstream event followed by ' +
`a statechange event to 'closing' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.reset();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
assert_equals(remoteStream.state, 'open');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closed');
}, 'createStream() followed by reset() fires a quicstream event followed ' +
`by a statechange event to 'closed' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
remoteQuicTransport.onquicstream = ({ stream }) => stream.reset();
const localStream = localQuicTransport.createStream();
localStream.finish();
const localWatcher = new EventWatcher(t, localStream, 'statechange');
await localWatcher.wait_for('statechange');
assert_equals(localStream.state, 'closed');
}, 'finish() on a remote stream that has already finished fires a ' +
`statechange event to 'closed' on the remote side.`);
promise_test(async t => {
const [ localQuicTransport, remoteQuicTransport ] =
await makeTwoConnectedQuicTransports(t);
const localStream = localQuicTransport.createStream();
localStream.finish();
localStream.reset();
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closing');
await remoteStreamWatcher.wait_for('statechange');
assert_equals(remoteStream.state, 'closed');
}, 'finish() then reset() fires two statechange events on the remote side.');
</script> </script>

View file

@ -79,4 +79,3 @@ async function makeTwoConnectedQuicTransports(t) {
]); ]);
return [ localQuicTransport, remoteQuicTransport ]; return [ localQuicTransport, remoteQuicTransport ];
} }

View file

@ -17,6 +17,7 @@
// makeAndGatherTwoIceTransports // makeAndGatherTwoIceTransports
// The following helper functions are called from RTCQuicTransport-helper.js: // The following helper functions are called from RTCQuicTransport-helper.js:
// generateCertificate
// makeQuicTransport // makeQuicTransport
// makeStandaloneQuicTransport // makeStandaloneQuicTransport
// makeAndStartTwoQuicTransports // makeAndStartTwoQuicTransports

View file

@ -45,15 +45,6 @@
}; };
dictionary RTCRtpEncodingParameters { dictionary RTCRtpEncodingParameters {
[readonly]
unsigned long ssrc;
[readonly]
RTCRtpRtxParameters rtx;
[readonly]
RTCRtpFecParameters fec;
RTCDtxStatus dtx; RTCDtxStatus dtx;
boolean active; boolean active;
RTCPriorityType priority; RTCPriorityType priority;
@ -67,16 +58,6 @@
double scaleResolutionDownBy; double scaleResolutionDownBy;
}; };
dictionary RTCRtpRtxParameters {
[readonly]
unsigned long ssrc;
};
dictionary RTCRtpFecParameters {
[readonly]
unsigned long ssrc;
};
enum RTCDtxStatus { enum RTCDtxStatus {
"disabled", "disabled",
"enabled" "enabled"
@ -229,32 +210,9 @@
param.encodings = undefined; param.encodings = undefined;
return promise_rejects(t, 'InvalidModificationError', return promise_rejects(t, new TypeError(),
sender.setParameters(param)); sender.setParameters(param));
}, `sender.setParameters() with encodings unset should reject with InvalidModificationError`); }, `sender.setParameters() with encodings unset should reject with TypeError`);
promise_test(async t => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const { sender } = pc.addTransceiver('audio');
await doOfferAnswerExchange(t, pc);
const param = sender.getParameters();
validateSenderRtpParameters(param);
const encoding = getFirstEncoding(param);
const { rtx } = encoding;
if(rtx === undefined) {
encoding.rtx = { ssrc: 2 };
} else if(rtx.ssrc === undefined) {
rtx.ssrc = 2;
} else {
rtx.ssrc += 1;
}
return promise_rejects(t, 'InvalidModificationError',
sender.setParameters(param));
}, `setParameters() with modified encoding.rtx field should reject with InvalidModificationError`);
promise_test(async t => { promise_test(async t => {
const pc = new RTCPeerConnection(); const pc = new RTCPeerConnection();

View file

@ -69,11 +69,6 @@ function validateSenderRtpParameters(param) {
When getParameters is called, the RTCRtpParameters dictionary is constructed When getParameters is called, the RTCRtpParameters dictionary is constructed
as follows: as follows:
- encodings is populated based on SSRCs and RIDs present in the current remote
description, including SSRCs used for RTX and FEC, if signaled. Every member
of the RTCRtpEncodingParameters dictionaries other than the SSRC and RID fields
is left undefined.
- The headerExtensions sequence is populated based on the header extensions that - The headerExtensions sequence is populated based on the header extensions that
the receiver is currently prepared to receive. the receiver is currently prepared to receive.
@ -144,15 +139,6 @@ function validateRtpParameters(param) {
/* /*
dictionary RTCRtpEncodingParameters { dictionary RTCRtpEncodingParameters {
[readonly]
unsigned long ssrc;
[readonly]
RTCRtpRtxParameters rtx;
[readonly]
RTCRtpFecParameters fec;
RTCDtxStatus dtx; RTCDtxStatus dtx;
boolean active; boolean active;
RTCPriorityType priority; RTCPriorityType priority;
@ -166,16 +152,6 @@ function validateRtpParameters(param) {
double scaleResolutionDownBy; double scaleResolutionDownBy;
}; };
dictionary RTCRtpRtxParameters {
[readonly]
unsigned long ssrc;
};
dictionary RTCRtpFecParameters {
[readonly]
unsigned long ssrc;
};
enum RTCDtxStatus { enum RTCDtxStatus {
"disabled", "disabled",
"enabled" "enabled"
@ -189,18 +165,6 @@ function validateRtpParameters(param) {
}; };
*/ */
function validateEncodingParameters(encoding) { function validateEncodingParameters(encoding) {
assert_optional_unsigned_int_field(encoding, 'ssrc');
assert_optional_dict_field(encoding, 'rtx');
if(encoding.rtx) {
assert_unsigned_int_field(encoding.rtx, 'ssrc');
}
assert_optional_dict_field(encoding, 'fec');
if(encoding.fec) {
assert_unsigned_int_field(encoding.fec, 'ssrc');
}
assert_optional_enum_field(encoding, 'dtx', assert_optional_enum_field(encoding, 'dtx',
['disabled', 'enabled']); ['disabled', 'enabled']);

View file

@ -22,11 +22,6 @@
When getParameters is called, the RTCRtpParameters dictionary is constructed When getParameters is called, the RTCRtpParameters dictionary is constructed
as follows: as follows:
- encodings is populated based on SSRCs and RIDs present in the current remote
description, including SSRCs used for RTX and FEC, if signaled. Every member
of the RTCRtpEncodingParameters dictionaries other than the SSRC and RID fields
is left undefined.
- The headerExtensions sequence is populated based on the header extensions that - The headerExtensions sequence is populated based on the header extensions that
the receiver is currently prepared to receive. the receiver is currently prepared to receive.

View file

@ -17,3 +17,6 @@
[WebGL test #588: could not create image (SVG)] [WebGL test #588: could not create image (SVG)]
expected: FAIL expected: FAIL
[WebGL test #156: could not create image (SVG)]
expected: FAIL