diff options
author | WPT Sync Bot <josh+wptsync@joshmatthews.net> | 2018-10-30 21:33:00 -0400 |
---|---|---|
committer | WPT Sync Bot <josh+wptsync@joshmatthews.net> | 2018-10-30 23:10:39 -0400 |
commit | 9f516d37179b66a56e93da6b311fd7f2a49e5bb6 (patch) | |
tree | 7a087809ee6fc832833af3bb3c124aaec84356cd | |
parent | cc0ac89e1a3af52439cdb8a79d01e12224c8ad11 (diff) | |
download | servo-9f516d37179b66a56e93da6b311fd7f2a49e5bb6.tar.gz servo-9f516d37179b66a56e93da6b311fd7f2a49e5bb6.zip |
Update web-platform-tests to revision b704e37ec97fe90b3a3d59c10f78c21907b5b576
70 files changed, 1685 insertions, 803 deletions
diff --git a/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini index dd4ffcf4345..76b398963ae 100644 --- a/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini +++ b/tests/wpt/metadata/FileAPI/url/url-in-tags-revoke.window.js.ini @@ -1,4 +1,5 @@ [url-in-tags-revoke.window.html] + expected: TIMEOUT [Fetching a blob URL immediately before revoking it works in an iframe.] expected: FAIL @@ -14,3 +15,6 @@ [Opening a blob URL in a new window by clicking an <a> tag works immediately before revoking the URL.] expected: FAIL + [Fetching a blob URL immediately before revoking it works in <script> tags.] + expected: TIMEOUT + diff --git a/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini b/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini index 947e223fb28..3a3d15b8406 100644 --- a/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini +++ b/tests/wpt/metadata/FileAPI/url/url-with-fetch.any.js.ini @@ -14,6 +14,9 @@ [Revoke blob URL after creating Request, will fetch] expected: FAIL + [Revoke blob URL after calling fetch, fetch should succeed] + expected: FAIL + [url-with-fetch.any.html] [Untitled] @@ -34,3 +37,6 @@ [Revoke blob URL after creating Request, will fetch] expected: FAIL + [Revoke blob URL after calling fetch, fetch should succeed] + expected: FAIL + diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json index 6426d83ab0d..ae29e32f819 100644 --- a/tests/wpt/metadata/MANIFEST.json +++ b/tests/wpt/metadata/MANIFEST.json @@ -147133,6 +147133,18 @@ {} ] ], + "css/css-transforms/text-perspective-001.html": [ + [ + "/css/css-transforms/text-perspective-001.html", + [ + [ + "about:blank", + "!=" + ] + ], + {} + ] + ], "css/css-transforms/transform-3d-rotateY-stair-above-001.xht": [ [ "/css/css-transforms/transform-3d-rotateY-stair-above-001.xht", @@ -188569,6 +188581,18 @@ {} ] ], + "html/rendering/replaced-elements/the-select-element/select-1-block-size.html": [ + [ + "/html/rendering/replaced-elements/the-select-element/select-1-block-size.html", + [ + [ + "/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html", + "==" + ] + ], + {} + ] + ], "html/rendering/replaced-elements/the-select-element/select-1-line-height.html": [ [ "/html/rendering/replaced-elements/the-select-element/select-1-line-height.html", @@ -188581,6 +188605,18 @@ {} ] ], + "html/rendering/replaced-elements/the-select-element/select-empty.html": [ + [ + "/html/rendering/replaced-elements/the-select-element/select-empty.html", + [ + [ + "/html/rendering/replaced-elements/the-select-element/select-empty-ref.html", + "==" + ] + ], + {} + ] + ], "html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html": [ [ "/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html", @@ -197254,6 +197290,11 @@ {} ] ], + "IndexedDB/key-generators/reading-autoincrement-common.js": [ + [ + {} + ] + ], "IndexedDB/nested-cloning-common.js": [ [ {} @@ -280139,6 +280180,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/values3/support/blue-32x32.png": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/variables/reftest.list": [ [ {} @@ -291834,11 +291880,21 @@ {} ] ], + "html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html": [ + [ + {} + ] + ], "html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html": [ [ {} ] ], + "html/rendering/replaced-elements/the-select-element/select-empty-ref.html": [ + [ + {} + ] + ], "html/rendering/replaced-elements/tools/gen-svgsizing-tests.py": [ [ {} @@ -316839,6 +316895,11 @@ {} ] ], + "webdriver/tests/support/fixtures.py": [ + [ + {} + ] + ], "webdriver/tests/support/helpers.py": [ [ {} @@ -316849,6 +316910,11 @@ {} ] ], + "webdriver/tests/support/image.py": [ + [ + {} + ] + ], "webdriver/tests/support/inline.py": [ [ {} @@ -326161,6 +326227,16 @@ {} ] ], + "IndexedDB/get-databases.any.js": [ + [ + "/IndexedDB/get-databases.any.html", + {} + ], + [ + "/IndexedDB/get-databases.any.worker.html", + {} + ] + ], "IndexedDB/globalscope-indexedDB-SameObject.html": [ [ "/IndexedDB/globalscope-indexedDB-SameObject.html", @@ -327949,6 +328025,78 @@ } ] ], + "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.js": [ + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.serviceworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.sharedworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.worker.html", + {} + ] + ], + "IndexedDB/key-generators/reading-autoincrement-indexes.any.js": [ + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes.any.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes.any.serviceworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes.any.sharedworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-indexes.any.worker.html", + {} + ] + ], + "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.js": [ + [ + "/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.serviceworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.sharedworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.worker.html", + {} + ] + ], + "IndexedDB/key-generators/reading-autoincrement-store.any.js": [ + [ + "/IndexedDB/key-generators/reading-autoincrement-store.any.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store.any.serviceworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store.any.sharedworker.html", + {} + ], + [ + "/IndexedDB/key-generators/reading-autoincrement-store.any.worker.html", + {} + ] + ], "IndexedDB/key_invalid.htm": [ [ "/IndexedDB/key_invalid.htm", @@ -400575,6 +400723,12 @@ {} ] ], + "service-workers/service-worker/postmessage-to-client-message-queue.https.html": [ + [ + "/service-workers/service-worker/postmessage-to-client-message-queue.https.html", + {} + ] + ], "service-workers/service-worker/postmessage-to-client.https.html": [ [ "/service-workers/service-worker/postmessage-to-client.https.html", @@ -436035,7 +436189,7 @@ "support" ], ".travis.yml": [ - "b14cfafbdf7a3b4380e746e939d1512ef55785ea", + "9d3431bc444a2da1dc674ef6673f692742191ad6", "support" ], ".well-known/README.md": [ @@ -440750,6 +440904,10 @@ "5db452ebafe68a095f083b65a713ba3e0ad40cf5", "testharness" ], + "IndexedDB/get-databases.any.js": [ + "f054e0fec2f0543eae7978303ae2a24858bdf245", + "testharness" + ], "IndexedDB/globalscope-indexedDB-SameObject.html": [ "7263aaaace5331310558e3f80b8509ac8246ed69", "testharness" @@ -441343,7 +441501,7 @@ "testharness" ], "IndexedDB/idbindex-rename-abort.html": [ - "b14d30122610bc7025a478c146fbac42128f7428", + "b61988e9b5c764b5b72b4937b8d76fd3aed15e67", "testharness" ], "IndexedDB/idbindex-rename-errors.html": [ @@ -441523,7 +441681,7 @@ "testharness" ], "IndexedDB/idbobjectstore-rename-abort.html": [ - "6e16c31e339f731e218044ee9320edba3d965661", + "75893cd84c012d4bc662ba11fd79ef1eacaf49cc", "testharness" ], "IndexedDB/idbobjectstore-rename-errors.html": [ @@ -441926,6 +442084,26 @@ "4dd5d9005b6cb6e4c2c7dccaef62804bfcdb73ec", "testharness" ], + "IndexedDB/key-generators/reading-autoincrement-common.js": [ + "45c8ffef923870909cb9b0e2af128081e5bce41a", + "support" + ], + "IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.js": [ + "d7938768fa152c20b4b58538350a51b78b38e445", + "testharness" + ], + "IndexedDB/key-generators/reading-autoincrement-indexes.any.js": [ + "d945b78bf3743bccd632dabdcb846af52c183110", + "testharness" + ], + "IndexedDB/key-generators/reading-autoincrement-store-cursors.any.js": [ + "05971098fa893ebe58de4b2ad05d84a4965b6e0d", + "testharness" + ], + "IndexedDB/key-generators/reading-autoincrement-store.any.js": [ + "bbba6a335139d5b2946b5f6d71a635fd5ee014c3", + "testharness" + ], "IndexedDB/key_invalid.htm": [ "30759d5ef3e594852990808621ce75c840d0ac39", "testharness" @@ -442035,7 +442213,7 @@ "testharness" ], "IndexedDB/support-promises.js": [ - "21e2163ec60eb3eee05269b83f583f77fad780eb", + "433af5092701d617e2964f7d1ea3ea089b50c441", "support" ], "IndexedDB/support.js": [ @@ -442131,7 +442309,7 @@ "support" ], "WebCryptoAPI/META.yml": [ - "ec95611b3fed980e2897a5fe2bedc6bb7fa2913d", + "8f27e484996c51eb9ebbbd96902fa1f885af7be0", "support" ], "WebCryptoAPI/README.md": [ @@ -445311,7 +445489,7 @@ "manual" ], "annotation-vocab/META.yml": [ - "030df88318ccaec889feaee3e25134f5504a678d", + "f99f921d352cbffa724fb0fa031eb60d2ceb2b83", "support" ], "annotation-vocab/tools/.gitignore": [ @@ -549075,7 +549253,7 @@ "manual" ], "css/css-grid/META.yml": [ - "f8482e16f983ca24e3333ae8989277f82b297ad1", + "18c574ac68bac7e5b95085d96c49347d5eb36814", "support" ], "css/css-grid/README.md": [ @@ -555963,7 +556141,7 @@ "testharness" ], "css/css-properties-values-api/registered-property-computation.html": [ - "180cdf601edd4a82398d29239141bf38e55bd0c1", + "2525e43ef51e1e5af94426346e51a68b87fea055", "testharness" ], "css/css-properties-values-api/registered-property-cssom.html": [ @@ -555971,15 +556149,15 @@ "testharness" ], "css/css-properties-values-api/registered-property-initial.html": [ - "24543d5c5fdc84706a28502d8cf8c2c7f925978e", + "77aa9cd11a3eabfd154cc98869699e6f24c64c5c", "testharness" ], "css/css-properties-values-api/resources/utils.js": [ - "c4dc3fd5a8d98106395e3e99566f05d6d9a30c0c", + "bef59560f68d84ed0d681bb22e0611ea2466024f", "support" ], "css/css-properties-values-api/self-utils.html": [ - "530c5f677ad25858a06281a9e526584e57081af5", + "05aa4b2fb03b29feee47177624715230768a44a0", "testharness" ], "css/css-properties-values-api/support/alt/alt.css": [ @@ -568398,6 +568576,10 @@ "2145190fec4cddb59f18a5ac1d5bfead0ce548fa", "support" ], + "css/css-transforms/text-perspective-001.html": [ + "e98b3e73b36a323a60ad5ef74e090ff193ad41b9", + "reftest" + ], "css/css-transforms/transform-2d-getComputedStyle-001.html": [ "a085b794fc4dbd01abd8cf779b691b541d0bf8e3", "testharness" @@ -584891,7 +585073,7 @@ "testharness" ], "css/geometry/META.yml": [ - "9e3a7979ed80210ccba78da767526aad875e00c2", + "98a2ae9860b2d682220dbf21eb2f3606ca68ff61", "support" ], "css/geometry/WebKitCSSMatrix.html": [ @@ -595359,19 +595541,19 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1-ref.html": [ - "a9d8056ccab98b795824ab62f7ca86175bc46c39", + "b64aa46bf2eeddfc89791c13f1cea946faefece5", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1.html": [ - "2a8bfdf65b0d08eef12775c1abe0698615ddbb7d", + "68351aef6e57dff3f065bad14630e81db171c0a6", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1-ref.html": [ - "16b89c1d805078574f3557b3c7791cb2ebef3d21", + "5385c46ef52592fa4535608ee09be865bff719ef", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1.html": [ - "e91f8c26ce1ec937f5225eb570b104033edfc26a", + "f52ceeeabe16a0011beb170d3bcc75852ae4e0cb", "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-border-radius-1-ref.html": [ @@ -595570,6 +595752,10 @@ "0f236cb3df999e9fb7d90ebf5ad05e97b3c269a1", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/values3/support/blue-32x32.png": [ + "deefd19b2ac53bef91c82ed2f6f4ea5f53a9e34f", + "support" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/variables/reftest.list": [ "baa90e4e9000c2df1f6bc487e25ecdf999a99cf5", "support" @@ -608659,7 +608845,7 @@ "testharness" ], "html/dom/elements/the-innertext-idl-attribute/getter-tests.js": [ - "5139ec97b05ce6d3cd9b84a20770065e9f81adb0", + "4dd2b6be20619cde5f244ca76d239aa9bbc50044", "support" ], "html/dom/elements/the-innertext-idl-attribute/getter.html": [ @@ -614194,6 +614380,14 @@ "3b8d992cc2a07dfd902dbb1011e2c348e862baaa", "reftest" ], + "html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html": [ + "3e437494c0ad8dadd4d58b630194678753516fde", + "support" + ], + "html/rendering/replaced-elements/the-select-element/select-1-block-size.html": [ + "4aecc596ce693a6cff3f6ffd5dbac1fa4911dfe8", + "reftest" + ], "html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html": [ "26e5f33282192b10f56cd66fefeda2c1b9d9b389", "support" @@ -614202,6 +614396,14 @@ "e6383f089ffa5550005f99257ecac7984dd09110", "reftest" ], + "html/rendering/replaced-elements/the-select-element/select-empty-ref.html": [ + "31ba23a5cf86f161b1204ea3f4c9fef4585af909", + "support" + ], + "html/rendering/replaced-elements/the-select-element/select-empty.html": [ + "6568a6de34985a7fc201ce0bd530b86b145083e8", + "reftest" + ], "html/rendering/replaced-elements/tools/gen-svgsizing-tests.py": [ "5ba69f8ab5ba0a74810c570d9a4f3d7ddd90a3ba", "support" @@ -636931,7 +637133,7 @@ "testharness" ], "pointerevents/META.yml": [ - "ef94157ef9a9df762f940f1c6b04128dd69f4f3b", + "be61ddddaf62acb3396ada6779ad3f50e6caa709", "support" ], "pointerevents/README.md": [ @@ -649762,8 +649964,12 @@ "29c056080c79d581975e0929dcebd84d63b86a20", "testharness" ], + "service-workers/service-worker/postmessage-to-client-message-queue.https.html": [ + "caa4f9445d3d8ad0ab92ba73713da17a33af185c", + "testharness" + ], "service-workers/service-worker/postmessage-to-client.https.html": [ - "b1dc41a018f273832f4ac90c17b4b981f095b0ef", + "15d2e889337078869e3c3e97d312649e6a8bd8b2", "testharness" ], "service-workers/service-worker/postmessage.https.html": [ @@ -651987,7 +652193,7 @@ "testharness" ], "speech-api/META.yml": [ - "17263d91d367f5571ac7df3616aa026bdb4f6433", + "ac4b89b03490dbb46c257a2e5fdec3a741acdd52", "support" ], "speech-api/SpeechRecognition-abort-manual.https.html": [ @@ -653319,7 +653525,7 @@ "testharness" ], "subresource-integrity/META.yml": [ - "740ad1412f671ad86d88098ae437a817cbd620d5", + "2b8891ec6b498cc6b24df46e21fffad437732b54", "support" ], "subresource-integrity/alternate.css": [ @@ -661615,7 +661821,7 @@ "support" ], "tools/wpt/run.py": [ - "a2cd1c0b115dff81a4cc0f356eb351fab51998f1", + "b977d8a0cd68ccb00b299c7840415f843c16f949", "support" ], "tools/wpt/testfiles.py": [ @@ -661643,7 +661849,7 @@ "support" ], "tools/wpt/utils.py": [ - "1e622a63859ac5da0d1aa0015a971083b23adbc9", + "fa60230389deb56686f6753171482b69ac28983c", "support" ], "tools/wpt/virtualenv.py": [ @@ -662111,7 +662317,7 @@ "support" ], "tools/wptrunner/wptrunner/testrunner.py": [ - "2b7c091c84722c750b46d6143c74c8d329a7fd99", + "e819f242e2df532d6e9c62e9292e1f563047c148", "support" ], "tools/wptrunner/wptrunner/tests/__init__.py": [ @@ -662255,7 +662461,7 @@ "support" ], "tools/wptrunner/wptrunner/wptrunner.py": [ - "0a5b1352e212fcb702f1824293a774ea48d78ef1", + "d0c1106b0f9bb1f2aa727e263cd1e74ab1b04c01", "support" ], "tools/wptrunner/wptrunner/wpttest.py": [ @@ -663307,7 +663513,7 @@ "testharness" ], "url/META.yml": [ - "459152f6f078042714905b3e1d2eaba1c415807b", + "3a789a0d513f0a78bf362dd73c8a807d0cd55a50", "support" ], "url/README.md": [ @@ -665667,7 +665873,7 @@ "support" ], "webaudio/META.yml": [ - "37276da53345515f79453de8c5ade6037ff6f9eb", + "e8f8cc59489e381dba1fd35e9d088a6de86a3783", "support" ], "webaudio/README.md": [ @@ -666755,7 +666961,7 @@ "wdspec" ], "webdriver/tests/conftest.py": [ - "d16883256aca4f600400f060719d0a7ac8d16dfd", + "42b82c9ecf29a1aed48bfa959c20aba6edd1319e", "support" ], "webdriver/tests/delete_all_cookies/__init__.py": [ @@ -666819,7 +667025,7 @@ "wdspec" ], "webdriver/tests/element_click/center_point.py": [ - "b3d2ea7a1098266530cb6e835861dcc7336b7091", + "21bf8f31fd8dd1c961008ab74330956dd11e14f2", "wdspec" ], "webdriver/tests/element_click/click.py": [ @@ -667475,23 +667681,31 @@ "support" ], "webdriver/tests/support/asserts.py": [ - "cdf313bc04b3e96e999b559de506b5595efe8419", + "1dea6ce68779269b005061a391f7553a6741157f", "support" ], "webdriver/tests/support/defaults.py": [ "c2020527a6f38a628b2c1a4199caaff46cf0c36b", "support" ], + "webdriver/tests/support/fixtures.py": [ + "d16883256aca4f600400f060719d0a7ac8d16dfd", + "support" + ], "webdriver/tests/support/helpers.py": [ - "b2db3e7b0d338f1325214cd8019b7cac613dd8b1", + "5dd7a323d8cc1a166acdb1b6445015b8b19d8c76", "support" ], "webdriver/tests/support/http_request.py": [ "5e46d97017e14ba009d4d1ed6d62bb5012f48d15", "support" ], + "webdriver/tests/support/image.py": [ + "1eb3a187a43b86ffe752d4d73f6e639bdd9e96da", + "support" + ], "webdriver/tests/support/inline.py": [ - "3bf56c84bedb47e024a88983fa15c232ddba7899", + "8b4f1657cffb193511da346bc4c236aac1d70308", "support" ], "webdriver/tests/support/merge_dictionaries.py": [ @@ -675751,7 +675965,7 @@ "testharness" ], "xhr/send-content-type-charset.htm": [ - "4e75df234682c91b7effa0de52f5f95a3ac438a4", + "0a91e1fbd7e061df3123163e049cc8aab90a67e2", "testharness" ], "xhr/send-content-type-string.htm": [ diff --git a/tests/wpt/metadata/css/css-fonts/variations/at-font-face-font-matching.html.ini b/tests/wpt/metadata/css/css-fonts/variations/at-font-face-font-matching.html.ini index 305de527a49..402de2dd591 100644 --- a/tests/wpt/metadata/css/css-fonts/variations/at-font-face-font-matching.html.ini +++ b/tests/wpt/metadata/css/css-fonts/variations/at-font-face-font-matching.html.ini @@ -53,9 +53,6 @@ [Matching font-weight: '500' should prefer '501 550' over '502 560'] expected: FAIL - [Matching font-weight: '501' should prefer '501' over '502 510'] - expected: FAIL - [Matching font-weight: '501' should prefer '502 510' over '503 520'] expected: FAIL @@ -137,9 +134,6 @@ [Matching font-style: 'oblique 21deg' should prefer 'oblique -50deg -20deg' over 'oblique -40deg -30deg'] expected: FAIL - [Matching font-style: 'oblique 10deg' should prefer 'oblique 10deg' over 'oblique 5deg'] - expected: FAIL - [Matching font-style: 'oblique 10deg' should prefer 'oblique 5deg' over 'oblique 15deg 20deg'] expected: FAIL @@ -203,9 +197,6 @@ [Matching font-style: 'oblique -10deg' should prefer 'oblique 0deg 10deg' over 'oblique 40deg 50deg'] expected: FAIL - [Matching font-style: 'oblique -20deg' should prefer 'oblique -20deg' over 'oblique -60deg -40deg'] - expected: FAIL - [Matching font-style: 'oblique -20deg' should prefer 'oblique -10deg' over 'italic'] expected: FAIL @@ -332,3 +323,6 @@ [Matching font-weight: '399' should prefer '350 399' over '340 360'] expected: FAIL + [Matching font-weight: '500' should prefer '450 460' over '400'] + expected: FAIL + diff --git a/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini b/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini index 384da3bc556..930d51de51f 100644 --- a/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini +++ b/tests/wpt/metadata/css/css-transitions/transitions-animatable-properties-01.html.ini @@ -71,51 +71,9 @@ [text-indent intermediate] expected: FAIL - [clip end] + [opacity end] expected: FAIL - [border-top-width end] - expected: FAIL - - [border-left-width end] - expected: FAIL - - [font-size end] - expected: FAIL - - [vertical-align end] - expected: FAIL - - [border-right-color end] - expected: FAIL - - [margin-right end] - expected: FAIL - - [max-width end] - expected: FAIL - - [height end] - expected: FAIL - - [bottom end] - expected: FAIL - - [top end] - expected: FAIL - - [font-weight end] - expected: FAIL - - [border-left-color end] - expected: FAIL - - [margin-bottom end] - expected: FAIL - - [border-right-width end] - expected: FAIL - - [padding-bottom intermediate] + [z-index end] expected: FAIL diff --git a/tests/wpt/metadata/encoding/single-byte-decoder.html.ini b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini index b0ddb349557..32626f90fad 100644 --- a/tests/wpt/metadata/encoding/single-byte-decoder.html.ini +++ b/tests/wpt/metadata/encoding/single-byte-decoder.html.ini @@ -2,7 +2,7 @@ type: testharness [single-byte-decoder.html?document] - expected: TIMEOUT + expected: CRASH [windows-1254: iso_8859-9 (document.characterSet and document.inputEncoding)] expected: FAIL @@ -509,6 +509,7 @@ [single-byte-decoder.html?XMLHttpRequest] + expected: CRASH [ISO-8859-2: iso_8859-2:1987 (XMLHttpRequest)] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/browsing-the-web/unloading-documents/beforeunload-canceling.html.ini b/tests/wpt/metadata/html/browsers/browsing-the-web/unloading-documents/beforeunload-canceling.html.ini deleted file mode 100644 index 2cc52f4040d..00000000000 --- a/tests/wpt/metadata/html/browsers/browsing-the-web/unloading-documents/beforeunload-canceling.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[beforeunload-canceling.html] - expected: TIMEOUT - [Returning 0 with a real iframe unloading; setting returnValue to foo] - expected: TIMEOUT - diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini new file mode 100644 index 00000000000..87b07c3e670 --- /dev/null +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_1.html.ini @@ -0,0 +1,4 @@ +[traverse_the_history_1.html] + [Multiple history traversals from the same task] + expected: FAIL + diff --git a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini index dc2e45516de..385376c7321 100644 --- a/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini @@ -1,4 +1,4 @@ -[traverse_the_history_5.html] +[traverse_the_history_4.html] [Multiple history traversals, last would be aborted] expected: FAIL diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini index 5de7bcd50f6..695cb7661a9 100644 --- a/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini +++ b/tests/wpt/metadata/html/browsers/history/the-location-interface/location-protocol-setter-non-broken.html.ini @@ -24,9 +24,6 @@ [Set HTTP URL frame location.protocol to gopher] expected: FAIL - [Set HTTP URL frame location.protocol to x] - expected: FAIL - [Set HTTP URL frame location.protocol to http+x] expected: FAIL diff --git a/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini b/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini index d67860013a4..e432b36d6cf 100644 --- a/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini +++ b/tests/wpt/metadata/html/dom/elements/the-innertext-idl-attribute/getter.html.ini @@ -266,3 +266,15 @@ [Whitespace around <img> should not be collapsed ("<div>abc <img width=1 height=1> def")] expected: FAIL + [text-transform handles Turkish casing ("<div><div lang='tr' style='text-transform:uppercase'>i ı")] + expected: FAIL + + [display:table-row on the element itself ("<div style='display:table-row'>")] + expected: FAIL + + [display:table-cell on the element itself ("<div style='display:table-cell'>")] + expected: FAIL + + [<br> ("<br>")] + expected: FAIL + diff --git a/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-1-block-size.html.ini b/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-1-block-size.html.ini new file mode 100644 index 00000000000..706aff5771a --- /dev/null +++ b/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-1-block-size.html.ini @@ -0,0 +1,2 @@ +[select-1-block-size.html] + expected: FAIL diff --git a/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-empty.html.ini b/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-empty.html.ini new file mode 100644 index 00000000000..06108e541fd --- /dev/null +++ b/tests/wpt/metadata/html/rendering/replaced-elements/the-select-element/select-empty.html.ini @@ -0,0 +1,2 @@ +[select-empty.html] + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html.ini index 22d1f1d6900..a6f7ac6f249 100644 --- a/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html.ini +++ b/tests/wpt/metadata/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html.ini @@ -5,5 +5,5 @@ expected: NOTRUN [calling play() on a sufficiently long video should trigger timeupdate event] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini b/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini new file mode 100644 index 00000000000..9e522297c94 --- /dev/null +++ b/tests/wpt/metadata/html/semantics/interactive-elements/the-details-element/toggleEvent.html.ini @@ -0,0 +1,7 @@ +[toggleEvent.html] + [Calling open twice on 'details' fires only one toggle event] + expected: FAIL + + [Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element] + expected: FAIL + diff --git a/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini new file mode 100644 index 00000000000..178680e5d14 --- /dev/null +++ b/tests/wpt/metadata/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html.ini @@ -0,0 +1,2 @@ +[script-onerror-insertion-point-2.html] + expected: TIMEOUT diff --git a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini index ce482a60da8..c6d49957c4a 100644 --- a/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini +++ b/tests/wpt/metadata/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/aborted-parser.window.js.ini @@ -2,6 +2,3 @@ [document.open() after parser is aborted] expected: FAIL - [async document.open() after parser is aborted] - expected: FAIL - diff --git a/tests/wpt/metadata/url/urlencoded-parser.any.js.ini b/tests/wpt/metadata/url/urlencoded-parser.any.js.ini index 98f06af7269..66b0152f73c 100644 --- a/tests/wpt/metadata/url/urlencoded-parser.any.js.ini +++ b/tests/wpt/metadata/url/urlencoded-parser.any.js.ini @@ -2,10 +2,16 @@ [request.formData() with input: &&&a=b&&&&c=d&] expected: FAIL - [response.formData() with input: a&b&c] + [request.formData() with input: a&b&c] expected: FAIL - [request.formData() with input: a&b&c] + [request.formData() with input: _charset_=windows-1252&test=%C2x] + expected: FAIL + + [response.formData() with input: _charset_=windows-1252&test=%C2x] + expected: FAIL + + [request.formData() with input: a=b&c=d&] expected: FAIL @@ -25,6 +31,6 @@ [request.formData() with input: &&&a=b&&&&c=d&] expected: FAIL - [response.formData() with input: _charset_=windows-1252&test=%C2x] + [request.formData() with input: a=b&c=d&] expected: FAIL diff --git a/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini b/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini index bf2a1d61bab..bfd4d6dd2d6 100644 --- a/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini +++ b/tests/wpt/metadata/workers/baseurl/alpha/import-in-moduleworker.html.ini @@ -1,4 +1,5 @@ [import-in-moduleworker.html] + expected: ERROR [Base URL in module dedicated workers: import] expected: FAIL diff --git a/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini b/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini index 62dd192867b..c2a07ab0aa7 100644 --- a/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini +++ b/tests/wpt/metadata/xhr/send-content-type-charset.htm.ini @@ -45,3 +45,21 @@ [unknown parameters need to be preserved] expected: FAIL + [charset with space that is UTF-8 does not change] + expected: FAIL + + [charset in double quotes with backslashes that is UTF-8 does not change] + expected: FAIL + + [If charset= param is UTF-8 (case-insensitive), it should not be changed (bogus charset)] + expected: FAIL + + [Multiple non-UTF-8 charset parameters deduplicate, bogus parameter dropped] + expected: FAIL + + [If charset= param is UTF-8 (case-insensitive), it should not be changed] + expected: FAIL + + [charset in double quotes that is UTF-8 does not change] + expected: FAIL + diff --git a/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini b/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini new file mode 100644 index 00000000000..dbea4f293ad --- /dev/null +++ b/tests/wpt/mozilla/meta/css/transition_calc_implicit.html.ini @@ -0,0 +1,2 @@ +[transition_calc_implicit.html] + expected: TIMEOUT diff --git a/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini b/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini deleted file mode 100644 index ac7c34f241f..00000000000 --- a/tests/wpt/mozilla/meta/mozilla/unitless-length.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[unitless-length.html] - expected: TIMEOUT diff --git a/tests/wpt/web-platform-tests/.travis.yml b/tests/wpt/web-platform-tests/.travis.yml index b14cfafbdf7..9d3431bc444 100644 --- a/tests/wpt/web-platform-tests/.travis.yml +++ b/tests/wpt/web-platform-tests/.travis.yml @@ -74,7 +74,7 @@ matrix: os: linux python: "3.6" env: JOB=tools_unittest TOXENV=py36 HYPOTHESIS_PROFILE=ci SCRIPT=tools/ci/ci_tools_unittest.sh - - name: "tools/wpt/ unittests" + - name: "tools/wpt/ tests" if: type = pull_request os: linux python: "2.7" diff --git a/tests/wpt/web-platform-tests/IndexedDB/get-databases.any.js b/tests/wpt/web-platform-tests/IndexedDB/get-databases.any.js new file mode 100644 index 00000000000..f054e0fec2f --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/get-databases.any.js @@ -0,0 +1,62 @@ +// META: script=support-promises.js + +promise_test(async testCase => { + // Delete any databases that may not have been cleaned up after + // previous test runs. + await deleteAllDatabases(testCase); + + const db_name = "TestDatabase"; + const db = await createNamedDatabase(testCase, db_name, ()=>{}); + const databases_promise = await indexedDB.databases(); + const expected_result = [ + {"name": db_name, "version": 1}, + ]; + assert_object_equals( + databases_promise, + expected_result, + "Call to databases() did not retrieve the single expected result."); +}, "Enumerate one database."); + +promise_test(async testCase => { + // Delete any databases that may not have been cleaned up after previous test + // runs. + await deleteAllDatabases(testCase); + + const db_name1 = "TestDatabase1"; + const db_name2 = "TestDatabase2"; + const db_name3 = "TestDatabase3"; + const db1 = await createNamedDatabase(testCase, db_name1, ()=>{}); + const db2 = await createNamedDatabase(testCase, db_name2, ()=>{}); + const db3 = await createNamedDatabase(testCase, db_name3, ()=>{}); + const databases_promise = await indexedDB.databases(); + const expected_result = [ + {"name": db_name1, "version": 1}, + {"name": db_name2, "version": 1}, + {"name": db_name3, "version": 1}, + ]; + assert_object_equals( + databases_promise, + expected_result, + "Call to databases() did not retrieve the multiple expected results"); +}, "Enumerate multiple databases."); + +promise_test(async testCase => { + // Add some databases and close their connections. + const db1 = await createNamedDatabase(testCase, "DB1", ()=>{}); + const db2 = await createNamedDatabase(testCase, "DB2", ()=>{}); + db1.onversionchange = () => { db1.close() }; + db2.onversionchange = () => { db2.close() }; + + // Delete any databases that may not have been cleaned up after previous test + // runs as well as the two databases made above. + await deleteAllDatabases(testCase); + + // Make sure the databases are no longer returned. + const databases_promise = await indexedDB.databases(); + assert_object_equals( + databases_promise, + [], + "Call to databases() found database it should not have.") +}, "Make sure an empty list is returned for the case of no databases."); + +done(); diff --git a/tests/wpt/web-platform-tests/IndexedDB/idbindex-rename-abort.html b/tests/wpt/web-platform-tests/IndexedDB/idbindex-rename-abort.html index b14d3012261..b61988e9b5c 100644 --- a/tests/wpt/web-platform-tests/IndexedDB/idbindex-rename-abort.html +++ b/tests/wpt/web-platform-tests/IndexedDB/idbindex-rename-abort.html @@ -39,9 +39,8 @@ promise_test(testCase => { 'versionchange transaction is aborted'); const request = indexedDB.open(dbName, 1); - return requestWatcher(testCase, request).wait_for('success'); - }).then(event => { - const database = event.target.result; + return promiseForRequest(testCase, request); + }).then(database => { const transaction = database.transaction('books', 'readonly'); const store = transaction.objectStore('books'); assert_array_equals( @@ -95,9 +94,8 @@ promise_test(testCase => { 'versionchange transaction is aborted'); const request = indexedDB.open(dbName, 1); - return requestWatcher(testCase, request).wait_for('success'); - }).then(event => { - const database = event.target.result; + return promiseForRequest(testCase, request); + }).then(database => { const transaction = database.transaction('not_books', 'readonly'); const store = transaction.objectStore('not_books'); assert_array_equals( diff --git a/tests/wpt/web-platform-tests/IndexedDB/idbobjectstore-rename-abort.html b/tests/wpt/web-platform-tests/IndexedDB/idbobjectstore-rename-abort.html index 6e16c31e339..75893cd84c0 100644 --- a/tests/wpt/web-platform-tests/IndexedDB/idbobjectstore-rename-abort.html +++ b/tests/wpt/web-platform-tests/IndexedDB/idbobjectstore-rename-abort.html @@ -40,9 +40,8 @@ promise_test(testCase => { 'IDBObjectStore.name should not reflect the rename any more ' + 'after the versionchange transaction is aborted'); const request = indexedDB.open(dbName, 1); - return requestWatcher(testCase, request).wait_for('success'); - }).then(event => { - const database = event.target.result; + return promiseForRequest(testCase, request); + }).then(database => { assert_array_equals( database.objectStoreNames, ['books'], 'IDBDatabase.objectStoreNames should not reflect the rename ' + @@ -107,9 +106,8 @@ promise_test(testCase => { 'should be empty after the versionchange transaction is aborted ' + 'returns'); const request = indexedDB.open(dbName, 1); - return requestWatcher(testCase, request).wait_for('success'); - }).then(event => { - const database = event.target.result; + return promiseForRequest(testCase, request); + }).then(database => { assert_array_equals( database.objectStoreNames, [], 'IDBDatabase.objectStoreNames should not reflect the creation or ' + diff --git a/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-common.js b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-common.js new file mode 100644 index 00000000000..45c8ffef923 --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-common.js @@ -0,0 +1,93 @@ +// Returns the "name" property written to the object with the given ID. +function nameForId(id) { + return `Object ${id}`; +} + +// Initial database setup used by all the reading-autoincrement tests. +async function setupAutoincrementDatabase(testCase) { + const database = await createDatabase(testCase, database => { + const store = database.createObjectStore( + 'store', { autoIncrement: true, keyPath: 'id' }); + store.createIndex('by_name', 'name', { unique: true }); + store.createIndex('by_id', 'id', { unique: true }); + + // Cover writing from the initial upgrade transaction. + for (let i = 1; i <= 16; ++i) { + if (i % 2 == 0) { + store.put({name: nameForId(i), id: i}); + } else { + store.put({name: nameForId(i)}); + } + } + }); + + // Cover writing from a subsequent transaction. + const transaction = database.transaction(['store'], 'readwrite'); + const store = transaction.objectStore('store'); + for (let i = 17; i <= 32; ++i) { + if (i % 2 == 0) { + store.put({name: nameForId(i), id: i}); + } else { + store.put({name: nameForId(i)}); + } + } + await promiseForTransaction(testCase, transaction); + + return database; +} + +// Returns the IDs used by the object store, sorted as strings. +// +// This is used to determine the correct order of records when retrieved from an +// index that uses stringified IDs. +function idsSortedByStringCompare() { + const stringIds = []; + for (let i = 1; i <= 32; ++i) + stringIds.push(i); + stringIds.sort((a, b) => indexedDB.cmp(`${a}`, `${b}`)); + return stringIds; +} + +async function iterateCursor(testCase, cursorRequest, callback) { + // This uses requestWatcher() directly instead of using promiseForRequest() + // inside the loop to avoid creating multiple EventWatcher instances. In turn, + // this avoids ending up with O(N) listeners for the request and O(N^2) + // dispatched events. + const eventWatcher = requestWatcher(testCase, cursorRequest); + while (true) { + const event = await eventWatcher.wait_for('success'); + const cursor = event.target.result; + if (cursor === null) + return; + callback(cursor); + cursor.continue(); + } +} + +// Returns equivalent information to getAllKeys() by iterating a cursor. +// +// Returns an array with one dictionary per entry in the source. The dictionary +// has the properties "key" and "primaryKey". +async function getAllKeysViaCursor(testCase, cursorSource) { + const results = []; + await iterateCursor(testCase, cursorSource.openKeyCursor(), cursor => { + results.push({ key: cursor.key, primaryKey: cursor.primaryKey }); + }); + return results; +} + +// Returns equivalent information to getAll() by iterating a cursor. +// +// Returns an array with one dictionary per entry in the source. The dictionary +// has the properties "key", "primaryKey" and "value". +async function getAllViaCursor(testCase, cursorSource) { + const results = []; + await iterateCursor(testCase, cursorSource.openCursor(), cursor => { + results.push({ + key: cursor.key, + primaryKey: cursor.primaryKey, + value: cursor.value, + }); + }); + return results; +}
\ No newline at end of file diff --git a/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.js b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.js new file mode 100644 index 00000000000..d7938768fa1 --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes-cursors.any.js @@ -0,0 +1,88 @@ +// META: global=window,dedicatedworker,sharedworker,serviceworker +// META: script=../support-promises.js +// META: script=./reading-autoincrement-common.js + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_id'); + + const result = await getAllViaCursor(testCase, index); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, i, 'Autoincrement index key'); + assert_equals(result[i - 1].primaryKey, i, 'Autoincrement primary key'); + assert_equals(result[i - 1].value.id, i, 'Autoincrement key in value'); + assert_equals(result[i - 1].value.name, nameForId(i), + 'String property in value'); + } + + database.close(); +}, 'IDBIndex.openCursor() iterates over an index on the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_id'); + + const result = await getAllKeysViaCursor(testCase, index); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, i, 'Autoincrement index key'); + assert_equals(result[i - 1].primaryKey, i, 'Autoincrement primary key'); + } + + database.close(); +}, 'IDBIndex.openKeyCursor() iterates over an index on the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_name'); + + const stringSortedIds = idsSortedByStringCompare(); + + const result = await getAllViaCursor(testCase, index); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, nameForId(stringSortedIds[i - 1]), + 'Index key'); + assert_equals(result[i - 1].primaryKey, stringSortedIds[i - 1], + 'Autoincrement primary key'); + assert_equals(result[i - 1].value.id, stringSortedIds[i - 1], + 'Autoincrement key in value'); + assert_equals(result[i - 1].value.name, nameForId(stringSortedIds[i - 1]), + 'String property in value'); + } + + database.close(); +}, 'IDBIndex.openCursor() iterates over an index not covering the ' + + 'autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_name'); + + const stringSortedIds = idsSortedByStringCompare(); + + const result = await getAllKeysViaCursor(testCase, index); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, nameForId(stringSortedIds[i - 1]), + 'Index key'); + assert_equals(result[i - 1].primaryKey, stringSortedIds[i - 1], + 'Autoincrement primary key'); + } + + database.close(); +}, 'IDBIndex.openKeyCursor() iterates over an index not covering the ' + + 'autoincrement key');
\ No newline at end of file diff --git a/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes.any.js b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes.any.js new file mode 100644 index 00000000000..d945b78bf37 --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-indexes.any.js @@ -0,0 +1,108 @@ +// META: global=window,dedicatedworker,sharedworker,serviceworker +// META: script=../support-promises.js +// META: script=./reading-autoincrement-common.js + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_id'); + const request = index.getAll(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].id, i, 'Autoincrement key'); + assert_equals(result[i - 1].name, nameForId(i), 'String property'); + } + + database.close(); +}, 'IDBIndex.getAll() for an index on the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_id'); + const request = index.getAllKeys(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) + assert_equals(result[i - 1], i, 'Autoincrement key'); + + database.close(); +}, 'IDBIndex.getAllKeys() for an index on the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_id'); + + for (let i = 1; i <= 32; ++i) { + const request = index.get(i); + const result = await promiseForRequest(testCase, request); + assert_equals(result.id, i, 'autoincrement key'); + assert_equals(result.name, nameForId(i), 'string property'); + } + + database.close(); +}, 'IDBIndex.get() for an index on the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const stringSortedIds = idsSortedByStringCompare(); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_name'); + const request = index.getAll(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].id, stringSortedIds[i - 1], + 'autoincrement key'); + assert_equals(result[i - 1].name, nameForId(stringSortedIds[i - 1]), + 'string property'); + } + + database.close(); +}, 'IDBIndex.getAll() for an index not covering the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const stringSortedIds = idsSortedByStringCompare(); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_name'); + const request = index.getAllKeys(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) + assert_equals(result[i - 1], stringSortedIds[i - 1], 'String property'); + + database.close(); +}, 'IDBIndex.getAllKeys() returns correct result for an index not covering ' + + 'the autoincrement key'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const index = store.index('by_name'); + + for (let i = 1; i <= 32; ++i) { + const request = index.get(nameForId(i)); + const result = await promiseForRequest(testCase, request); + assert_equals(result.id, i, 'Autoincrement key'); + assert_equals(result.name, nameForId(i), 'String property'); + } + + database.close(); +}, 'IDBIndex.get() for an index not covering the autoincrement key'); diff --git a/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.js b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.js new file mode 100644 index 00000000000..05971098fa8 --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store-cursors.any.js @@ -0,0 +1,38 @@ +// META: global=window,dedicatedworker,sharedworker,serviceworker +// META: script=../support-promises.js +// META: script=./reading-autoincrement-common.js + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + + const result = await getAllViaCursor(testCase, store); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, i, 'Autoincrement key'); + assert_equals(result[i - 1].primaryKey, i, 'Autoincrement primary key'); + assert_equals(result[i - 1].value.id, i, 'Autoincrement key in value'); + assert_equals(result[i - 1].value.name, nameForId(i), + 'string property in value'); + } + + database.close(); +}, 'IDBObjectStore.openCursor() iterates over an autoincrement store'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + + const result = await getAllKeysViaCursor(testCase, store); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].key, i, 'Incorrect autoincrement key'); + assert_equals(result[i - 1].primaryKey, i, 'Incorrect primary key'); + } + + database.close(); +}, 'IDBObjectStore.openKeyCursor() iterates over an autoincrement store');
\ No newline at end of file diff --git a/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store.any.js b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store.any.js new file mode 100644 index 00000000000..bbba6a33513 --- /dev/null +++ b/tests/wpt/web-platform-tests/IndexedDB/key-generators/reading-autoincrement-store.any.js @@ -0,0 +1,49 @@ +// META: global=window,dedicatedworker,sharedworker,serviceworker +// META: script=../support-promises.js +// META: script=./reading-autoincrement-common.js + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const request = store.getAll(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) { + assert_equals(result[i - 1].id, i, 'Autoincrement key'); + assert_equals(result[i - 1].name, nameForId(i), 'String property'); + } + + database.close(); +}, 'IDBObjectStore.getAll() for an autoincrement store'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + const request = store.getAllKeys(); + const result = await promiseForRequest(testCase, request); + assert_equals(result.length, 32); + for (let i = 1; i <= 32; ++i) + assert_equals(result[i - 1], i, 'Autoincrement key'); + + database.close(); +}, 'IDBObjectStore.getAllKeys() for an autoincrement store'); + +promise_test(async testCase => { + const database = await setupAutoincrementDatabase(testCase); + + const transaction = database.transaction(['store'], 'readonly'); + const store = transaction.objectStore('store'); + + for (let i = 1; i <= 32; ++i) { + const request = store.get(i); + const result = await promiseForRequest(testCase, request); + assert_equals(result.id, i, 'Autoincrement key'); + assert_equals(result.name, nameForId(i), 'String property'); + } + + database.close(); +}, 'IDBObjectStore.get() for an autoincrement store');
\ No newline at end of file diff --git a/tests/wpt/web-platform-tests/IndexedDB/support-promises.js b/tests/wpt/web-platform-tests/IndexedDB/support-promises.js index 21e2163ec60..433af509270 100644 --- a/tests/wpt/web-platform-tests/IndexedDB/support-promises.js +++ b/tests/wpt/web-platform-tests/IndexedDB/support-promises.js @@ -5,11 +5,39 @@ function databaseName(testCase) { return 'db' + self.location.pathname + '-' + testCase.name; } -// Creates an EventWatcher covering all the events that can be issued by -// IndexedDB requests and transactions. +// EventWatcher covering all the events defined on IndexedDB requests. +// +// The events cover IDBRequest and IDBOpenDBRequest. function requestWatcher(testCase, request) { return new EventWatcher(testCase, request, - ['abort', 'blocked', 'complete', 'error', 'success', 'upgradeneeded']); + ['blocked', 'error', 'success', 'upgradeneeded']); +} + +// EventWatcher covering all the events defined on IndexedDB transactions. +// +// The events cover IDBTransaction. +function transactionWatcher(testCase, request) { + return new EventWatcher(testCase, request, ['abort', 'complete', 'error']); +} + +// Promise that resolves with an IDBRequest's result. +// +// The promise only resolves if IDBRequest receives the "success" event. Any +// other event causes the promise to reject with an error. This is correct in +// most cases, but insufficient for indexedDB.open(), which issues +// "upgradeneded" events under normal operation. +function promiseForRequest(testCase, request) { + const eventWatcher = requestWatcher(testCase, request); + return eventWatcher.wait_for('success').then(event => event.target.result); +} + +// Promise that resolves when an IDBTransaction completes. +// +// The promise resolves with undefined if IDBTransaction receives the "complete" +// event, and rejects with an error for any other event. +function promiseForTransaction(testCase, request) { + const eventWatcher = transactionWatcher(testCase, request); + return eventWatcher.wait_for('complete').then(() => {}); } // Migrates an IndexedDB database whose name is unique for the test case. @@ -64,7 +92,7 @@ function migrateNamedDatabase( requestEventPromise = new Promise((resolve, reject) => { request.onerror = event => { event.preventDefault(); - resolve(event); + resolve(event.target.error); }; request.onsuccess = () => reject(new Error( 'indexedDB.open should not succeed for an aborted ' + @@ -79,8 +107,7 @@ function migrateNamedDatabase( if (!shouldBeAborted) { request.onerror = null; request.onsuccess = null; - requestEventPromise = - requestWatcher(testCase, request).wait_for('success'); + requestEventPromise = promiseForRequest(testCase, request); } // requestEventPromise needs to be the last promise in the chain, because @@ -95,12 +122,10 @@ function migrateNamedDatabase( 'indexedDB.open should not succeed without creating a ' + 'versionchange transaction')); }; - }).then(event => { - const database = event.target.result; - if (database) { - testCase.add_cleanup(() => { database.close(); }); - } - return database || event.target.error; + }).then(databaseOrError => { + if (databaseOrError instanceof IDBDatabase) + testCase.add_cleanup(() => { databaseOrError.close(); }); + return databaseOrError; }); } @@ -126,9 +151,7 @@ function createDatabase(testCase, setupCallback) { // close the database. function createNamedDatabase(testCase, databaseName, setupCallback) { const request = indexedDB.deleteDatabase(databaseName); - const eventWatcher = requestWatcher(testCase, request); - - return eventWatcher.wait_for('success').then(event => { + return promiseForRequest(testCase, request).then(() => { testCase.add_cleanup(() => { indexedDB.deleteDatabase(databaseName); }); return migrateNamedDatabase(testCase, databaseName, 1, setupCallback) }); @@ -152,9 +175,7 @@ function openDatabase(testCase, version) { // close the database. function openNamedDatabase(testCase, databaseName, version) { const request = indexedDB.open(databaseName, version); - const eventWatcher = requestWatcher(testCase, request); - return eventWatcher.wait_for('success').then(() => { - const database = request.result; + return promiseForRequest(testCase, request).then(database => { testCase.add_cleanup(() => { database.close(); }); return database; }); @@ -215,9 +236,7 @@ function checkStoreIndexes (testCase, store, errorMessage) { function checkStoreGenerator(testCase, store, expectedKey, errorMessage) { const request = store.put( { title: 'Bedrock Nights ' + expectedKey, author: 'Barney' }); - const eventWatcher = requestWatcher(testCase, request); - return eventWatcher.wait_for('success').then(() => { - const result = request.result; + return promiseForRequest(testCase, request).then(result => { assert_equals(result, expectedKey, errorMessage); }); } @@ -230,9 +249,7 @@ function checkStoreGenerator(testCase, store, expectedKey, errorMessage) { // is using it incorrectly. function checkStoreContents(testCase, store, errorMessage) { const request = store.get(123456); - const eventWatcher = requestWatcher(testCase, request); - return eventWatcher.wait_for('success').then(() => { - const result = request.result; + return promiseForRequest(testCase, request).then(result => { assert_equals(result.isbn, BOOKS_RECORD_DATA[0].isbn, errorMessage); assert_equals(result.author, BOOKS_RECORD_DATA[0].author, errorMessage); assert_equals(result.title, BOOKS_RECORD_DATA[0].title, errorMessage); @@ -247,9 +264,7 @@ function checkStoreContents(testCase, store, errorMessage) { // is using it incorrectly. function checkAuthorIndexContents(testCase, index, errorMessage) { const request = index.get(BOOKS_RECORD_DATA[2].author); - const eventWatcher = requestWatcher(testCase, request); - return eventWatcher.wait_for('success').then(() => { - const result = request.result; + return promiseForRequest(testCase, request).then(result => { assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage); assert_equals(result.title, BOOKS_RECORD_DATA[2].title, errorMessage); }); @@ -263,9 +278,7 @@ function checkAuthorIndexContents(testCase, index, errorMessage) { // is using it incorrectly. function checkTitleIndexContents(testCase, index, errorMessage) { const request = index.get(BOOKS_RECORD_DATA[2].title); - const eventWatcher = requestWatcher(testCase, request); - return eventWatcher.wait_for('success').then(() => { - const result = request.result; + return promiseForRequest(testCase, request).then(result => { assert_equals(result.isbn, BOOKS_RECORD_DATA[2].isbn, errorMessage); assert_equals(result.author, BOOKS_RECORD_DATA[2].author, errorMessage); }); @@ -290,3 +303,12 @@ function largeValue(size, seed) { return buffer; } + +async function deleteAllDatabases(testCase) { + const dbs_to_delete = await indexedDB.databases(); + for( const db_info of dbs_to_delete) { + let request = indexedDB.deleteDatabase(db_info.name); + let eventWatcher = requestWatcher(testCase, request); + await eventWatcher.wait_for('success'); + } +} diff --git a/tests/wpt/web-platform-tests/WebCryptoAPI/META.yml b/tests/wpt/web-platform-tests/WebCryptoAPI/META.yml index ec95611b3fe..8f27e484996 100644 --- a/tests/wpt/web-platform-tests/WebCryptoAPI/META.yml +++ b/tests/wpt/web-platform-tests/WebCryptoAPI/META.yml @@ -1,4 +1,3 @@ spec: https://w3c.github.io/webcrypto/ suggested_reviewers: - - Wafflespeanut - jimsch diff --git a/tests/wpt/web-platform-tests/annotation-vocab/META.yml b/tests/wpt/web-platform-tests/annotation-vocab/META.yml index 030df88318c..f99f921d352 100644 --- a/tests/wpt/web-platform-tests/annotation-vocab/META.yml +++ b/tests/wpt/web-platform-tests/annotation-vocab/META.yml @@ -1,4 +1,3 @@ spec: https://www.w3.org/TR/annotation-vocab/ suggested_reviewers: - halindrome - - gkellogg diff --git a/tests/wpt/web-platform-tests/css/css-grid/META.yml b/tests/wpt/web-platform-tests/css/css-grid/META.yml index f8482e16f98..18c574ac68b 100644 --- a/tests/wpt/web-platform-tests/css/css-grid/META.yml +++ b/tests/wpt/web-platform-tests/css/css-grid/META.yml @@ -1,7 +1,6 @@ spec: https://drafts.csswg.org/css-grid/ suggested_reviewers: - mrego - - tomalec - plinss - jxs - tabatkins diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-computation.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-computation.html index 180cdf601ed..2525e43ef51 100644 --- a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-computation.html +++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-computation.html @@ -18,134 +18,147 @@ <script> -for (let element of [divWithFontSizeSet, divWithFontSizeInherited]) { - let id = element.id; - - // Generate a property and temporarily set its value. Then call 'fn' with - // the name of the generated property. - function with_custom_property(reg, value, fn) { - let name = generate_property(reg); - - // Because we want to include the parsing step, insert a stylesheet - // node with textContent. - let node = document.createElement('style'); - node.textContent = `#${id} { ${name}:${value}; }`; - document.body.append(node); - - try { - fn(name); - } finally { - node.remove(); - } +// Generate a property and temporarily set its value. Then call 'fn' with +// the name of the generated property. +function with_custom_property(element, reg, value, fn) { + if (element.id.length == 0) + throw 'The specified element must have an ID'; + + let name = generate_property(reg); + + // Because we want to include the parsing step, insert a stylesheet + // node with textContent. + let node = document.createElement('style'); + node.textContent = `#${element.id} { ${name}:${value}; }`; + document.body.append(node); + + try { + fn(name); + } finally { + node.remove(); } +} - function assert_computed_value(syntax, value, expected) { - with_custom_property(syntax, value, (name) => { - let actual = getComputedStyle(element).getPropertyValue(name); - assert_equals(actual, expected); - }); - } +function assert_computed_value(element, syntax, value, expected) { + with_custom_property(element, syntax, value, (name) => { + let actual = getComputedStyle(element).getPropertyValue(name); + assert_equals(actual, expected); + }); +} - // Computes an absolute reference value for some length. - // - // E.g. to figure out how many pixels '10vh' is, do length_ref('10vh'). - function length_ref(value, refnode = ref) { - try { - // The reference property 'min-height' is chosen arbitrarily, but - // avoid properties with "resolved value is used value"-behavior - // [1], as it may affect rounding, and custom properties do not - // have this behavior. - // - // [1] https://drafts.csswg.org/cssom/#resolved-values - const ref_property = 'min-height'; - refnode.style = `${ref_property}: ${value}`; - return getComputedStyle(refnode).getPropertyValue(ref_property); - } finally { - refnode.style = ''; - } +// Computes an absolute reference value for some length. +// +// E.g. to figure out how many pixels '10vh' is, do length_ref('10vh'). +function length_ref(value, refnode = ref) { + try { + // The reference property 'min-height' is chosen arbitrarily, but + // avoid properties with "resolved value is used value"-behavior + // [1], as it may affect rounding, and custom properties do not + // have this behavior. + // + // [1] https://drafts.csswg.org/cssom/#resolved-values + const ref_property = 'min-height'; + refnode.style = `${ref_property}: ${value}`; + return getComputedStyle(refnode).getPropertyValue(ref_property); + } finally { + refnode.style = ''; } +} +function test_computed_value(syntax, value, expected) { test(function() { - assert_computed_value('<length>', '12px', '12px'); - assert_computed_value('<length>', '13vw', length_ref('13vw')); - assert_computed_value('<length>', '14em', '140px'); - assert_computed_value('<length>', '15vmin', length_ref('15vmin')); - assert_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); - with_custom_property('<length>', '14em', (name) => { - assert_computed_value('<length>', `var(${name})`, '140px'); - }); - }, "<length> values are computed correctly for " + id); - - test(function() { - assert_computed_value('<length-percentage>', '17em', '170px'); - assert_computed_value('<length-percentage>', '18%', '18%'); - assert_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(190px + -2%)'); - }, "<length-percentage> values are computed correctly for " + id); - - test(function() { - assert_computed_value('<length>#', '10px, 3em', '10px, 30px'); - assert_computed_value('<length>#', '10px, 3em', '10px, 30px'); - assert_computed_value('<length>#', '4em ,9px', '40px, 9px'); - assert_computed_value('<length>#', '8em', '80px'); - }, "<length># values are computed correctly for " + id); - - test(function() { - assert_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); - assert_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(10px + 50%), 4px'); - assert_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(37px + 13%)'); - }, "<length-percentage># values are computed correctly for " + id); - - test(function() { - assert_computed_value('<length>+', '10px 3em', '10px 30px'); - assert_computed_value('<length>+', '4em 9px', '40px 9px'); - }, "<length>+ values are computed correctly for " + id); - - test(function() { - assert_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); - assert_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(10px + 50%) 4px'); - }, "<length-percentage>+ values are computed correctly for " + id); - - test(function() { - assert_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); - assert_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); - assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))'); - assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); - }, "<transform-function> values are computed correctly for " + id); - - test(function() { - assert_computed_value('<integer>', '15', '15'); - assert_computed_value('<integer>', 'calc(15 + 15)', '30'); - assert_computed_value('<integer>', 'calc(2.4)', '2'); - assert_computed_value('<integer>', 'calc(2.6)', '3'); - assert_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); - }, "<integer> values are computed correctly for " + id); - - test(function() { - assert_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); - }, "<integer>+ values are computed correctly for " + id); - - test(function() { - assert_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); - assert_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); - assert_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); - assert_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); - assert_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); - assert_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); - assert_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); - assert_computed_value('<color>', 'currentcolor', 'currentcolor'); - }, "<color> values are computed correctly for " + id); + assert_computed_value(divWithFontSizeSet, syntax, value, expected); + }, `${syntax} values are computed correctly [${value}]`); +} - test(function() { - assert_computed_value('*', 'tomato', 'tomato'); - assert_computed_value('tomato | plum', 'plum', 'plum'); - assert_computed_value('tomato | plum | <color>', 'plum', 'plum'); - }, "ident values that look like color keywords are not converted to colors" + id); +test(function(){ + const element = divWithFontSizeSet; + with_custom_property(element, '<length>', '14em', (name) => { + assert_computed_value(element, '<length>', `var(${name})`, '140px'); + }); +}, '<length> values computed are correctly via var()-reference'); + +test(function(){ + const element = divWithFontSizeInherited; + with_custom_property(element, '<length>', '14em', (name) => { + assert_computed_value(element, '<length>', `var(${name})`, '140px'); + }); +}, '<length> values computed are correctly via var()-reference when font-size is inherited'); + +test(function(){ + const element = divWithFontSizeInherited; + assert_computed_value(element, '<length>', '14em', '140px'); +}, '<length> values are computed correctly when font-size is inherited [14em]'); + +test(function(){ + const element = divWithFontSizeInherited; + assert_computed_value(element, '<length>', 'calc(14em + 10px)', '150px'); +}, '<length> values are computed correctly when font-size is inherited [calc(14em + 10px)]'); + +test_computed_value('<length>', '12px', '12px'); +test_computed_value('<length>', '13vw', length_ref('13vw')); +test_computed_value('<length>', '14em', '140px'); +test_computed_value('<length>', '15vmin', length_ref('15vmin')); +test_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)')); + +test_computed_value('<length-percentage>', '17em', '170px'); +test_computed_value('<length-percentage>', '18%', '18%'); +test_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(190px + -2%)'); + +test_computed_value('<length>#', '10px, 3em', '10px, 30px'); +test_computed_value('<length>#', '4em ,9px', '40px, 9px'); +test_computed_value('<length>#', '8em', '80px'); + +test_computed_value('<length-percentage>#', '3% , 10vmax , 22px', ['3%', length_ref('10vmax'), '22px'].join(', ')); +test_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(10px + 50%), 4px'); +test_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(37px + 13%)'); + +test_computed_value('<length>+', '10px 3em', '10px 30px'); +test_computed_value('<length>+', '4em 9px', '40px 9px'); + +test_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' ')); +test_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(10px + 50%) 4px'); + +test_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)'); +test_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)'); +test_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))'); +test_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)'); + +test_computed_value('<integer>', '15', '15'); +test_computed_value('<integer>', 'calc(15 + 15)', '30'); +test_computed_value('<integer>', 'calc(2.4)', '2'); +test_computed_value('<integer>', 'calc(2.6)', '3'); +test_computed_value('<integer>', 'calc(2.6 + 3.1)', '6'); + +test_computed_value('<integer>+', '15 calc(2.4) calc(2.6)', '15 2 3'); + +test_computed_value('<color>', '#ff0000', 'rgb(255, 0, 0)'); +test_computed_value('<color>', '#000f00', 'rgb(0, 15, 0)'); +test_computed_value('<color>', '#00000a', 'rgb(0, 0, 10)'); +test_computed_value('<color>', '#badbee', 'rgb(186, 219, 238)'); +test_computed_value('<color>', '#badbee33', 'rgba(186, 219, 238, 0.2)'); +test_computed_value('<color>', 'tomato', 'rgb(255, 99, 71)'); +test_computed_value('<color>', 'plum', 'rgb(221, 160, 221)'); +test_computed_value('<color>', 'currentcolor', 'currentcolor'); + +// Custom ident values that look like color keywords should not be converted. +test_computed_value('*', 'tomato', 'tomato'); +test_computed_value('tomato | plum', 'plum', 'plum'); +test_computed_value('tomato | plum | <color>', 'plum', 'plum'); + +test_computed_value('*', '-50grad', '-50grad'); +test_computed_value('<angle>', '180deg', '180deg'); +test_computed_value('<angle>', '400grad', '360deg'); +test_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); + +test_computed_value('*', '50s', '50s'); +test_computed_value('<time>', '1s', '1s'); +test_computed_value('<time>', '1000ms', '1s'); +test_computed_value('<time>', 'calc(1000ms + 1s)', '2s'); + +test_computed_value('*', '50dpi', '50dpi'); +test_computed_value('<resolution>', '1dppx', '1dppx'); +test_computed_value('<resolution>', '96dpi', '1dppx'); +test_computed_value('<resolution>', 'calc(1dppx + 96dpi)', '2dppx'); - test(function() { - assert_computed_value('*', '-50grad', '-50grad'); - assert_computed_value('<angle>', '180deg', '180deg'); - assert_computed_value('<angle>', '400grad', '360deg'); - assert_computed_value('<angle>', 'calc(360deg + 400grad)', '720deg'); - }, "<angle> values computed correctly for " + id); -} </script> diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-initial.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-initial.html index 24543d5c5fd..77aa9cd11a3 100644 --- a/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-initial.html +++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/registered-property-initial.html @@ -1,35 +1,45 @@ -<!DOCTYPE HTML> +<!DOCTYPE html> <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#dom-propertydescriptor-initialvalue" /> <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#register-a-custom-property" /> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> -<style> -#target { - background: var(--inherited-color); - color: var(--non-inherited-color); -} -</style> +<script src="./resources/utils.js"></script> <div id=target></div> <script> -test(function() { - CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)', inherits: false}); - CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)', inherits: false}); - CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true}); - CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple', inherits: false}); - CSS.registerProperty({name: '--transform-function', syntax: '<transform-function>', initialValue: 'rotate(42deg)', inherits: false}); - CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))', inherits: false}); - CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))', inherits: false}); - computedStyle = getComputedStyle(target); - assert_equals(computedStyle.getPropertyValue('--length'), '25px'); - assert_equals(computedStyle.getPropertyValue('--length-percentage'), 'calc(100px + 10%)'); - assert_equals(computedStyle.getPropertyValue('--inherited-color'), 'rgb(255, 192, 203)'); - assert_equals(computedStyle.getPropertyValue('--non-inherited-color'), 'rgb(128, 0, 128)'); - assert_equals(computedStyle.getPropertyValue('--transform-function'), 'rotate(42deg)'); - assert_equals(computedStyle.getPropertyValue('--single-transform-list'), 'scale(4)'); - assert_equals(computedStyle.getPropertyValue('--multiple-transform-list'), 'scale(3) translateX(4px)'); +function test_initial_value(reg, expected) { + let suffix = reg.inherits === true ? ', inherits' : ''; + test(function(){ + let name = generate_property(reg); + let actual = getComputedStyle(target).getPropertyValue(name); + assert_equals(actual, expected); + }, `Initial value for ${reg.syntax} correctly computed [${reg.initialValue}${suffix}]`); +} + +test_initial_value({ syntax: '<length>', initialValue: 'calc(10px + 15px)' }, '25px'); +test_initial_value({ syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)' }, 'calc(100px + 10%)'); +test_initial_value({ syntax: '<color>', initialValue: 'pink', inherits: true }, 'rgb(255, 192, 203)'); +test_initial_value({ syntax: '<color>', initialValue: 'purple' }, 'rgb(128, 0, 128)'); +test_initial_value({ syntax: '<transform-function>', initialValue: 'rotate(42deg)' }, 'rotate(42deg)'); +test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))' }, 'scale(4)'); +test_initial_value({ syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))' }, 'scale(3) translateX(4px)'); + +// Test that the initial value of the custom property 'reg' is successfully +// substituted into 'property'. +function test_substituted_value(reg, property, expected) { + let inherits_text = reg.inherits === true ? 'inherited' : 'non-inherited'; + test(function(){ + try { + let name = generate_property(reg); + target.style = `${property}:var(${name});`; + assert_equals(getComputedStyle(target).getPropertyValue(property), expected); + } finally { + target.style = ''; + } + }, `Initial ${inherits_text} value can be substituted [${reg.initialValue}, ${property}]`); +} + +test_substituted_value({ syntax: '<color>', initialValue: 'purple', inherits: true }, 'color', 'rgb(128, 0, 128)'); +test_substituted_value({ syntax: '<color>', initialValue: 'pink' }, 'background-color', 'rgb(255, 192, 203)'); - assert_equals(computedStyle.backgroundColor, 'rgb(255, 192, 203)'); - assert_equals(computedStyle.color, 'rgb(128, 0, 128)'); -}, "Initial values of registered properties can be referenced when no custom properties are explicitly set."); </script> diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/resources/utils.js b/tests/wpt/web-platform-tests/css/css-properties-values-api/resources/utils.js index c4dc3fd5a8d..bef59560f68 100644 --- a/tests/wpt/web-platform-tests/css/css-properties-values-api/resources/utils.js +++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/resources/utils.js @@ -50,6 +50,14 @@ function any_initial_value(syntax) { // generated. If a single string is used as the argument, it is assumed to be // the syntax. function generate_property(reg) { + // Verify that only valid keys are specified. This prevents the caller from + // accidentally supplying 'inherited' instead of 'inherits', for example. + if (typeof(reg) === 'object') { + const permitted = new Set(['name', 'syntax', 'initialValue', 'inherits']); + if (!Object.keys(reg).every(k => permitted.has(k))) + throw new Error('generate_property: invalid parameter'); + } + let syntax = typeof(reg) === 'string' ? reg : reg.syntax; let initial = typeof(reg.initialValue) === 'undefined' ? any_initial_value(syntax) : reg.initialValue; diff --git a/tests/wpt/web-platform-tests/css/css-properties-values-api/self-utils.html b/tests/wpt/web-platform-tests/css/css-properties-values-api/self-utils.html index 530c5f677ad..05aa4b2fb03 100644 --- a/tests/wpt/web-platform-tests/css/css-properties-values-api/self-utils.html +++ b/tests/wpt/web-platform-tests/css/css-properties-values-api/self-utils.html @@ -32,4 +32,10 @@ test(function(){ } }, 'Generated properties respect inherits flag'); +test(function(){ + assert_throws(new Error(), () => generate_property({syntax: '<length>', foo: 1})); + assert_throws(new Error(), () => generate_property({syntax: '<length>', inherited: false})); + assert_throws(new Error(), () => generate_property({syntax: '<length>', initial: '10px'})); +}, 'Can\'t generate property with unknown fields'); + </script> diff --git a/tests/wpt/web-platform-tests/css/css-transforms/text-perspective-001.html b/tests/wpt/web-platform-tests/css/css-transforms/text-perspective-001.html new file mode 100644 index 00000000000..e98b3e73b36 --- /dev/null +++ b/tests/wpt/web-platform-tests/css/css-transforms/text-perspective-001.html @@ -0,0 +1,27 @@ +<!doctype> +<meta charset="utf-8"> +<title>CSS Test: Text is not incorrectly clipped in presence of perspective.</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1494685"> +<link rel="mismatch" href="about:blank"> +<style> +* { + margin: 0; + padding: 0; +} +.container { + perspective: 1px; +} +.heading { + transform: translateZ(-9px) scale(10); +} +h1 { + font-size: 100px; +} +</style> +<div class="container"> + <div class="heading"> + <h1>X</h1> + </div> +</div> diff --git a/tests/wpt/web-platform-tests/css/geometry/META.yml b/tests/wpt/web-platform-tests/css/geometry/META.yml index 9e3a7979ed8..98a2ae9860b 100644 --- a/tests/wpt/web-platform-tests/css/geometry/META.yml +++ b/tests/wpt/web-platform-tests/css/geometry/META.yml @@ -1,5 +1,4 @@ spec: https://drafts.fxtf.org/geometry/ suggested_reviewers: - peterjoel - - tschneidereit - dirkschulze diff --git a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1-ref.html b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1-ref.html index a9d8056ccab..b64aa46bf2e 100644 --- a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1-ref.html +++ b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1-ref.html @@ -9,7 +9,7 @@ p { height: 50px; width: 200px; border: thin solid; - background-image: url(../backgrounds/blue-32x32.png); + background-image: url(support/blue-32x32.png); background-repeat: no-repeat; } diff --git a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1.html b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1.html index 2a8bfdf65b0..68351aef6e5 100644 --- a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1.html +++ b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-position-1.html @@ -11,7 +11,7 @@ p { height: 50px; width: 200px; border: thin solid; - background-image: url(../backgrounds/blue-32x32.png); + background-image: url(support/blue-32x32.png); background-repeat: no-repeat; } diff --git a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1-ref.html b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1-ref.html index 16b89c1d805..5385c46ef52 100644 --- a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1-ref.html +++ b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1-ref.html @@ -9,7 +9,7 @@ p { height: 50px; width: 200px; border: thin solid; - background-image: url(../backgrounds/blue-32x32.png); + background-image: url(support/blue-32x32.png); background-repeat: no-repeat; } diff --git a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1.html b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1.html index e91f8c26ce1..f52ceeeabe1 100644 --- a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1.html +++ b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/calc-background-size-1.html @@ -11,7 +11,7 @@ p { height: 50px; width: 200px; border: thin solid; - background-image: url(../backgrounds/blue-32x32.png); + background-image: url(support/blue-32x32.png); background-repeat: no-repeat; } diff --git a/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/support/blue-32x32.png b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/support/blue-32x32.png Binary files differnew file mode 100644 index 00000000000..deefd19b2ac --- /dev/null +++ b/tests/wpt/web-platform-tests/css/vendor-imports/mozilla/mozilla-central-reftests/values3/support/blue-32x32.png diff --git a/tests/wpt/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-tests.js b/tests/wpt/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-tests.js index 5139ec97b05..4dd2b6be206 100644 --- a/tests/wpt/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-tests.js +++ b/tests/wpt/web-platform-tests/html/dom/elements/the-innertext-idl-attribute/getter-tests.js @@ -273,6 +273,11 @@ testText("<div>abc<div class='itable'><span class='cell'>def</span></div>ghi", " testText("<div>abc<div class='itable'><span class='row'><span class='cell'>def</span></span>\n<span class='row'><span class='cell'>123</span></span></div>ghi", "abcdef\n123ghi", "Single newline in two-row inline-table"); +/**** display:table-row/table-cell/table-caption ****/ +testText("<div style='display:table-row'>", "", "display:table-row on the element itself"); +testText("<div style='display:table-cell'>", "", "display:table-cell on the element itself"); +testText("<div style='display:table-caption'>", "", "display:table-caption on the element itself"); + /**** Lists ****/ testText("<div><ol><li>abc", "abc", "<ol> list items get no special treatment"); @@ -293,6 +298,9 @@ testText("<div>abc<hr><hr>def", "abc\ndef", "<hr><hr> induces just one line brea testText("<div>abc<hr><hr><hr>def", "abc\ndef", "<hr><hr><hr> induces just one line break"); testText("<div><hr class='poke'>", "abc", "<hr> content rendered"); testText("<div>abc<!--comment-->def", "abcdef", "comment ignored"); +testText("<br>", "", "<br>"); +testText("<p>", "", "empty <p>"); +testText("<div>", "", "empty <div>"); /**** text-transform ****/ @@ -308,11 +316,13 @@ testText("<div>abc<span>123<div>456</div>789</span>def", "abc123\n456\n789def", testText("<div>abc<div style='float:left'>123</div>def", "abc\n123\ndef", "floats induce a block boundary"); testText("<div>abc<span style='float:left'>123</span>def", "abc\n123\ndef", "floats induce a block boundary"); +testText("<div style='float:left'>123", "123", "float on the element itself"); /**** position ****/ testText("<div>abc<div style='position:absolute'>123</div>def", "abc\n123\ndef", "position:absolute induces a block boundary"); testText("<div>abc<span style='position:absolute'>123</span>def", "abc\n123\ndef", "position:absolute induces a block boundary"); +testText("<div style='position:absolute'>123", "123", "position:absolute on the element itself"); testText("<div>abc<div style='position:relative'>123</div>def", "abc\n123\ndef", "position:relative has no effect"); testText("<div>abc<span style='position:relative'>123</span>def", "abc123def", "position:relative has no effect"); diff --git a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html new file mode 100644 index 00000000000..3e437494c0a --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Combobox block-size test</title> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <style> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} + +select { -webkit-appearance: none; } + +.big { font-size: 48pt; min-height: 40pt; } +.lh { line-height: 48pt; min-height: 40pt; } + +.mask { position:fixed; left:20px; right:0; top:0; bottom:0; background: black; } + </style> +</head> +<body> + +<!-- mask off differences on the right side --> +<div class="mask"></div> + +<select><optgroup label="label"><option>option</option></select><br> +<select class="big"><optgroup label="label"><option>option</option></select><br> +<select class="lh"><optgroup label="label"><option>option</option></select><br> + +</body> +</html> diff --git a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html new file mode 100644 index 00000000000..4aecc596ce6 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html @@ -0,0 +1,38 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Test: Combobox block-size test</title> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="match" href="select-1-block-size-ref.html"> + <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499578"> + <style> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} + +select { -webkit-appearance: none; } + +optgroup { font-size: 32pt; } +option { font-size: 24pt; } +.big { font-size: 48pt; } +.lh { line-height: 48pt; } + +.mask { position:fixed; left:20px; right:0; top:0; bottom:0; background: black; } + </style> +</head> +<body> + +<!-- mask off differences on the right side --> +<div class="mask"></div> + +<select><optgroup label="label"><option>option</option></select><br> +<select class="big"><optgroup label="label"><option>option</option></select><br> +<select class="lh"><optgroup label="label"><option>option</option></select><br> + +</body> +</html> diff --git a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html new file mode 100644 index 00000000000..31ba23a5cf8 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html @@ -0,0 +1,35 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: empty SELECT</title> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <style> + +.none { display: none; } + + </style> +</head> +<body> + +<table border="1" cellpadding="10"> +<tr> +<td><select size="4"><option class="none"></select> +<td><select size="4" style="-webkit-appearance: none"><option class="none">option</select> +<td><select size="4" style="-webkit-appearance: none; border: 1px solid black"><option class="none">option</select> +<td><select size="4" style="border: 1px solid black"><option class="none">option</select> +</table> + +<table border="1" cellpadding="10"> +<tr> +<td><select size="1"><option class="none"></select> +<td><select size="1" style="-webkit-appearance: none"><option class="none"></select> +<td><select size="1" style="-webkit-appearance: none; border: 1px solid black"><option class="none"></select> +<td><select size="1" style="border: 1px solid black"><option class="none"></select> +</table> + +</body> +</html> diff --git a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty.html b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty.html new file mode 100644 index 00000000000..6568a6de349 --- /dev/null +++ b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/the-select-element/select-empty.html @@ -0,0 +1,33 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Test: empty SELECT</title> + <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com"> + <link rel="match" href="select-empty-ref.html"> + <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2"> + <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499230"> +</head> +<body> + +<table border="1" cellpadding="10"> +<tr> +<td><select size="4"></select> +<td><select size="4" style="-webkit-appearance: none"></select> +<td><select size="4" style="-webkit-appearance: none; border: 1px solid black"></select> +<td><select size="4" style="border: 1px solid black"></select> +</table> + +<table border="1" cellpadding="10"> +<tr> +<td><select size="1"></select> +<td><select size="1" style="-webkit-appearance: none"></select> +<td><select size="1" style="-webkit-appearance: none; border: 1px solid black"></select> +<td><select size="1" style="border: 1px solid black"></select> +</table> + +</body> +</html> diff --git a/tests/wpt/web-platform-tests/pointerevents/META.yml b/tests/wpt/web-platform-tests/pointerevents/META.yml index ef94157ef9a..be61ddddaf6 100644 --- a/tests/wpt/web-platform-tests/pointerevents/META.yml +++ b/tests/wpt/web-platform-tests/pointerevents/META.yml @@ -4,6 +4,5 @@ suggested_reviewers: - jacobrossi - plehegar - scottgonzalez - - staktrace - RByers - NavidZ diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client-message-queue.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client-message-queue.https.html new file mode 100644 index 00000000000..caa4f9445d3 --- /dev/null +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client-message-queue.https.html @@ -0,0 +1,211 @@ +<!DOCTYPE html> +<title>Service Worker: postMessage to Client (message queue)</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="resources/test-helpers.sub.js"></script> +<script> +// This function creates a message listener that captures all messages +// sent to this window and matches them with corresponding requests. +// This frees test code from having to use clunky constructs just to +// avoid race conditions, since the relative order of message and +// request arrival doesn't matter. +function create_message_listener(t) { + const listener = { + messages: new Set(), + requests: new Set(), + waitFor: function(predicate) { + for (const event of this.messages) { + // If a message satisfying the predicate has already + // arrived, it gets matched to this request. + if (predicate(event)) { + this.messages.delete(event); + return Promise.resolve(event); + } + } + + // If no match was found, the request is stored and a + // promise is returned. + const request = { predicate }; + const promise = new Promise(resolve => request.resolve = resolve); + this.requests.add(request); + return promise; + } + }; + window.onmessage = t.step_func(event => { + for (const request of listener.requests) { + // If the new message matches a stored request's + // predicate, the request's promise is resolved with this + // message. + if (request.predicate(event)) { + listener.requests.delete(request); + request.resolve(event); + return; + } + }; + + // No outstanding request for this message, store it in case + // it's requested later. + listener.messages.add(event); + }); + return listener; +} + +async function service_worker_register_and_activate(t, script, scope) { + const registration = await service_worker_unregister_and_register(t, script, scope); + t.add_cleanup(() => registration.unregister()); + const worker = registration.installing; + await wait_for_state(t, worker, 'activated'); + return worker; +} + +// Add an iframe (parent) whose document contains a nested iframe +// (child), then set the child's src attribute to child_url and return +// its Window (without waiting for it to finish loading). +async function with_nested_iframes(t, child_url) { + const parent = await with_iframe('resources/nested-iframe-parent.html?role=parent'); + t.add_cleanup(() => parent.remove()); + const child = parent.contentWindow.document.getElementById('child'); + child.setAttribute('src', child_url); + return child.contentWindow; +} + +// Returns a predicate matching a fetch message with the specified +// key. +function fetch_message(key) { + return event => event.data.type === 'fetch' && event.data.key === key; +} + +// Returns a predicate matching a ping message with the specified +// payload. +function ping_message(data) { + return event => event.data.type === 'ping' && event.data.data === data; +} + +// A client message queue test is a testharness.js test with some +// additional setup: +// 1. A listener (see create_message_listener) +// 2. An active service worker +// 3. Two nested iframes +// 4. A state transition function that controls the order of events +// during the test +function client_message_queue_test(url, test_function, description) { + promise_test(async t => { + t.listener = create_message_listener(t); + + const script = 'resources/stalling-service-worker.js'; + const scope = 'resources/'; + t.service_worker = await service_worker_register_and_activate(t, script, scope); + + // We create two nested iframes such that both are controlled by + // the newly installed service worker. + const child_url = url + '?role=child'; + t.frame = await with_nested_iframes(t, child_url); + + t.state_transition = async function(from, to, scripts) { + // A state transition begins with the child's parser + // fetching a script due to a <script> tag. The request + // arrives at the service worker, which notifies the + // parent, which in turn notifies the test. Note that the + // event loop keeps spinning while the parser is waiting. + const request = await this.listener.waitFor(fetch_message(to)); + + // The test instructs the service worker to send two ping + // messages through the Client interface: first to the + // child, then to the parent. + this.service_worker.postMessage(from); + + // When the parent receives the ping message, it forwards + // it to the test. Assuming that messages to both child + // and parent are mapped to the same task queue (this is + // not [yet] required by the spec), receiving this message + // guarantees that the child has already dispatched its + // message if it was allowed to do so. + await this.listener.waitFor(ping_message(from)); + + // Finally, reply to the service worker's fetch + // notification with the script it should use as the fetch + // request's response. This is a defensive mechanism that + // ensures the child's parser really is blocked until the + // test is ready to continue. + request.ports[0].postMessage([`state = '${to}';`].concat(scripts)); + }; + + await test_function(t); + }, description); +} + +function client_message_queue_enable_test( + install_script, + start_script, + earliest_dispatch, + description) +{ + function later_state(state1, state2) { + const states = ['init', 'install', 'start', 'finish', 'loaded']; + const index1 = states.indexOf(state1); + const index2 = states.indexOf(state2); + const max_index = Math.max(index1, index2); + return states[max_index]; + } + + client_message_queue_test('enable-client-message-queue.html', async t => { + // While parsing the child's document, the child transitions + // from the 'init' state all the way to the 'finish' state. + // Once parsing is finished it would enter the final 'loaded' + // state. All but the last transition require assitance from + // the test. + await t.state_transition('init', 'install', [install_script]); + await t.state_transition('install', 'start', [start_script]); + await t.state_transition('start', 'finish', []); + + // Wait for all messages to get dispatched on the child's + // ServiceWorkerContainer and then verify that each message + // was dispatched while the child was in the correct state. + const report = await t.frame.report; + ['init', 'install', 'start'].forEach(state => { + const dispatch = later_state(state, earliest_dispatch); + assert_equals(report[state], dispatch, + `Message sent in state '${state}' dispatched in state '${dispatch}'`); + }); + }, description); +} + +const empty_script = ``; + +const add_event_listener = + `navigator.serviceWorker.addEventListener('message', handle_message);`; + +const set_onmessage = `navigator.serviceWorker.onmessage = handle_message;`; + +const start_messages = `navigator.serviceWorker.startMessages();`; + +client_message_queue_enable_test(add_event_listener, empty_script, 'loaded', + 'Messages from ServiceWorker to Client only received after DOMContentLoaded event.'); + +client_message_queue_enable_test(add_event_listener, start_messages, 'start', + 'Messages from ServiceWorker to Client only received after calling startMessages().'); + +client_message_queue_enable_test(set_onmessage, empty_script, 'install', + 'Messages from ServiceWorker to Client only received after setting onmessage.'); + +const resolve_manual_promise = `resolve_manual_promise();` + +async function test_microtasks_when_client_message_queue_enabled(t, scripts) { + await t.state_transition('init', 'start', scripts.concat([resolve_manual_promise])); + let result = await t.frame.result; + assert_equals(result[0], 'microtask', 'The microtask was executed first.'); + assert_equals(result[1], 'message', 'The message was dispatched.'); +} + +client_message_queue_test('message-vs-microtask.html', t => { + return test_microtasks_when_client_message_queue_enabled(t, [ + add_event_listener, + start_messages, + ]); +}, 'Microtasks run before dispatching messages after calling startMessages().'); + +client_message_queue_test('message-vs-microtask.html', t => { + return test_microtasks_when_client_message_queue_enabled(t, [set_onmessage]); +}, 'Microtasks run before dispatching messages after setting onmessage.'); +</script> diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html index b1dc41a018f..15d2e889337 100644 --- a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html +++ b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html @@ -51,208 +51,4 @@ promise_test(t => { }) .then(e => { assert_equals(e.data, 'quit'); }); }, 'postMessage from ServiceWorker to Client.'); - -// This function creates a message listener that captures all messages -// sent to this window and matches them with corresponding requests. -// This frees test code from having to use clunky constructs just to -// avoid race conditions, since the relative order of message and -// request arrival doesn't matter. -function create_message_listener(t) { - const listener = { - messages: new Set(), - requests: new Set(), - waitFor: function(predicate) { - for (const event of this.messages) { - // If a message satisfying the predicate has already - // arrived, it gets matched to this request. - if (predicate(event)) { - this.messages.delete(event); - return Promise.resolve(event); - } - } - - // If no match was found, the request is stored and a - // promise is returned. - const request = { predicate }; - const promise = new Promise(resolve => request.resolve = resolve); - this.requests.add(request); - return promise; - } - }; - window.onmessage = t.step_func(event => { - for (const request of listener.requests) { - // If the new message matches a stored request's - // predicate, the request's promise is resolved with this - // message. - if (request.predicate(event)) { - listener.requests.delete(request); - request.resolve(event); - return; - } - }; - - // No outstanding request for this message, store it in case - // it's requested later. - listener.messages.add(event); - }); - return listener; -} - -async function service_worker_register_and_activate(t, script, scope) { - const registration = await service_worker_unregister_and_register(t, script, scope); - t.add_cleanup(() => registration.unregister()); - const worker = registration.installing; - await wait_for_state(t, worker, 'activated'); - return worker; -} - -// Add an iframe (parent) whose document contains a nested iframe -// (child), then set the child's src attribute to child_url and return -// its Window (without waiting for it to finish loading). -async function with_nested_iframes(t, child_url) { - const parent = await with_iframe('resources/nested-iframe-parent.html?role=parent'); - t.add_cleanup(() => parent.remove()); - const child = parent.contentWindow.document.getElementById('child'); - child.setAttribute('src', child_url); - return child.contentWindow; -} - -// Returns a predicate matching a fetch message with the specified -// key. -function fetch_message(key) { - return event => event.data.type === 'fetch' && event.data.key === key; -} - -// Returns a predicate matching a ping message with the specified -// payload. -function ping_message(data) { - return event => event.data.type === 'ping' && event.data.data === data; -} - -// A client message queue test is a testharness.js test with some -// additional setup: -// 1. A listener (see create_message_listener) -// 2. An active service worker -// 3. Two nested iframes -// 4. A state transition function that controls the order of events -// during the test -function client_message_queue_test(url, test_function, description) { - promise_test(async t => { - t.listener = create_message_listener(t); - - const script = 'resources/stalling-service-worker.js'; - const scope = 'resources/'; - t.service_worker = await service_worker_register_and_activate(t, script, scope); - - // We create two nested iframes such that both are controlled by - // the newly installed service worker. - const child_url = url + '?role=child'; - t.frame = await with_nested_iframes(t, child_url); - - t.state_transition = async function(from, to, scripts) { - // A state transition begins with the child's parser - // fetching a script due to a <script> tag. The request - // arrives at the service worker, which notifies the - // parent, which in turn notifies the test. Note that the - // event loop keeps spinning while the parser is waiting. - const request = await this.listener.waitFor(fetch_message(to)); - - // The test instructs the service worker to send two ping - // messages through the Client interface: first to the - // child, then to the parent. - this.service_worker.postMessage(from); - - // When the parent receives the ping message, it forwards - // it to the test. Assuming that messages to both child - // and parent are mapped to the same task queue (this is - // not [yet] required by the spec), receiving this message - // guarantees that the child has already dispatched its - // message if it was allowed to do so. - await this.listener.waitFor(ping_message(from)); - - // Finally, reply to the service worker's fetch - // notification with the script it should use as the fetch - // request's response. This is a defensive mechanism that - // ensures the child's parser really is blocked until the - // test is ready to continue. - request.ports[0].postMessage([`state = '${to}';`].concat(scripts)); - }; - - await test_function(t); - }, description); -} - -function client_message_queue_enable_test( - install_script, - start_script, - earliest_dispatch, - description) -{ - function later_state(state1, state2) { - const states = ['init', 'install', 'start', 'finish', 'loaded']; - const index1 = states.indexOf(state1); - const index2 = states.indexOf(state2); - const max_index = Math.max(index1, index2); - return states[max_index]; - } - - client_message_queue_test('enable-client-message-queue.html', async t => { - // While parsing the child's document, the child transitions - // from the 'init' state all the way to the 'finish' state. - // Once parsing is finished it would enter the final 'loaded' - // state. All but the last transition require assitance from - // the test. - await t.state_transition('init', 'install', [install_script]); - await t.state_transition('install', 'start', [start_script]); - await t.state_transition('start', 'finish', []); - - // Wait for all messages to get dispatched on the child's - // ServiceWorkerContainer and then verify that each message - // was dispatched while the child was in the correct state. - const report = await t.frame.report; - ['init', 'install', 'start'].forEach(state => { - const dispatch = later_state(state, earliest_dispatch); - assert_equals(report[state], dispatch, - `Message sent in state '${state}' dispatched in state '${dispatch}'`); - }); - }, description); -} - -const empty_script = ``; - -const add_event_listener = - `navigator.serviceWorker.addEventListener('message', handle_message);`; - -const set_onmessage = `navigator.serviceWorker.onmessage = handle_message;`; - -const start_messages = `navigator.serviceWorker.startMessages();`; - -client_message_queue_enable_test(add_event_listener, empty_script, 'loaded', - 'Messages from ServiceWorker to Client only received after DOMContentLoaded event.'); - -client_message_queue_enable_test(add_event_listener, start_messages, 'start', - 'Messages from ServiceWorker to Client only received after calling startMessages().'); - -client_message_queue_enable_test(set_onmessage, empty_script, 'install', - 'Messages from ServiceWorker to Client only received after setting onmessage.'); - -const resolve_manual_promise = `resolve_manual_promise();` - -async function test_microtasks_when_client_message_queue_enabled(t, scripts) { - await t.state_transition('init', 'start', scripts.concat([resolve_manual_promise])); - let result = await t.frame.result; - assert_equals(result[0], 'microtask', 'The microtask was executed first.'); - assert_equals(result[1], 'message', 'The message was dispatched.'); -} - -client_message_queue_test('message-vs-microtask.html', t => { - return test_microtasks_when_client_message_queue_enabled(t, [ - add_event_listener, - start_messages, - ]); -}, 'Microtasks run before dispatching messages after calling startMessages().'); - -client_message_queue_test('message-vs-microtask.html', t => { - return test_microtasks_when_client_message_queue_enabled(t, [set_onmessage]); -}, 'Microtasks run before dispatching messages after setting onmessage.'); </script> diff --git a/tests/wpt/web-platform-tests/speech-api/META.yml b/tests/wpt/web-platform-tests/speech-api/META.yml index 17263d91d36..ac4b89b0349 100644 --- a/tests/wpt/web-platform-tests/speech-api/META.yml +++ b/tests/wpt/web-platform-tests/speech-api/META.yml @@ -1,4 +1,3 @@ spec: https://w3c.github.io/speech-api/ suggested_reviewers: - - andrenatal - gshires diff --git a/tests/wpt/web-platform-tests/subresource-integrity/META.yml b/tests/wpt/web-platform-tests/subresource-integrity/META.yml index 740ad1412f6..2b8891ec6b4 100644 --- a/tests/wpt/web-platform-tests/subresource-integrity/META.yml +++ b/tests/wpt/web-platform-tests/subresource-integrity/META.yml @@ -1,8 +1,6 @@ spec: https://w3c.github.io/webappsec-subresource-integrity/ suggested_reviewers: - metromoxie - - fmarier - jonathanKingston - mikewest - hillbrad - - mastahyeti diff --git a/tests/wpt/web-platform-tests/tools/wpt/run.py b/tests/wpt/web-platform-tests/tools/wpt/run.py index a2cd1c0b115..b977d8a0cd6 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/run.py +++ b/tests/wpt/web-platform-tests/tools/wpt/run.py @@ -264,6 +264,8 @@ class Chrome(BrowserSetup): if kwargs["browser_channel"] == "dev": logger.info("Automatically turning on experimental features for Chrome Dev") kwargs["binary_args"].append("--enable-experimental-web-platform-features") + # TODO(foolip): remove after unified plan is enabled on Chrome stable + kwargs["binary_args"].append("--enable-features=RTCUnifiedPlanByDefault") # Allow audio autoplay without a user gesture. kwargs["binary_args"].append("--autoplay-policy=no-user-gesture-required") diff --git a/tests/wpt/web-platform-tests/tools/wpt/utils.py b/tests/wpt/web-platform-tests/tools/wpt/utils.py index 1e622a63859..fa60230389d 100644 --- a/tests/wpt/web-platform-tests/tools/wpt/utils.py +++ b/tests/wpt/web-platform-tests/tools/wpt/utils.py @@ -1,7 +1,6 @@ import logging import os import subprocess -import sys import tarfile import zipfile from io import BytesIO @@ -49,20 +48,6 @@ def call(*args): raise -def get_git_cmd(repo_path): - """Create a function for invoking git commands as a subprocess.""" - def git(cmd, *args): - full_cmd = ["git", cmd] + list(args) - try: - logger.debug(" ".join(full_cmd)) - return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT).strip() - except subprocess.CalledProcessError as e: - logger.error("Git command exited with status %i" % e.returncode) - logger.error(e.output) - sys.exit(1) - return git - - def seekable(fileobj): """Attempt to use file.seek on given file, with fallbacks.""" try: @@ -94,21 +79,6 @@ def unzip(fileobj, dest=None, limit=None): os.chmod(os.path.join(dest, info.filename), perm) -class pwd(object): - """Create context for temporarily changing present working directory.""" - def __init__(self, dir): - self.dir = dir - self.old_dir = None - - def __enter__(self): - self.old_dir = os.path.abspath(os.curdir) - os.chdir(self.dir) - - def __exit__(self, *args, **kwargs): - os.chdir(self.old_dir) - self.old_dir = None - - def get(url): """Issue GET request to a given URL and return the response.""" import requests diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py index 2b7c091c847..e819f242e2d 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/testrunner.py @@ -818,14 +818,10 @@ class ManagerGroup(object): self.pool.add(manager) self.wait() - def is_alive(self): - """Boolean indicating whether any manager in the group is still alive""" - return any(manager.is_alive() for manager in self.pool) - def wait(self): """Wait for all the managers in the group to finish""" - for item in self.pool: - item.join() + for manager in self.pool: + manager.join() def stop(self): """Set the stop flag so that all managers in the group stop as soon @@ -834,7 +830,7 @@ class ManagerGroup(object): self.logger.debug("Stop flag set in ManagerGroup") def test_count(self): - return sum(item.test_count for item in self.pool) + return sum(manager.test_count for manager in self.pool) def unexpected_count(self): - return sum(item.unexpected_count for item in self.pool) + return sum(manager.unexpected_count for manager in self.pool) diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py index 0a5b1352e21..d0c1106b0f9 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/wptrunner.py @@ -275,8 +275,8 @@ def run_tests(config, test_paths, product, **kwargs): logger.critical("Main thread got signal") manager_group.stop() raise - test_count += manager_group.test_count() - unexpected_count += manager_group.unexpected_count() + test_count += manager_group.test_count() + unexpected_count += manager_group.unexpected_count() test_total += test_count unexpected_total += unexpected_count diff --git a/tests/wpt/web-platform-tests/url/META.yml b/tests/wpt/web-platform-tests/url/META.yml index 459152f6f07..3a789a0d513 100644 --- a/tests/wpt/web-platform-tests/url/META.yml +++ b/tests/wpt/web-platform-tests/url/META.yml @@ -1,7 +1,6 @@ spec: https://url.spec.whatwg.org/ suggested_reviewers: - mikewest - - smola - domenic - Sebmaster - annevk diff --git a/tests/wpt/web-platform-tests/webaudio/META.yml b/tests/wpt/web-platform-tests/webaudio/META.yml index 37276da5334..e8f8cc59489 100644 --- a/tests/wpt/web-platform-tests/webaudio/META.yml +++ b/tests/wpt/web-platform-tests/webaudio/META.yml @@ -1,5 +1,4 @@ spec: https://webaudio.github.io/web-audio-api/ suggested_reviewers: - - chrislo - padenot - rtoy diff --git a/tests/wpt/web-platform-tests/webdriver/tests/conftest.py b/tests/wpt/web-platform-tests/webdriver/tests/conftest.py index d16883256ac..42b82c9ecf2 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/conftest.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/conftest.py @@ -1,234 +1 @@ -import copy -import json -import os -import urlparse - -import pytest -import webdriver - -from tests.support import defaults -from tests.support.helpers import cleanup_session -from tests.support.http_request import HTTPRequest -from tests.support.sync import Poll - - -_current_session = None -_custom_session = False - - -def pytest_configure(config): - # register the capabilities marker - config.addinivalue_line("markers", - "capabilities: mark test to use capabilities") - - -@pytest.fixture -def capabilities(): - """Default capabilities to use for a new WebDriver session.""" - return {} - - -def pytest_generate_tests(metafunc): - if "capabilities" in metafunc.fixturenames: - marker = metafunc.definition.get_closest_marker(name="capabilities") - if marker: - metafunc.parametrize("capabilities", marker.args, ids=None) - - -@pytest.fixture -def add_event_listeners(session): - """Register listeners for tracked events on element.""" - def add_event_listeners(element, tracked_events): - element.session.execute_script(""" - let element = arguments[0]; - let trackedEvents = arguments[1]; - - if (!("events" in window)) { - window.events = []; - } - - for (var i = 0; i < trackedEvents.length; i++) { - element.addEventListener(trackedEvents[i], function (event) { - window.events.push(event.type); - }); - } - """, args=(element, tracked_events)) - return add_event_listeners - - -@pytest.fixture -def create_cookie(session, url): - """Create a cookie""" - def create_cookie(name, value, **kwargs): - if kwargs.get("path", None) is not None: - session.url = url(kwargs["path"]) - - session.set_cookie(name, value, **kwargs) - return session.cookies(name) - - return create_cookie - - -@pytest.fixture -def create_frame(session): - """Create an `iframe` element in the current browsing context and insert it - into the document. Return a reference to the newly-created element.""" - def create_frame(): - append = """ - var frame = document.createElement('iframe'); - document.body.appendChild(frame); - return frame; - """ - return session.execute_script(append) - - return create_frame - - -@pytest.fixture -def create_window(session): - """Open new window and return the window handle.""" - def create_window(): - windows_before = session.handles - name = session.execute_script("window.open()") - assert len(session.handles) == len(windows_before) + 1 - new_windows = list(set(session.handles) - set(windows_before)) - return new_windows.pop() - return create_window - - -@pytest.fixture -def http(configuration): - return HTTPRequest(configuration["host"], configuration["port"]) - - -@pytest.fixture -def server_config(): - return json.loads(os.environ.get("WD_SERVER_CONFIG")) - - -@pytest.fixture(scope="session") -def configuration(): - host = os.environ.get("WD_HOST", defaults.DRIVER_HOST) - port = int(os.environ.get("WD_PORT", str(defaults.DRIVER_PORT))) - capabilities = json.loads(os.environ.get("WD_CAPABILITIES", "{}")) - - return { - "host": host, - "port": port, - "capabilities": capabilities - } - - -@pytest.fixture(scope="function") -def session(capabilities, configuration, request): - """Create and start a session for a test that does not itself test session creation. - - By default the session will stay open after each test, but we always try to start a - new one and assume that if that fails there is already a valid session. This makes it - possible to recover from some errors that might leave the session in a bad state, but - does not demand that we start a new session per test.""" - global _current_session - - # Update configuration capabilities with custom ones from the - # capabilities fixture, which can be set by tests - caps = copy.deepcopy(configuration["capabilities"]) - caps.update(capabilities) - caps = {"alwaysMatch": caps} - - # If there is a session with different capabilities active, end it now - if _current_session is not None and ( - caps != _current_session.requested_capabilities): - _current_session.end() - _current_session = None - - if _current_session is None: - _current_session = webdriver.Session( - configuration["host"], - configuration["port"], - capabilities=caps) - try: - _current_session.start() - except webdriver.error.SessionNotCreatedException: - if not _current_session.session_id: - raise - - # Enforce a fixed default window size - _current_session.window.size = defaults.WINDOW_SIZE - - yield _current_session - - cleanup_session(_current_session) - - -@pytest.fixture(scope="function") -def current_session(): - return _current_session - - -@pytest.fixture -def url(server_config): - def inner(path, protocol="http", query="", fragment=""): - port = server_config["ports"][protocol][0] - host = "%s:%s" % (server_config["browser_host"], port) - return urlparse.urlunsplit((protocol, host, path, query, fragment)) - - inner.__name__ = "url" - return inner - - -@pytest.fixture -def create_dialog(session): - """Create a dialog (one of "alert", "prompt", or "confirm") and provide a - function to validate that the dialog has been "handled" (either accepted or - dismissed) by returning some value.""" - - def create_dialog(dialog_type, text=None): - assert dialog_type in ("alert", "confirm", "prompt"), ( - "Invalid dialog type: '%s'" % dialog_type) - - if text is None: - text = "" - - assert isinstance(text, basestring), "`text` parameter must be a string" - - # Script completes itself when the user prompt has been opened. - # For prompt() dialogs, add a value for the 'default' argument, - # as some user agents (IE, for example) do not produce consistent - # values for the default. - session.execute_async_script(""" - let dialog_type = arguments[0]; - let text = arguments[1]; - - setTimeout(function() { - if (dialog_type == 'prompt') { - window.dialog_return_value = window[dialog_type](text, ''); - } else { - window.dialog_return_value = window[dialog_type](text); - } - }, 0); - """, args=(dialog_type, text)) - - wait = Poll( - session, - timeout=15, - ignored_exceptions=webdriver.NoSuchAlertException, - message="No user prompt with text '{}' detected".format(text)) - wait.until(lambda s: s.alert.text == text) - - return create_dialog - - -@pytest.fixture -def closed_window(session, create_window): - original_handle = session.window_handle - - new_handle = create_window() - session.window_handle = new_handle - - session.close() - assert new_handle not in session.handles, "Unable to close window {}".format(new_handle) - - yield new_handle - - session.window_handle = original_handle - +pytest_plugins = "tests.support.fixtures" diff --git a/tests/wpt/web-platform-tests/webdriver/tests/element_click/center_point.py b/tests/wpt/web-platform-tests/webdriver/tests/element_click/center_point.py index b3d2ea7a109..21bf8f31fd8 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/element_click/center_point.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/element_click/center_point.py @@ -51,7 +51,7 @@ def square(size): <script> window.clicks = []; let div = document.querySelector("div"); - div.addEventListener("click", ({{clientX, clientY}}) => window.clicks.push([clientX, clientY])); + div.addEventListener("click", function(e) {{ window.clicks.push([e.clientX, e.clientY]) }}); </script> """.format(size=size)) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py b/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py index cdf313bc04b..1dea6ce6877 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/asserts.py @@ -1,3 +1,6 @@ +import base64 +import imghdr + from webdriver import Element, NoSuchAlertException, WebDriverException @@ -189,3 +192,10 @@ def assert_move_to_coordinates(point, target, events): assert e["pageX"] == point["x"] assert e["pageY"] == point["y"] assert e["target"] == target + + +def assert_png(screenshot): + """Test that screenshot is a Base64 encoded PNG file.""" + image = base64.decodestring(screenshot) + mime_type = imghdr.what("", image) + assert mime_type == "png", "Expected image to be PNG, but it was {}".format(mime_type) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py b/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py new file mode 100644 index 00000000000..d16883256ac --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/fixtures.py @@ -0,0 +1,234 @@ +import copy +import json +import os +import urlparse + +import pytest +import webdriver + +from tests.support import defaults +from tests.support.helpers import cleanup_session +from tests.support.http_request import HTTPRequest +from tests.support.sync import Poll + + +_current_session = None +_custom_session = False + + +def pytest_configure(config): + # register the capabilities marker + config.addinivalue_line("markers", + "capabilities: mark test to use capabilities") + + +@pytest.fixture +def capabilities(): + """Default capabilities to use for a new WebDriver session.""" + return {} + + +def pytest_generate_tests(metafunc): + if "capabilities" in metafunc.fixturenames: + marker = metafunc.definition.get_closest_marker(name="capabilities") + if marker: + metafunc.parametrize("capabilities", marker.args, ids=None) + + +@pytest.fixture +def add_event_listeners(session): + """Register listeners for tracked events on element.""" + def add_event_listeners(element, tracked_events): + element.session.execute_script(""" + let element = arguments[0]; + let trackedEvents = arguments[1]; + + if (!("events" in window)) { + window.events = []; + } + + for (var i = 0; i < trackedEvents.length; i++) { + element.addEventListener(trackedEvents[i], function (event) { + window.events.push(event.type); + }); + } + """, args=(element, tracked_events)) + return add_event_listeners + + +@pytest.fixture +def create_cookie(session, url): + """Create a cookie""" + def create_cookie(name, value, **kwargs): + if kwargs.get("path", None) is not None: + session.url = url(kwargs["path"]) + + session.set_cookie(name, value, **kwargs) + return session.cookies(name) + + return create_cookie + + +@pytest.fixture +def create_frame(session): + """Create an `iframe` element in the current browsing context and insert it + into the document. Return a reference to the newly-created element.""" + def create_frame(): + append = """ + var frame = document.createElement('iframe'); + document.body.appendChild(frame); + return frame; + """ + return session.execute_script(append) + + return create_frame + + +@pytest.fixture +def create_window(session): + """Open new window and return the window handle.""" + def create_window(): + windows_before = session.handles + name = session.execute_script("window.open()") + assert len(session.handles) == len(windows_before) + 1 + new_windows = list(set(session.handles) - set(windows_before)) + return new_windows.pop() + return create_window + + +@pytest.fixture +def http(configuration): + return HTTPRequest(configuration["host"], configuration["port"]) + + +@pytest.fixture +def server_config(): + return json.loads(os.environ.get("WD_SERVER_CONFIG")) + + +@pytest.fixture(scope="session") +def configuration(): + host = os.environ.get("WD_HOST", defaults.DRIVER_HOST) + port = int(os.environ.get("WD_PORT", str(defaults.DRIVER_PORT))) + capabilities = json.loads(os.environ.get("WD_CAPABILITIES", "{}")) + + return { + "host": host, + "port": port, + "capabilities": capabilities + } + + +@pytest.fixture(scope="function") +def session(capabilities, configuration, request): + """Create and start a session for a test that does not itself test session creation. + + By default the session will stay open after each test, but we always try to start a + new one and assume that if that fails there is already a valid session. This makes it + possible to recover from some errors that might leave the session in a bad state, but + does not demand that we start a new session per test.""" + global _current_session + + # Update configuration capabilities with custom ones from the + # capabilities fixture, which can be set by tests + caps = copy.deepcopy(configuration["capabilities"]) + caps.update(capabilities) + caps = {"alwaysMatch": caps} + + # If there is a session with different capabilities active, end it now + if _current_session is not None and ( + caps != _current_session.requested_capabilities): + _current_session.end() + _current_session = None + + if _current_session is None: + _current_session = webdriver.Session( + configuration["host"], + configuration["port"], + capabilities=caps) + try: + _current_session.start() + except webdriver.error.SessionNotCreatedException: + if not _current_session.session_id: + raise + + # Enforce a fixed default window size + _current_session.window.size = defaults.WINDOW_SIZE + + yield _current_session + + cleanup_session(_current_session) + + +@pytest.fixture(scope="function") +def current_session(): + return _current_session + + +@pytest.fixture +def url(server_config): + def inner(path, protocol="http", query="", fragment=""): + port = server_config["ports"][protocol][0] + host = "%s:%s" % (server_config["browser_host"], port) + return urlparse.urlunsplit((protocol, host, path, query, fragment)) + + inner.__name__ = "url" + return inner + + +@pytest.fixture +def create_dialog(session): + """Create a dialog (one of "alert", "prompt", or "confirm") and provide a + function to validate that the dialog has been "handled" (either accepted or + dismissed) by returning some value.""" + + def create_dialog(dialog_type, text=None): + assert dialog_type in ("alert", "confirm", "prompt"), ( + "Invalid dialog type: '%s'" % dialog_type) + + if text is None: + text = "" + + assert isinstance(text, basestring), "`text` parameter must be a string" + + # Script completes itself when the user prompt has been opened. + # For prompt() dialogs, add a value for the 'default' argument, + # as some user agents (IE, for example) do not produce consistent + # values for the default. + session.execute_async_script(""" + let dialog_type = arguments[0]; + let text = arguments[1]; + + setTimeout(function() { + if (dialog_type == 'prompt') { + window.dialog_return_value = window[dialog_type](text, ''); + } else { + window.dialog_return_value = window[dialog_type](text); + } + }, 0); + """, args=(dialog_type, text)) + + wait = Poll( + session, + timeout=15, + ignored_exceptions=webdriver.NoSuchAlertException, + message="No user prompt with text '{}' detected".format(text)) + wait.until(lambda s: s.alert.text == text) + + return create_dialog + + +@pytest.fixture +def closed_window(session, create_window): + original_handle = session.window_handle + + new_handle = create_window() + session.window_handle = new_handle + + session.close() + assert new_handle not in session.handles, "Unable to close window {}".format(new_handle) + + yield new_handle + + session.window_handle = original_handle + diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/helpers.py b/tests/wpt/web-platform-tests/webdriver/tests/support/helpers.py index b2db3e7b0d3..5dd7a323d8c 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/support/helpers.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/helpers.py @@ -117,3 +117,11 @@ def is_element_in_viewport(session, element): return !(rect.right < 0 || rect.bottom < 0 || rect.left > viewport.width || rect.top > viewport.height) """, args=(element,)) + + +def document_dimensions(session): + return tuple(session.execute_script(""" + let {devicePixelRatio} = window; + let {width, height} = document.documentElement.getBoundingClientRect(); + return [width * devicePixelRatio, height * devicePixelRatio]; + """)) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/image.py b/tests/wpt/web-platform-tests/webdriver/tests/support/image.py new file mode 100644 index 00000000000..1eb3a187a43 --- /dev/null +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/image.py @@ -0,0 +1,11 @@ +import base64 +import struct + +from tests.support.asserts import assert_png + + +def png_dimensions(screenshot): + assert_png(screenshot) + image = base64.decodestring(screenshot) + width, height = struct.unpack(">LL", image[16:24]) + return int(width), int(height) diff --git a/tests/wpt/web-platform-tests/webdriver/tests/support/inline.py b/tests/wpt/web-platform-tests/webdriver/tests/support/inline.py index 3bf56c84bed..8b4f1657cff 100644 --- a/tests/wpt/web-platform-tests/webdriver/tests/support/inline.py +++ b/tests/wpt/web-platform-tests/webdriver/tests/support/inline.py @@ -2,7 +2,7 @@ import urllib def inline(doc, doctype="html", mime="text/html;charset=utf-8", protocol="http"): - from ..conftest import server_config, url + from .fixtures import server_config, url build_url = url(server_config()) if doctype == "html": diff --git a/tests/wpt/web-platform-tests/xhr/send-content-type-charset.htm b/tests/wpt/web-platform-tests/xhr/send-content-type-charset.htm index 4e75df23468..0a91e1fbd7e 100644 --- a/tests/wpt/web-platform-tests/xhr/send-content-type-charset.htm +++ b/tests/wpt/web-platform-tests/xhr/send-content-type-charset.htm @@ -4,8 +4,6 @@ <title>XMLHttpRequest: send() - charset parameter of Content-Type</title> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> - <link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::ol[1]/li[4]/p/code[contains(text(),'Content-Type')]/.. following::ol[1]/li[4]/p/code[contains(text(),'Content-Type')]/../following-sibling::p" /> - <link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-a-string" data-tested-assertations="following::p[2]" /> </head> <body> <div id="log"></div> @@ -45,8 +43,8 @@ ) request( "text/plain;charset=utf-8", - "text/plain;charset=UTF-8", - "Correct text/plain MIME with charset" + "text/plain;charset=utf-8", + "If charset= param is UTF-8 (case-insensitive), it should not be changed" ) request( "text/x-pink-unicorn", @@ -70,8 +68,8 @@ ) request( "text/plain;charset=utf-8;charset=waddup", - "text/plain;charset=UTF-8", - "charset given but wrong, fix it (known MIME, bogus charset)" + "text/plain;charset=utf-8;charset=waddup", + "If charset= param is UTF-8 (case-insensitive), it should not be changed (bogus charset)" ) request( "text/plain;charset=shift-jis", @@ -81,7 +79,7 @@ request( "text/x-pink-unicorn; charset=windows-1252; charset=bogus; notrelated; charset=ascii", "text/x-pink-unicorn;charset=UTF-8", - "Multiple charset parameters deduplicate, bogus parameter dropped" + "Multiple non-UTF-8 charset parameters deduplicate, bogus parameter dropped" ) request( null, @@ -90,20 +88,20 @@ ) request( "text/plain;charset= utf-8", - "text/plain;charset=UTF-8", - "charset with space") + "text/plain;charset= utf-8", + "charset with space that is UTF-8 does not change") request( "text/plain;charset=\"utf-8\"", - "text/plain;charset=UTF-8", - "charset in double quotes") + "text/plain;charset=\"utf-8\"", + "charset in double quotes that is UTF-8 does not change") request( "text/plain;charset=\" utf-8\"", "text/plain;charset=UTF-8", "charset in double quotes with space") request( "text/plain;charset=\"u\\t\\f-8\"", - "text/plain;charset=UTF-8", - "charset in double quotes with backslashes") + "text/plain;charset=\"u\\t\\f-8\"", + "charset in double quotes with backslashes that is UTF-8 does not change") request( "YO/yo;charset=x;yo=YO; X=y", "yo/yo;charset=UTF-8;yo=YO;x=y", |