diff options
407 files changed, 12183 insertions, 1088 deletions
diff --git a/tests/wpt/meta-legacy-layout/css/css-content/parsing/content-valid.html.ini b/tests/wpt/meta-legacy-layout/css/css-content/parsing/content-valid.html.ini index ec3fb653e49..030357bc4f9 100644 --- a/tests/wpt/meta-legacy-layout/css/css-content/parsing/content-valid.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-content/parsing/content-valid.html.ini @@ -214,3 +214,21 @@ [e.style['content'\] = "url(\\"https://www.example.com/picture.svg\\") \\"hello\\" / attr(foo)" should set the property value] expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / \\"alt text\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / \\"alt text\\" attr(foo) \\"bar\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / attr(foo)" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / \\"alt text\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / \\"alt text\\" attr(foo) \\"bar\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / attr(foo)" should set the property value] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-lists/counters-005.html.ini b/tests/wpt/meta-legacy-layout/css/css-lists/counters-005.html.ini new file mode 100644 index 00000000000..41b44b5559d --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-lists/counters-005.html.ini @@ -0,0 +1,2 @@ +[counters-005.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-overflow/overfow-outside-padding.html.ini b/tests/wpt/meta-legacy-layout/css/css-overflow/overflow-outside-padding.html.ini index 5df726e8c88..58ca44deaae 100644 --- a/tests/wpt/meta-legacy-layout/css/css-overflow/overfow-outside-padding.html.ini +++ b/tests/wpt/meta-legacy-layout/css/css-overflow/overflow-outside-padding.html.ini @@ -1,3 +1,3 @@ -[overfow-outside-padding.html] +[overflow-outside-padding.html] [#target did not trigger scroll overflow] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/css-text/white-space/text-wrap-nowrap-001.html.ini b/tests/wpt/meta-legacy-layout/css/css-text/white-space/text-wrap-nowrap-001.html.ini new file mode 100644 index 00000000000..bcca040350a --- /dev/null +++ b/tests/wpt/meta-legacy-layout/css/css-text/white-space/text-wrap-nowrap-001.html.ini @@ -0,0 +1,2 @@ +[text-wrap-nowrap-001.html] + expected: FAIL diff --git a/tests/wpt/meta/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html.ini b/tests/wpt/meta-legacy-layout/css/cssom/CSSStyleSheet-constructable-baseURL.html.ini index 13602c25c9d..a9bad39b1da 100644 --- a/tests/wpt/meta/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/css/cssom/CSSStyleSheet-constructable-baseURL.html.ini @@ -1,10 +1,9 @@ -[CSSStyleSheet-constructable-baseURL.tentative.html] +[CSSStyleSheet-constructable-baseURL.html] [Constructing sheet with custom base URL ueses that URL for CSS rules] expected: FAIL - [Constructing sheet with invalid base URL throws a NotAllowedError] - expected: FAIL - [Constructing sheet with relative URL adds to the constructor document's base URL] expected: FAIL + [Constructing sheet with invalid base URL throws a NotAllowedError] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/custom-elements/reactions/customized-builtins/HTMLMediaElement.html.ini b/tests/wpt/meta-legacy-layout/custom-elements/reactions/customized-builtins/HTMLMediaElement.html.ini new file mode 100644 index 00000000000..2ca05f57bb0 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/custom-elements/reactions/customized-builtins/HTMLMediaElement.html.ini @@ -0,0 +1,2 @@ +[HTMLMediaElement.html] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini b/tests/wpt/meta-legacy-layout/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini index 14c28753235..17c5362cdbb 100644 --- a/tests/wpt/meta-legacy-layout/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini +++ b/tests/wpt/meta-legacy-layout/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini @@ -10,3 +10,6 @@ [Upgrade into customized built-in element when definition is added] expected: FAIL + + [Upgrade into autonomous custom element should not inherit from global registry for missing values] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/eventsource/eventsource-request-cancellation.any.window.js.ini b/tests/wpt/meta-legacy-layout/eventsource/eventsource-request-cancellation.any.window.js.ini deleted file mode 100644 index 101e03a6b7d..00000000000 --- a/tests/wpt/meta-legacy-layout/eventsource/eventsource-request-cancellation.any.window.js.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-request-cancellation.window.any.html] - expected: TIMEOUT - -[eventsource-request-cancellation.window.any.worker.html] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/fetch/api/response/response-arraybuffer-realm.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/api/response/response-arraybuffer-realm.window.js.ini new file mode 100644 index 00000000000..e273ea59211 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/fetch/api/response/response-arraybuffer-realm.window.js.ini @@ -0,0 +1,3 @@ +[response-arraybuffer-realm.window.html] + [realm of the ArrayBuffer from Response arrayBuffer()] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini b/tests/wpt/meta-legacy-layout/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini new file mode 100644 index 00000000000..f0403ab2cb8 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini @@ -0,0 +1,9 @@ +[send-on-deactivate-with-background-sync.tentative.https.window.html] + [fetchLater() does send on page entering BFCache even if BackgroundSync is on.] + expected: FAIL + + [fetchLater() with activateAfter=0 sends on page entering BFCache if BackgroundSync is on.] + expected: FAIL + + [fetchLater() with activateAfter=1m does send on page entering BFCache even if BackgroundSync is on.] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini new file mode 100644 index 00000000000..31590bbd841 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini @@ -0,0 +1,4 @@ +[order-in-bfcache-restore-iframe.html] + expected: TIMEOUT + [pagereveal event in iframe fires and in correct order on restoration from BFCache] + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini new file mode 100644 index 00000000000..f2af0d28013 --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini @@ -0,0 +1,3 @@ +[order-in-new-document-navigation-iframe.html] + [pagereveal event fires and in correct order on new-document navigation in an iframe] + expected: FAIL diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini index d6188c03424..7a5fcb79165 100644 --- a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_4.html.ini +++ b/tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_5.html.ini @@ -1,3 +1,3 @@ -[traverse_the_history_4.html] +[traverse_the_history_5.html] [Multiple history traversals, last would be aborted] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini new file mode 100644 index 00000000000..3e854890a7f --- /dev/null +++ b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini @@ -0,0 +1,2 @@ +[svg-filter-lh-rlh.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini b/tests/wpt/meta-legacy-layout/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini index 2e74427b47e..ffb5beada75 100644 --- a/tests/wpt/meta-legacy-layout/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini +++ b/tests/wpt/meta-legacy-layout/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini @@ -1,6 +1,6 @@ [Document.currentScript.html] type: testharness - expected: CRASH + expected: TIMEOUT [Script script-exec] expected: NOTRUN diff --git a/tests/wpt/meta-legacy-layout/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini b/tests/wpt/meta-legacy-layout/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini index 2ef0896e3b3..8b8af2b9c2e 100644 --- a/tests/wpt/meta-legacy-layout/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini +++ b/tests/wpt/meta-legacy-layout/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini @@ -1,4 +1,3 @@ [document-base-url-window-initiator-is-not-opener.https.window.html] - expected: TIMEOUT [window.open() gets base url from initiator not opener.] expected: [FAIL, PASS, TIMEOUT] diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini index 66e6567502d..e5994e21efc 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini @@ -1,5 +1,5 @@ [iframe_sandbox_popups_escaping-1.html] type: testharness - expected: TIMEOUT + expected: CRASH [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini index 841bafc6eca..b83d68ddd33 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html.ini @@ -1,3 +1,3 @@ [iframe_sandbox_popups_escaping-2.html] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini index a6c31bc671e..eacbe5794ea 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini @@ -1,4 +1,5 @@ [iframe_sandbox_popups_escaping-3.html] type: testharness + expected: TIMEOUT [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini index ccdaf8d61b2..ff6467094b8 100644 --- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini +++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini @@ -1,3 +1,3 @@ [iframe_sandbox_popups_nonescaping-3.html] [Check that popups from a sandboxed iframe do not escape the sandbox] - expected: NOTRUN + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/mediasession/mediametadata.html.ini b/tests/wpt/meta-legacy-layout/mediasession/mediametadata.html.ini index 2a2b3e73c85..dc8ec67091e 100644 --- a/tests/wpt/meta-legacy-layout/mediasession/mediametadata.html.ini +++ b/tests/wpt/meta-legacy-layout/mediasession/mediametadata.html.ini @@ -41,3 +41,14 @@ [Test that the base URL of MediaImage is the base URL of entry setting object] expected: FAIL + [Test that MediaMetadata is read/write] + expected: FAIL + + [Test that MediaMetadata.artwork can't be modified] + expected: FAIL + + [Test that MediaMetadata.chapterInfo is Frozen] + expected: FAIL + + [Test that MediaMetadata.chapterInfo's artwork returns parsed urls] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini deleted file mode 100644 index b7b36c1d3a4..00000000000 --- a/tests/wpt/meta-legacy-layout/webmessaging/with-ports/018.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[018.html] - expected: TIMEOUT - [origin of the script that invoked the method, javascript:] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini deleted file mode 100644 index c7946fc91b4..00000000000 --- a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/017.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[017.html] - expected: TIMEOUT - [origin of the script that invoked the method, about:blank] - expected: TIMEOUT diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json index 124d021a511..d83c1f07de4 100644 --- a/tests/wpt/meta/MANIFEST.json +++ b/tests/wpt/meta/MANIFEST.json @@ -549,6 +549,17 @@ } }, "compositing": { + "background-blending": { + "crashtests": { + "bgblend-root-change.html": [ + "06db053574580316235397f9c98e2b9b017cfafe", + [ + null, + {} + ] + ] + } + }, "opacity-and-transform-animation-crash.html": [ "294a823cd8ee0b7e5f289d2b623d59c7ceaa9f18", [ @@ -2283,13 +2294,6 @@ {} ] ], - "padding-overflow-crash.html": [ - "163be06a91758492002a8505c346103cf0a0b4cc", - [ - null, - {} - ] - ], "position-relative-with-scrollable-with-abspos-crash.html": [ "f0699f2046089da69c04c0085a2622290b8827b7", [ @@ -2668,6 +2672,13 @@ ] ] }, + "li-without-ul-counter-crash.html": [ + "e95c675eea4639c39f8b3a7ff0447bbcc9808187", + [ + null, + {} + ] + ], "list-item-counter-crash.html": [ "fc8a38c628026dc190d81e27150d8ebabb130ae2", [ @@ -3850,6 +3861,13 @@ ] ], "crashtests": { + "computed-property-universal-syntax.html": [ + "b87f03b2df3d536ef2459d6498e0cd121bc4f06c", + [ + null, + {} + ] + ], "initial-in-audio-crash.html": [ "dfc2b850a51fcedc6d61af7a93430e2cda5c8954", [ @@ -3930,6 +3948,13 @@ {} ] ], + "get-computed-style-crash.html": [ + "60e097cc8d11518afeff76432d0b32e4bdd0a8af", + [ + null, + {} + ] + ], "highlight-painting-005-crash.html": [ "3f93fc3cbe4c7459cad625b0d363c5cdc6d130c5", [ @@ -4887,6 +4912,22 @@ {} ] ], + "navigation": { + "opt-in-without-frame-crash.html": [ + "01c4d723498b7b4f2d3ca5b37d536377d2fa30d6", + [ + null, + {} + ] + ], + "reload-crash.html": [ + "a2bf11b31dc28129382837d7dd75f37544a51911", + [ + null, + {} + ] + ] + }, "root-element-cv-hidden-crash.html": [ "890194b7c171ea7a42fd083567637aacee4fd877", [ @@ -19800,13 +19841,6 @@ {} ] ], - "text-overflow-017.html": [ - "561d4d0b6fe96195159ef15bdc877d3c1ae6c2dd", - [ - null, - {} - ] - ], "text-overflow-018.html": [ "848ebe690eb84406260daf7a1335822887490e61", [ @@ -19831,6 +19865,17 @@ ] ] }, + "css-view-transitions": { + "navigation": { + "transition-to-prerender-manual.html": [ + "7465065c5da0895d95e8a9f01135b0a243a5650e", + [ + null, + {} + ] + ] + } + }, "css-writing-modes": { "alt-display-vertical-001-manual.html": [ "2e9de77ccb0e24f562c9b3f5bf6bccc3acef8870", @@ -32667,6 +32712,45 @@ {} ] ], + "page-box-001-print.html": [ + "35c2f06c93bfa3f5f162d945393d7acbea1250dc", + [ + null, + [ + [ + "/css/css-page/page-box-001-print-ref.html", + "==" + ] + ], + {} + ] + ], + "page-box-002-print.html": [ + "3b87b6903dd321b1c56df812b6ef1458c3c4a8ce", + [ + null, + [ + [ + "/css/css-page/page-box-002-print-ref.html", + "==" + ] + ], + {} + ] + ], + "page-box-003-print.html": [ + "44cc13555b543b8a4d9db28dcac6282438f74c51", + [ + null, + [ + [ + "/css/css-page/page-box-003-print-ref.html", + "==" + ] + ], + {} + ] + ], "page-left-right-001-print.html": [ "044696fcca27ec7ebe18edab3053dfbb65af6bbc", [ @@ -32771,6 +32855,19 @@ {} ] ], + "page-margin-007-print.html": [ + "c2045d0dac22111a4e1ee209cc9b7cec86a5efd2", + [ + null, + [ + [ + "/css/css-page/page-margin-007-print-ref.html", + "==" + ] + ], + {} + ] + ], "page-margin-negative-print.tentative.html": [ "205a13f7a589ff0403641fc3f5c8d391cf209043", [ @@ -122001,6 +122098,32 @@ {} ] ], + "position-try-switch-from-fixed-anchor.html": [ + "904aa55180dafd92ed7526854d13edb1f7ae0406", + [ + null, + [ + [ + "/css/css-anchor-position/position-try-switch-from-fixed-anchor-ref.html", + "==" + ] + ], + {} + ] + ], + "position-try-switch-to-fixed-anchor.html": [ + "54fcb2e4df3d6155ca672ea067ca4180b2893173", + [ + null, + [ + [ + "/css/css-anchor-position/position-try-switch-to-fixed-anchor-ref.html", + "==" + ] + ], + {} + ] + ], "position-visibility-add-no-overflow.html": [ "de0647f88bedb93a886761080a72582e4a76f045", [ @@ -173305,6 +173428,19 @@ {} ] ], + "padding-overflow.html": [ + "163be06a91758492002a8505c346103cf0a0b4cc", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "percentage-descendant-of-anonymous-flex-item.html": [ "592b5212ea6e5bd787aa9aab0d7f1c16c78bc134", [ @@ -197952,7 +198088,7 @@ ] ], "counter-set-001.html": [ - "4e28367798ae65095b21094d2d5da777b57f4294", + "6ec53e3bfa12306db12ecdded3f6727053222094", [ null, [ @@ -198055,6 +198191,19 @@ {} ] ], + "counters-005.html": [ + "12908e64720863293bb71dd0867524921bf34273", + [ + null, + [ + [ + "/css/css-lists/counters-005-ref.html", + "==" + ] + ], + {} + ] + ], "counters-scope-001.html": [ "2ea72753bd984fe93db1872d5f90e72da6cd4966", [ @@ -204978,6 +205127,19 @@ {} ] ], + "mask-image-svg-viewport-changed.html": [ + "156317b2517d639b8521d510b7e5bf3c793273ed", + [ + null, + [ + [ + "/css/css-masking/clip-path/reference/green-100x100.html", + "==" + ] + ], + {} + ] + ], "mask-image-url-image-hash.html": [ "b1efc90818bec85d5022a9b908a14c2e0c35ff3b", [ @@ -221914,6 +222076,19 @@ {} ] ], + "pseudo-first-line.html": [ + "180420d98a4d94d5efd84cee8c83309fa060ffdb", + [ + null, + [ + [ + "/css/css-ruby/pseudo-first-line-ref.html", + "==" + ] + ], + {} + ] + ], "rb-display-001.html": [ "5149eb34a4686a38cdf347fbe6162df83a9403a6", [ @@ -233691,6 +233866,19 @@ {} ] ], + "collapsed-border-partial-invalidation-003.html": [ + "073f67e669da0b884c507c356a016e1ef229961f", + [ + null, + [ + [ + "/css/css-tables/collapsed-border-partial-invalidation-003-ref.html", + "==" + ] + ], + {} + ] + ], "collapsed-border-positioned-tr-td.html": [ "d5c6094497268941071e516073a54f38e5900d45", [ @@ -246515,7 +246703,7 @@ ] ], "break-spaces-008.html": [ - "4612996c52cb6039fb74991ae53539b991ca22cb", + "dc9f5934f413df2406995cd7107a55c03873bb52", [ null, [ @@ -247308,7 +247496,7 @@ ] ], "break-spaces-with-ideographic-space-008.html": [ - "7102439d4697e9d49e29afbc52ab9d2040c95af8", + "d222e1b75350b19ff40f0ab65dc5ecb4ea9b0510", [ null, [ @@ -249711,6 +249899,23 @@ {} ] ], + "text-wrap-nowrap-001.html": [ + "94437df6deeb3ddcf73d7732c046901cb4b3842d", + [ + null, + [ + [ + "/css/css-text/white-space/reference/text-wrap-nowrap-001-ref.html", + "==" + ], + [ + "/css/css-text/white-space/reference/text-wrap-nowrap-001-mis-ref.html", + "!=" + ] + ], + {} + ] + ], "textarea-break-spaces-001.html": [ "ad81e99768f9816c6e8a659c13aed81c4f22d940", [ @@ -267748,6 +267953,19 @@ } ] ], + "transform3d-preserve3d-014.html": [ + "e8d7a4805b001dda187ab1f45b30e2ddd7df2e43", + [ + null, + [ + [ + "/css/css-transforms/transform-lime-square-ref.html", + "==" + ] + ], + {} + ] + ], "transform3d-rotate3d-001.html": [ "93a46f1c6ab038b92e9bbbe3356d219cd2f1bdf4", [ @@ -286986,6 +287204,368 @@ {} ] ], + "names-are-tree-scoped.html": [ + "efca07e209da39040ee6a954480801e1280d427e", + [ + null, + [ + [ + "/css/css-view-transitions/names-are-tree-scoped-ref.html", + "==" + ] + ], + {} + ] + ], + "navigation": { + "at-rule-opt-in-auto.html": [ + "8993cf1a6772e5fc72908482539b5fb9e4f43e61", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html", + "==" + ] + ], + {} + ] + ], + "at-rule-opt-in-none-in-new.html": [ + "2aecb7b91355086acba7908c9069716415aa5f38", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-none-ref.html", + "==" + ] + ], + {} + ] + ], + "at-rule-opt-in-none-in-old.html": [ + "b5b0b3a1104d1eae0e7a7ae68728136ca9d99d51", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-none-ref.html", + "==" + ] + ], + {} + ] + ], + "chromium-paint-holding-timeout.html": [ + "83596940fa420005492b38def7e8cd49d0252632", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/chromium-paint-holding-timeout-ref.html", + "==" + ] + ], + {} + ] + ], + "navigation-auto-excludes-reload.html": [ + "c0fb61a4b0aa85848f55332e5d491798854853b0", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/navigation-auto-excludes-reload-ref.html", + "==" + ] + ], + {} + ] + ], + "no-view-transition-with-cross-origin-redirect.sub.html": [ + "8780310af2ff2942de48a824919c8c4b950519cb", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect-ref.html", + "==" + ] + ], + {} + ] + ], + "opt-in-removed-during-transition.html": [ + "eb2295f2f0306be34afcbbe17f0ca726c3a7eb8e", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/opt-in-removed-during-transition-ref.html", + "==" + ] + ], + {} + ] + ], + "pagereveal-finished-promise.html": [ + "baac948bac431a2c0a9774b098b137bc1a93d520", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/pagereveal-finished-promise-ref.html", + "==" + ] + ], + {} + ] + ], + "pagereveal-ready-promise.html": [ + "65b370c9c052e07de27c62e072850792a5a4c2ab", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/pagereveal-ready-promise-ref.html", + "==" + ] + ], + {} + ] + ], + "pagereveal-setup-transition.html": [ + "7407824ea73d5649028cae7fe3838676fece1577", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/pagereveal-setup-transition-ref.html", + "==" + ] + ], + {} + ] + ], + "pageswap-fired-before-old-state-capture.html": [ + "8ce791bcaecfdc181da3c34a644d1014fe806e36", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture-ref.html", + "==" + ] + ], + {} + ] + ], + "prerender-removed-during-navigation.html": [ + "d261b0df5520fc9b5ce6deb5112138111e3a5899", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/prerender-removed-during-navigation-ref.html", + "==" + ] + ], + {} + ] + ], + "root-and-nested-element-transition.html": [ + "457f263bf955eabd43bd38c1dbabeafcbc89f7b2", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-and-nested-element-transition-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + [ + "/css/css-view-transitions/navigation/root-and-nested-element-transition.html", + "/css/css-view-transitions/navigation/root-and-nested-element-transition-ref.html", + "==" + ], + [ + [ + 0, + 2 + ], + [ + 0, + 2000 + ] + ] + ] + ] + } + ] + ], + "root-element-transition-iframe-cross-origin.sub.html": [ + "51a7c926e6d04088285e83bc1d492fdf071406cb", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-iframe-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-iframe-with-startVT-on-main.html": [ + "b7ef426121c3435587f8cb33d05957e9aab019e9", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-iframe.html": [ + "a320d92c698c0b0f287de1d70e217d0e254b1665", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-iframe-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-no-opt-in-on-new.html": [ + "5cec74aac2d768ef065ae88bf73b9b805e98f812", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-no-opt-in-on-old.html": [ + "9d834ffd6a1c4815dc9b71e12c8eb3c0e525a78e", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-opt-in-removed-on-new.html": [ + "46daf95e5e4e1f31229692aea8b10504311a9ec0", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition-opt-in-removed-on-old.html": [ + "5fab64a306712d2bdf81facba96be6038201adde", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html", + "==" + ] + ], + {} + ] + ], + "root-element-transition.html": [ + "fb293b83994cc51fdd60e96fd08789801b2666d8", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/root-element-transition-ref.html", + "==" + ] + ], + {} + ] + ], + "transition-to-prerender.html": [ + "bdc66708970bda64e24f0f64b6a5525d0a8947ff", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/transition-to-prerender-ref.html", + "==" + ] + ], + {} + ] + ], + "with-types": { + "at-rule-opt-in-auto-with-types-mutable.html": [ + "307e8a8b747eabce19d0e3dac100d0c040512c09", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html", + "==" + ] + ], + {} + ] + ], + "at-rule-opt-in-auto-with-types-no-cascade.html": [ + "5fec29db89c7d833cdf3bf325bf3b20c6e065f97", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html", + "==" + ] + ], + {} + ] + ], + "at-rule-opt-in-auto-with-types.html": [ + "87503d9f1e360cffd85cfb0369ec7f3b305ff05f", + [ + null, + [ + [ + "/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html", + "==" + ] + ], + {} + ] + ] + } + }, "new-and-old-sizes-match.html": [ "70b6515fb5b8189c925127636f7860ae424f0284", [ @@ -288785,6 +289365,123 @@ {} ] ], + "view-transition-types-match-early-mutation.html": [ + "24737d9050ef6d53be5a44c553faa2901d014928", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-match-early.html": [ + "b62e8a716795367d5b34f33c190ffd7be4b6ad78", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-match-late-mutation.html": [ + "dbceba111ee416e078948c0042f6e8660c764ba4", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-matches.html": [ + "ef15d97fb997e1dd744bcc42108e68c750b74d68", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-matches-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-removed.html": [ + "fe458efafd302dbe3b6b4d00e58cb1f19ee1a761", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-reserved-mutation.html": [ + "ba8b5e1e3c8899225a1d63a4b90900b189b247fb", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-reserved-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-reserved.html": [ + "1dca3774aa4e1feb3fe0eb5d8d1a52aceebf86a7", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-reserved-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-stay.html": [ + "dc738e6912c01850b21a93c9e8fffe925c1502b2", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], + "view-transition-types-universal-match.html": [ + "534c144ecf0c3b7dc14fd915782f8daeef93a18c", + [ + null, + [ + [ + "/css/css-view-transitions/view-transition-types-one-green-square-ref.html", + "==" + ] + ], + {} + ] + ], "web-animations-api-parse-pseudo-argument.html": [ "dfaac62c17f99e7465a32c452eaed807f289cac6", [ @@ -317349,6 +318046,19 @@ } ] ], + "svg-filter-lh-rlh.html": [ + "b61193fb9fdd107319d98ee8429970221dbfd549", + [ + null, + [ + [ + "/html/canvas/element/manual/filters/svg-filter-lh-rlh-expected.html", + "==" + ] + ], + {} + ] + ], "tentative": { "canvas-filter-object-blur.html": [ "9fe7ef120c5cc73f3f3bfd1278d9d7dc025f402f", @@ -325879,6 +326589,19 @@ {} ] ], + "input-password-background-suppresses-appearance.html": [ + "3c85b100a1dc74e94d0a7f7e187da951d7476209", + [ + null, + [ + [ + "/html/rendering/widgets/input-password-background-suppresses-appearance-ref.html", + "==" + ] + ], + {} + ] + ], "input-radio-disabled-checked.html": [ "3ac2a37199b653ab4e1dd5d098bce9bb9e83dc44", [ @@ -343272,7 +343995,7 @@ }, "support": { ".azure-pipelines.yml": [ - "36e745a87f151b68483a906b2a52b622e5030f88", + "c018c592d1db33277a6499a8a20bc0f304d221fd", [] ], ".gitattributes": [ @@ -347790,6 +348513,10 @@ "7695c4a33e328a01434196d5fa19af84e04bc57b", [] ], + "WEB_FEATURES.yml": [ + "ae8464657b14e41a7da2513f65cf39920496c689", + [] + ], "permissions-policy": { "compute-pressure-allowed-by-permissions-policy.https.html.headers": [ "76185cbb2de93a463c1fb7930343a73cbb31f99a", @@ -368186,7 +368913,7 @@ [] ], "cookie-test.js": [ - "a909e4d72facf95760ef35c96efbb426bbc9c8e0", + "8299c4731786dcf6ada011820e008d670a4df78d", [] ], "cookie.py": [ @@ -368546,6 +369273,10 @@ "a40fc100eee697ed7dcd451626409af18606442e", [] ], + "manifest_check_disclosure_shown_false.json": [ + "47ca63edc4fc96f4d563beba7e872ae5d47461c1", + [] + ], "manifest_check_same_site_strict.json": [ "d7304159834804c417f498acebc45f59e588dcbb", [] @@ -368642,6 +369373,10 @@ "7ec81c390a9ea116e0a1809e08159a1d1c40e5a1", [] ], + "token_check_disclosure_shown_false.py": [ + "f4b732053ff0f2d5545c3602d701d92702e111af", + [] + ], "token_check_same_site_strict.py": [ "4e55bf27f610032b30eb3278ddd0f7db4716efef", [] @@ -386473,6 +387208,14 @@ "4d7de12447c8297b8f0fc04338d80a028a3e9798", [] ], + "position-try-switch-from-fixed-anchor-ref.html": [ + "72026a2f63e0bef3ba9481780946f1f9d1148a5a", + [] + ], + "position-try-switch-to-fixed-anchor-ref.html": [ + "254cbf3df455dad3c235a7880463f5a275e2957b", + [] + ], "position-visibility-anchors-valid-ref.html": [ "96b4e865512c2adf1215e7aaae43bc1053bd6356", [] @@ -389575,16 +390318,12 @@ "21086fc62185a65da89513daf0c8bc1b66688064", [] ], - "LICENSE": [ - "d47f50cca8a2d9dc40dee384ae256f8aecf44e0a", - [] - ], "META.yml": [ "f5030db7cb57a09012f740fe54ae26d466bcef24", [] ], "WEB_FEATURES.yml": [ - "8910deab28b0f600ac25a1ae11d0f8d2678cf786", + "cbb0f23ede228cea0304ad3c7de5e9ca41a047d4", [] ], "a98rgb-003-ref.html": [ @@ -395126,7 +395865,7 @@ [] ], "WEB_FEATURES.yml": [ - "5e69c923abf5bfb8d62b862e956b2a14c0b031c4", + "6739fa2d06a8a032fc2f3816aaa5bb3d0afef434", [] ], "alternates-order-ref.html": [ @@ -396085,7 +396824,7 @@ ], "parsing": { "WEB_FEATURES.yml": [ - "6a24d269b48134bf8e4e99f8e805a53fae91d1e4", + "a3bc09cb1f1b9a4889dd122d896b19706646f295", [] ], "ahem-ex-500.otf": [ @@ -404267,6 +405006,10 @@ } }, "css-highlight-api": { + "WEB_FEATURES.yml": [ + "0ce5201312974300d33d2c95171640f60b1bbc0e", + [] + ], "highlight-priority-painting-ref.html": [ "1865f1e104917ebeb3d6e9cb53de06977ea8623c", [] @@ -404471,6 +405214,10 @@ "8d3b9472b2c9a2ee88dc97f907f9d16eb4fa3755", [] ], + "WEB_FEATURES.yml": [ + "0a1af1998309bacf9fdfeb69f0a33f662eac20ea", + [] + ], "color-stop-currentcolor-ref.html": [ "7686a3b16ed8b9ebf3f8ffcbecd4bdb5e1225bfe", [] @@ -405544,6 +406291,10 @@ [] ], "baseline-source": { + "WEB_FEATURES.yml": [ + "f399a6dc6f73dccf050094c4b646cc0125ce4167", + [] + ], "baseline-source-inline-box-ref.html": [ "ef3077970a298a026ffaa2e0584ed5220ae10f59", [] @@ -406052,7 +406803,7 @@ [] ], "counter-set-001-ref.html": [ - "301197904a5af79eb5024bb7d97ac161e5ada3ad", + "2b5eb90ccfc61af30e95e539a34f85ac8a8b58cd", [] ], "counter-set-002-ref.html": [ @@ -406083,6 +406834,10 @@ "070c7047386818eb8b6d8b08faac8516b6e70018", [] ], + "counters-005-ref.html": [ + "232bab76a106674358e024f9e0bb97993aac476a", + [] + ], "counters-scope-001-ref.html": [ "e7c3abf51014e2f698c42a1de2830bff55da6461", [] @@ -406345,6 +407100,16 @@ "7f92755b092845d3d550568e0572453801451f3d", [] ], + "WEB_FEATURES.yml": [ + "76ea5c208e91c63632413ea3f3e8bc3d4dee0fe8", + [] + ], + "animations": { + "WEB_FEATURES.yml": [ + "758ef35275eeacc96b6e584f672f86c4b170e0e1", + [] + ] + }, "clip": { "clip-filter-order-ref.html": [ "fe9511a8dfce2b4f597597871abccd03727f136f", @@ -406920,6 +407685,10 @@ } }, "mask-image": { + "WEB_FEATURES.yml": [ + "b5bbd438dac187e92af375c0933ed9a27783a6a7", + [] + ], "mask-clip-1-ref.html": [ "3925bd4f1db4fa25b93e9e121afdf0940ae0bd4b", [] @@ -407205,6 +407974,12 @@ ] } }, + "parsing": { + "WEB_FEATURES.yml": [ + "0837d0ddf902333b45942311cc585e6e385af634", + [] + ] + }, "resources": { "blue-20.png": [ "c464c75eeca3ead65c00e7c26150d97ad58da5c3", @@ -408321,6 +409096,10 @@ "b9ba7acd150e5022de5c5208cd7f5f7d4dde93c3", [] ], + "WEB_FEATURES.yml": [ + "81358de0c75128c99ae0feaf441520f2c8a5c280", + [] + ], "clip-001-ref.html": [ "9ccdbf93c615f6078b82add5362e6032e9efe583", [] @@ -409071,6 +409850,18 @@ "d39bd738507490b5590afa7a4eb6cce9766b63bc", [] ], + "page-box-001-print-ref.html": [ + "d9ab323877f7144062ce908345d32e57900cc2d6", + [] + ], + "page-box-002-print-ref.html": [ + "e1ee4ab5d148662f6ea6af9f906caed7e821b207", + [] + ], + "page-box-003-print-ref.html": [ + "e1ee4ab5d148662f6ea6af9f906caed7e821b207", + [] + ], "page-left-right-001-print-ref.html": [ "1eb011bed8a0dde4a65494d54fc2e2bd9a042080", [] @@ -409103,6 +409894,10 @@ "fe7a2c66db21b005464b89a5436894c67b95ad58", [] ], + "page-margin-007-print-ref.html": [ + "20d16df19de9dc0ad95f5b17344cd21210983c18", + [] + ], "page-margin-negative-print-ref.tentative.html": [ "9e816c12fb7ddcd94cdfaf1e910f6146e70c05c6", [] @@ -410207,6 +411002,10 @@ "200d92cc590880be73f63d9e6e00594471700d46", [] ], + "WEB_FEATURES.yml": [ + "5dd44e39c8bc48241907d935ae3c3ef2fb1dbce5", + [] + ], "active-selection-051-ref.html": [ "77e2d2817f66adb707e506c46a1eed948a2e92e3", [] @@ -411039,6 +411838,10 @@ "8c470232876d5a3d3b0c988f2cfef0936d142a10", [] ], + "pseudo-first-line-ref.html": [ + "55c96fb2d3c45e680549c8b500ecaf28d297c311", + [] + ], "reference": { "improperly-contained-annotation-001-ref.html": [ "72a55541bcba241cdced59588e46118a40c8528c", @@ -411383,6 +412186,10 @@ "df776353a31f1cef3abe9bc9d195da9be5da2510", [] ], + "WEB_FEATURES.yml": [ + "d285b01e8687b5bf44c33e6dd0fe0ad49f115b7a", + [] + ], "no-red-ref.html": [ "061454fb67a67b9b5b1d62b2603731da3988a3d9", [] @@ -411473,7 +412280,7 @@ "css-scroll-snap-2": { "resources": { "common.js": [ - "8dce29474d8f6d4e2a1215d6112f0deea261f907", + "d95b605120b7f85df08d7d9bceaa20f9d5c70341", [] ], "user-scroll-common.js": [ @@ -413457,6 +414264,10 @@ "d89389a6dc3bc2d86a17ea6f22857feaff6119fb", [] ], + "collapsed-border-partial-invalidation-003-ref.html": [ + "2b19a838143bdd1602cb252221f68bf2fc84ca70", + [] + ], "collapsed-border-positioned-tr-td-ref.html": [ "b3099017699bb83d78bf0492c9c451ccd1e034bf", [] @@ -415423,7 +416234,7 @@ }, "parsing": { "WEB_FEATURES.yml": [ - "e06782e8f5b477831cdb06a2f93d0dc7fc49af1b", + "fa39887d52807e3c0753fc1f4b20dc6cbed864fd", [] ] }, @@ -416658,6 +417469,10 @@ ] }, "white-space": { + "WEB_FEATURES.yml": [ + "89253912e8520ad5496e4a9c5da747f9d16bcf9d", + [] + ], "lone-cr-001-ref.html": [ "943daefee058239e51eef2a4c6b1b46471508696", [] @@ -416863,6 +417678,14 @@ "401e35e2f1f8c534487782df003078b1a53b6e36", [] ], + "text-wrap-nowrap-001-mis-ref.html": [ + "ca73318ecf3bae78643e5a754da54e8c8dc313d2", + [] + ], + "text-wrap-nowrap-001-ref.html": [ + "bd5b231d83126b01720fd5d2d3c57f8d920acdf5", + [] + ], "textarea-pre-wrap-001-ref.html": [ "31070ea92815e4d3a3ece48ed69da03de02f671e", [] @@ -418342,7 +419165,7 @@ [] ], "WEB_FEATURES.yml": [ - "ca13ab5ae1bedbcbdd995938b62fb5768032c999", + "bb44025b80bbd77cbd32483e2212b1c975426539", [] ], "add-child-in-empty-layer-ref.html": [ @@ -418351,7 +419174,7 @@ ], "animation": { "WEB_FEATURES.yml": [ - "831086f99e9f8fd220dbb2264f46945c7a88c1b3", + "9116c202c42c02bf586cd6a92e7c618b65d2e2f4", [] ], "canvas-webgl-translate-in-animation-ref.html": [ @@ -418552,6 +419375,10 @@ [] ], "individual-transform": { + "WEB_FEATURES.yml": [ + "8fa77e513de722f44e607829f6e92272ea533736", + [] + ], "animation": { "individual-transform-combine-ref.html": [ "7c8eb206a9fb7fc9a4cf53f5282cfc1fb251d450", @@ -418601,7 +419428,7 @@ ], "parsing": { "WEB_FEATURES.yml": [ - "831086f99e9f8fd220dbb2264f46945c7a88c1b3", + "1bf7e23a0b465c5eb50eb043c140032ee1524e4a", [] ] }, @@ -419819,10 +420646,20 @@ "f72f11dccae5e8b63de6148573723f86fbb4c708", [] ], + "WEB_FEATURES.yml": [ + "4da279daa391f56226f7c324790de8dfe6277514", + [] + ], "inherit-background-color-transition-ref.html": [ "b7a5824836e157f21649fabe12a701b860e04c9f", [] ], + "parsing": { + "WEB_FEATURES.yml": [ + "4da279daa391f56226f7c324790de8dfe6277514", + [] + ] + }, "reference": { "transition-test-ref.html": [ "d9d91ec9da9e90feaf164632b22cb285f10a76ca", @@ -420263,6 +421100,12 @@ "e66e037ed020c5164a8f6adfe41e4e3ffcc3841b", [] ], + "parsing": { + "WEB_FEATURES.yml": [ + "b4ae339c2f3301bc1845c39923c05095d9e48499", + [] + ] + }, "pointer-events-no-scrollbars-001-ref.html": [ "096eb16229039740135314ef3b0a6ad1bd74c3d3", [] @@ -421416,7 +422259,7 @@ [] ], "WEB_FEATURES.yml": [ - "dc7331ab9545223f7c420b54be38a929498661cc", + "526bb67def54a02a8e268cd0393451a27c2c7989", [] ], "attr-notype-fallback-ref.html": [ @@ -422369,6 +423212,150 @@ "7d513e282df217e0299d39888ab02afb64b92717", [] ], + "names-are-tree-scoped-ref.html": [ + "62419b07ee148486917f96b7b1eb8ffdeae7c2ca", + [] + ], + "navigation": { + "at-rule-opt-in-auto-ref.html": [ + "be8cc501cf09a01105a8f0c89d8e47b91dd66c01", + [] + ], + "at-rule-opt-in-none-ref.html": [ + "59e3342daebb77a8e484add21626472c01b396ab", + [] + ], + "chromium-paint-holding-timeout-ref.html": [ + "90267e3a84a34157078d1ad890710ea8059a75da", + [] + ], + "navigation-auto-excludes-reload-ref.html": [ + "ed12194c3107880808952a165fe591c6e5fa490b", + [] + ], + "no-view-transition-with-cross-origin-redirect-ref.html": [ + "91f24f877bd679e62ecdb84017049ec2d13d9290", + [] + ], + "opt-in-removed-during-transition-ref.html": [ + "f2b0dbfd338ce0ff60b5d6e834c8c9942e55fbc7", + [] + ], + "pagereveal-finished-promise-ref.html": [ + "64aa26f6547f259a854e4766677d19205248c1b5", + [] + ], + "pagereveal-ready-promise-ref.html": [ + "0c1ed2765651a2173f85b61ed5876d9fb86bcc52", + [] + ], + "pagereveal-setup-transition-ref.html": [ + "cda9820d536796a4746292873248fb969f6f7e1f", + [] + ], + "pageswap-fired-before-old-state-capture-ref.html": [ + "bda333066a3f9a2192d2c507121ef472d1162412", + [] + ], + "prerender-removed-during-navigation-ref.html": [ + "cbcfd19d9505f4b69ae8c367e8a489a6ef729505", + [] + ], + "resources": { + "at-rule-opt-in-auto-with-types-mutable.html": [ + "ef4a540d0407540dfe57f46ef0cc31d6c0460049", + [] + ], + "at-rule-opt-in-auto-with-types.html": [ + "b30d3791d6e9e0306ebd24307a97d53886f48318", + [] + ], + "at-rule-opt-in-auto.html": [ + "e887d4b21075e82e936701408c2c652f009498af", + [] + ], + "at-rule-opt-in-none.html": [ + "bf5a73c73ee014ecf5777f77b9282d8f947f58af", + [] + ], + "chromium-paint-holding-timeout.html": [ + "3964199c54cd7230d517b2d676e1a4dbea9067b4", + [] + ], + "common.js": [ + "cbe023a3d9ed808dcab2bc9b3b1a769ca6ff68cc", + [] + ], + "opt-in-style.css": [ + "9aac2b4e85b4255236246fbfb89df8f17dc0f592", + [] + ], + "opt-out-style.css": [ + "f01d587ddadb28049f07ae8f40fa937c479a721b", + [] + ], + "outbound-before-render.html": [ + "0815c3b3d7604c6002323f504a129679723e5cce", + [] + ], + "render-blocking-stylesheet.py": [ + "15ae6aba6ff021eb8c463d3bb050ca5020a9fdef", + [] + ], + "root-and-nested-element-transition.html": [ + "c572ce9798bc52447afb5532a5f652d6443d1ceb", + [] + ], + "root-element-transition-iframe-inner-result.html": [ + "65f14843d9cd3ca15da328cbb854fbd5c7d4aec9", + [] + ], + "root-element-transition-iframe.html": [ + "7f008442f77ae2364b71f92b97b46a6f68ac8c3d", + [] + ], + "root-element-transition-no-opt-in.html": [ + "82d2bdc5597b6ac1a1287133b2a0ac4625aa6599", + [] + ], + "root-element-transition-opt-in-removed.html": [ + "83f5d76c163575a98ce99fb9a73da3f2c5429691", + [] + ], + "root-element-transition.html": [ + "af68ba0074243f836500193b3b58cfa4a131382a", + [] + ], + "transition-to-prerender.html": [ + "63f810a26368ab446b05c0562894b8e0590531ba", + [] + ] + }, + "root-and-nested-element-transition-ref.html": [ + "a0bb6180c4f8d95801605aa9eb1b570588f86e35", + [] + ], + "root-element-transition-iframe-ref.html": [ + "576689af320e98fa03bc15bfb7adfc4c7ee04a62", + [] + ], + "root-element-transition-iframe-with-startVT-on-main-ref.html": [ + "f350545c7f759516675831fe8565ce481a0bd5d8", + [] + ], + "root-element-transition-no-opt-in-ref.html": [ + "d38b8aa4cd7e3ae877b55b8b030131cc91926739", + [] + ], + "root-element-transition-ref.html": [ + "65f14843d9cd3ca15da328cbb854fbd5c7d4aec9", + [] + ], + "transition-to-prerender-ref.html": [ + "7df899fdca151dd273063323733c0c20fedb3bb3", + [] + ] + }, "new-and-old-sizes-match-ref.html": [ "79e89801391530b6fb074545a92db68493667f05", [] @@ -422675,6 +423662,18 @@ "e86fa3f3e21e9a8df3a28ba9ca60332a4d1b6ab7", [] ], + "view-transition-types-matches-ref.html": [ + "80b1c6a1000fbc5f0bc06ec78b9523a6722c8b37", + [] + ], + "view-transition-types-one-green-square-ref.html": [ + "4e66b92bc49d10857323c2b1f39142f3f3eec008", + [] + ], + "view-transition-types-reserved-ref.html": [ + "9195d0811477c7cfe74f83d66901e926a505a5df", + [] + ], "web-animations-api-ref.html": [ "d71d6e1375e01a3decfc7e74c9f3165ce9c0af1a", [] @@ -426707,6 +427706,10 @@ "20835b48397f136a30b82a62654d389cad326315", [] ], + "WEB_FEATURES.yml": [ + "0a436801cb7fe8709c444d00a70288866a3055da", + [] + ], "animation": { "reftests": { "offset-path-path-interpolation-ref.html": [ @@ -427944,6 +428947,10 @@ "ElementInternals-reportValidity-bubble-notref.html": [ "dda233296569d8ec855855434a4947d8a847a2c6", [] + ], + "WEB_FEATURES.yml": [ + "e40f6e12ae43b8399cf2f67824609c9050460812", + [] ] }, "pseudo-class-defined-print-ref.html": [ @@ -428111,7 +429118,7 @@ }, "direct-sockets": { "META.yml": [ - "85c05e8c834847aa6a1d5aa1f1faa8c60a7ea9ca", + "ace03410a2394cd404607607daa070ae5f00915f", [] ], "README.md": [ @@ -428119,11 +429126,15 @@ [] ], "disabled-by-permissions-policy.https.sub.html.headers": [ - "ba6f09f55b393880aadf79a41d9220313ed294c8", + "661a357effcfdf7f25a4974e151818ac3a9ec464", + [] + ], + "tcp_socket.https.html.headers": [ + "177feb102dbffb11e5ff7bee147f1834cb771e74", [] ], - "disabled-by-permissions-policy.js": [ - "a27d1ddf497a7fa0ccd8ecd40b94732a831da97c", + "udp_socket.https.html.headers": [ + "177feb102dbffb11e5ff7bee147f1834cb771e74", [] ] }, @@ -433163,6 +434174,10 @@ "34864d4a4b6bd911f496026ada7bdc41ba3a6905", [] ], + "WEB_FEATURES.yml": [ + "fb48eaa3112102a1037291b2be4a17f87df51e91", + [] + ], "report.https.sub.html.sub.headers": [ "1ec5df78f30183b07f2739f180354d87e4572c5b", [] @@ -433801,11 +434816,11 @@ [] ], "bidding-logic.sub.py": [ - "e17f2c2c75d294d7cdf53d3f0afb2826bae10813", + "8c0539d43c83a72b57498b0ec5c4f16d2fb26599", [] ], "decision-logic.sub.py": [ - "3a23f981620d6a467a293333b3eff5ee1df098fc", + "545c7e5e4f85be20eaab38c7ede42e7be926dfd0", [] ], "direct-from-seller-signals.py": [ @@ -433825,11 +434840,11 @@ [] ], "fledge-util.sub.js": [ - "a7d0f63830d63bebf964aed74038b1fbbb2a75e7", + "148613eef8d903352f84ef30012a5654d82a3fc6", [] ], "fledge_http_server_util.py": [ - "162c93e8b06328437253e106183a48c398121c75", + "92733eedf43b8d5bf84470ffa10321c3cb56ae2e", [] ], "incrementer.wasm": [ @@ -433849,7 +434864,7 @@ [] ], "request-tracker.py": [ - "3514741f6343e4f27b55d1838ee43857a354fafe", + "dea8427266f1245e297795a69538b3a4f0007af2", [] ], "set-cookie.asis": [ @@ -433857,7 +434872,7 @@ [] ], "subordinate-frame.sub.html": [ - "f5b1ef995956fbf5fa7359b4d23338ad0185d826", + "ea1f0c44d6286a3188acab7a83d0c2411bc23f48", [] ], "subordinate-frame.sub.html.headers": [ @@ -433865,11 +434880,11 @@ [] ], "trusted-bidding-signals.py": [ - "955a7c0bdfadbbcb315dfc7902dd26a109970680", + "5a89e3b602565170c5e5eb3427eea71c36579dbe", [] ], "trusted-scoring-signals.py": [ - "ce53e762958e55af08c9330271a250c7bf95360f", + "934d2e9129d04a511b44540a6d326eff4d2b75f3", [] ], "update-url.py": [ @@ -435697,6 +436712,10 @@ ], "pagereveal": { "resources": { + "iframe.html": [ + "a1c1c6233282b7d94aafe59ebf4ffe9b5f121f0c", + [] + ], "order-in-prerender-activation-popup.html": [ "78989adc172997dd379ea6e7aee578be45702b79", [] @@ -438798,6 +439817,14 @@ "caf6b53ce39f2fa61c43b35f6c91c6954e7350d6", [] ], + "svg-filter-lh-rlh-expected.html": [ + "d183f6940deb4399186770a4e97bb136e05f5f61", + [] + ], + "svg-filter.svg": [ + "a783a3eb15dbbab1395539e1d6597551c0bd62da", + [] + ], "tentative": { "canvas-filter-object-blur-expected.html": [ "ae8911b2de39e593c2ef262ed9cd5eaa70b5bf0c", @@ -446268,6 +447295,10 @@ ] }, "widgets": { + "WEB_FEATURES.yml": [ + "b4ae339c2f3301bc1845c39923c05095d9e48499", + [] + ], "appearance": { "appearance-animation-002-ref.html": [ "fab70234d2be44ea73de81456b3dff7aab44ad74", @@ -446348,6 +447379,10 @@ "5b2ea91fe5fa635c221adc8801605f3b14fb66c7", [] ], + "input-password-background-suppresses-appearance-ref.html": [ + "33e0e6ac161007679a51f435951f579ab5dfaf09", + [] + ], "input-radio-disabled-checked-notref.html": [ "987e03cd92d7824e61cc75bbd723bd9583ab8fe1", [] @@ -447713,6 +448748,10 @@ [] ], "attributes-common-to-form-controls": { + "WEB_FEATURES.yml": [ + "457c9040053508f0a7d29ec4e1b94b53e3b1be04", + [] + ], "resources": { "dirname-iframe.html": [ "b5ed7e3d9a717746d9653c7d5f867f3acbf3e47f", @@ -450376,7 +451415,7 @@ ], "pseudo-classes": { "WEB_FEATURES.yml": [ - "055a5fb4a302b72585d2ca80a849bd653a4d0666", + "2877344b6493b39b7019964a352efdeb4a1b58d4", [] ], "focus-iframe.html": [ @@ -453077,7 +454116,7 @@ "reftest": { "legacy": { "fuzzy-ref-2.html.ini": [ - "cdfd9736c54bdf645a776caaa93d497fe937a04e", + "e78d0b4315db33a0eec9c8a1d7879cb83dd43f4e", [] ], "reftest_and_fail_0-ref.html.ini": [ @@ -453089,24 +454128,20 @@ [] ], "reftest_fuzzy_chain_ini.html.ini": [ - "d3776e243e460f438bcaddd1169ccbcc937b6e33", + "6c8e46ceafd81554635139d8308b41b438e75369", [] ] }, - "reftest_fuzzy_1.html.ini": [ - "44f185357bc55366f4ac1825e16c91e356ffe2f6", - [] - ], "reftest_fuzzy_ini_full.html.ini": [ - "d682550d53eaeab5ff70cbabb09e1ff7a7bdb8d2", + "0ea76527da400b3c4e1c9dbe0ea9b8c837e3eeb9", [] ], "reftest_fuzzy_ini_ref_only.html.ini": [ - "4437fceff899b84e9f316cf6d0e6fb300dc503d7", + "8e321bdb90291dbc3427eb2741643c7e42cff8fc", [] ], "reftest_fuzzy_ini_short.html.ini": [ - "27e3290e6fbc90ba0b08816924924fe4bc0b8922", + "4a3cb610fac473594194f88714696b4cc7019c8f", [] ], "reftest_match_and_mismatch-0.html.ini": [ @@ -453264,7 +454299,7 @@ ] }, "click_iframe_crossorigin.sub.html.ini": [ - "c0ca25ab6572190cea7793e92514edc3cbbd10c2", + "aa94652ad763060f10aba1e03af806035d29ecd1", [] ], "file_upload.sub.html.ini": [ @@ -455140,7 +456175,7 @@ ] }, "lint.ignore": [ - "61bca89ddc9a88ee8c1590cb37715595d7222bce", + "14e02983f753d491299396b65f2b43dc55119ac5", [] ], "loading": { @@ -459396,6 +460431,10 @@ "fd10e7d15abd6ed0f4e76581b225ca1e9a248c79", [] ], + "WEB_FEATURES.yml": [ + "384fd1a3e54bc7784406de3651be747a69c99bad", + [] + ], "avoid-prefetching-on-text-plain-inner.html": [ "518e2465418ad6aaecc5a6fb3957eeef38259240", [] @@ -461955,10 +462994,6 @@ "8fa27bc56a1d828e96e4a4b6a7276c9f1afb6250", [] ], - "mock-direct-sockets.js": [ - "6d557f7a01530664d619c1568f1482bfd121e4b7", - [] - ], "mock-facedetection.js": [ "7ae658621ee9c34b9dc1091777ef4ccaff950a02", [] @@ -463886,6 +464921,10 @@ }, "service-worker": { "ServiceWorkerGlobalScope": { + "error-message-event-worker.js": [ + "525bc96e763e0c61b72a1099c1ee2a1f928f7b84", + [] + ], "isSecureContext.serviceworker.js": [ "5033594e34ba75fa2d69b8d44c0cc69e333d3569", [] @@ -463961,6 +465000,10 @@ ] } }, + "WEB_FEATURES.yml": [ + "9ddc5b400dc0e116b9c3c8a14203d3a475422c69", + [] + ], "multi-globals": { "current": { "current.https.html": [ @@ -464591,7 +465634,7 @@ [] ], "fetch-request-resources-iframe.https.html": [ - "86e9f4bb3598a5951920d13e1e002d78fe0aa21e", + "37fc491134d0f5324cb88be28acb567b547b68d6", [] ], "fetch-request-resources-worker.js": [ @@ -465757,7 +466800,7 @@ [] ], "WEB_FEATURES.yml": [ - "171923c067225ac7334b8011e7deaf347538952a", + "dcb21f387167f46062bc66d2bf5d0f3fc8c58417", [] ], "declarative": { @@ -465791,7 +466834,7 @@ "focus-navigation": { "resources": { "focus-utils.js": [ - "f4056dc1688442c2c41ce9421161bea448da7c2f", + "4aadfe24cbc1aafff7f36293e755694d5a6c7a48", [] ], "shadow-dom.js": [ @@ -466175,6 +467218,10 @@ "d304669ea19186b4fde0b105c37725d7a628e8bd", [] ], + "shared-storage-writable-fetch-request-in-sandboxed-iframe-inner.https.sub.html": [ + "ef8b2459f3cc386473a38d9ff651925a5f7c4850", + [] + ], "shared-storage-writable-iframe-in-fenced-inner.https.sub.html": [ "87dbe81a2b5294d8b7bc62dcc0e438d3f5ef830a", [] @@ -466183,6 +467230,14 @@ "1b63235b7cdffe9ebb43bfac3a01d5220e1519fb", [] ], + "shared-storage-writable-iframe-request-in-sandboxed-iframe-inner.https.sub.html": [ + "4d1b7ab198d7f0e85f3d3dcc8681264c2d05c56a", + [] + ], + "shared-storage-writable-img-request-in-sandboxed-iframe-inner.https.sub.html": [ + "8842a4689d823ab0b767eb14ec3f18a22deb2b19", + [] + ], "shared-storage-writable-pixel-write.png": [ "818c71d03f435db011069584cda25c1f66af1a85", [] @@ -466636,6 +467691,10 @@ "5b6ac87aed5ea1ed41f7e79bf340a4259039e52a", [] ], + "slow-executor.py": [ + "379ab552b94d0effd2bb28da60a80e3233c09002", + [] + ], "sw.js": [ "dd8a9631b4e8d25e0f3a4258806b909b07e682d7", [] @@ -467140,6 +468199,10 @@ "554bd31684ec096f0a3cf56a82dbfbc5556ddfa2", [] ], + "WEB_FEATURES.yml": [ + "a24e831c4aa8229d12f8fe9bdf8f3e1187f51db5", + [] + ], "helpers.js": [ "416c4a401efcd8933233a755ab65400cca4cdcb3", [] @@ -467916,10 +468979,6 @@ "25acb75ba00ec48e95515f7c803f52e1aaf9418b", [] ], - "paint-context-005-ref.svg": [ - "fa30a5361cb7461de2a653bc5df99243d97e25a7", - [] - ], "paint-context-006-ref.svg": [ "6aa42374c512b528868c55d0339eb4deedf09d69", [] @@ -468742,7 +469801,7 @@ [] ], "requirements_build.txt": [ - "7b4f8619b2e5d3bbbf3fa1d15de96c76fcc44e98", + "e74e4e5302de95611631ab3193f8ae38f643f7dc", [] ], "requirements_macos_color_profile.txt": [ @@ -468750,7 +469809,7 @@ [] ], "requirements_tc.txt": [ - "aa57643b9b58af506ca3548239adda1d4ff35534", + "b3c1c51f129b07fc0383de30ab659142052404eb", [] ], "run_tc.py": [ @@ -468936,11 +469995,11 @@ [] ], "lint.py": [ - "e3a555413b83178e34987a3a015159af29bbb34d", + "32bc7ece7b12f366fae0278fe4de06df43395583", [] ], "rules.py": [ - "c7b3a59b19e22f0aeda41374f7ba311d635bdbbb", + "8dba7817a9e5633a48de61351df7976780ab3832", [] ], "tests": { @@ -469137,7 +470196,7 @@ } }, "test_file_lints.py": [ - "f2ebcd9080a32a7cce54e36877e9367360e28237", + "e77048b31566887576d31c37d3d80833336131c2", [] ], "test_lint.py": [ @@ -469361,7 +470420,7 @@ [] ], "requirements_tests.txt": [ - "24785f3531394470e232e5420a2fd64cbc1c0774", + "74792e6131456c571fadd096ae0a53e0edfb0d93", [] ], "runner": { @@ -479940,7 +480999,7 @@ ] }, "transport.py": [ - "d61ebaddea7b7e3cac008781a8dcf1dc8326700d", + "14b990f971d235db7a354677a7b9032dd2ff88a5", [] ], "undefined.py": [ @@ -480258,7 +481317,7 @@ [] ], "base.py": [ - "6b1465cde8aca91a1a1df7819a8e8aa0f4608e36", + "dd4fc314fc0449a35bfe6a58e9fa4921dcd62d64", [] ], "chrome.py": [ @@ -480294,7 +481353,7 @@ [] ], "firefox.py": [ - "d977930a289b614caf4e0c598876500b20630497", + "d22da8568adbe91e2c3379683e249507a908a35a", [] ], "firefox_android.py": [ @@ -480366,11 +481425,11 @@ [] ], "executorchrome.py": [ - "f5641471562b65c56701423329b9a16f4d103561", + "46d38f14c55ee4ddc4452eec972df30ee07ed354", [] ], "executoredge.py": [ - "3b62cb7477b26f2ab44ccb5a8fb610ed18b4c023", + "ad546b7e84062b1cecd6fb42e96f4d4e3af4a0b8", [] ], "executormarionette.py": [ @@ -480571,7 +481630,7 @@ [] ], "test_base.py": [ - "a3d804336e12ebc214c452c3c449fb75836c6d45", + "b5e40e3f8df1a1c69b0bc946c2b26901bd4d4b45", [] ], "test_sauce.py": [ @@ -481120,7 +482179,7 @@ [] ], "openssl.py": [ - "25f86e019ecf210dd1bf2d735932781bb7fb430e", + "2a388671b62f32ccbfba6682e634a72feff99d53", [] ], "pregenerated.py": [ @@ -482033,6 +483092,10 @@ "README.md": [ "ab7a3530515861c91c4c012b93c2e0cf8e913def", [] + ], + "WEB_FEATURES.yml": [ + "f206d0be0b4d054917184b9a52492c095142d1fd", + [] ] }, "virtual-keyboard": { @@ -484846,7 +485909,7 @@ [] ], "test_actions_scroll.html": [ - "db5952ed74d2bc771933296f313797126c18291e", + "edeff342fe4d67d8af2272a516a618648485ff55", [] ] }, @@ -485173,7 +486236,7 @@ [] ], "conv_transpose2d.json": [ - "742752fd41d6a682bba884cddefabcb5e72b4987", + "241faf52633abd2bac30c95e1d83d9930b2fe32b", [] ], "cos.json": [ @@ -485422,7 +486485,7 @@ ] }, "utils.js": [ - "e5b80ae9f7fb081758960a3e6b4cbf0cf92f2b37", + "c231f46bcf5221808a3f05345f28507d3a6215c6", [] ], "utils_validation.js": [ @@ -485474,6 +486537,10 @@ "31d80926d33b559fd31c5da4b0dea8d18e3ab34c", [] ], + "WEB_FEATURES.yml": [ + "117b04f81fe45dc7935177063c7177ac00e06fc0", + [] + ], "coverage": { "RTCDTMFSender.txt": [ "aa30021323870669c8aada66f481168bf4cd4c7b", @@ -488749,6 +489816,10 @@ } }, "modules": { + "WEB_FEATURES.yml": [ + "ab73efc0d041258d2e778479391523c2960156e8", + [] + ], "dedicated-worker-options-credentials.html.headers": [ "8da851ab7363870014a32121a3cd87979aa2099d", [] @@ -491642,7 +492713,7 @@ ] ], "idb-binary-key-detached.htm": [ - "ac6fc2ef98021be045338302b08151bd13535575", + "a4ce3fbce00917b747c4dd40655cb2d6aa55c63d", [ null, {} @@ -525501,6 +526572,15 @@ } ] ], + "fedcm-disclosure-text-shown.https.html": [ + "e3f303ec4c9ff5b34960373bc90f4fb258b268c6", + [ + null, + { + "testdriver": true + } + ] + ], "fedcm-userinfo-after-resolve.https.html": [ "0521f4a2ab5d82aeaca1f603b297e1199b886af8", [ @@ -531682,7 +532762,7 @@ ] }, "relpos-inline-hit-testing.html": [ - "ca0c961ca22b3ac7fac7f25f21085ceb220dfddc", + "aa7cd5ad97c7ab1614fe445ecb8a5f37165feffb", [ null, {} @@ -532406,7 +533486,7 @@ ] ], "color-computed-relative-color.html": [ - "ac2f9c87aac34ddeb3a54c45d449d49e2e333538", + "5a58ae6179834ffbcc4098318f5ba0f8825698e6", [ null, {} @@ -534244,7 +535324,7 @@ ] ], "content-valid.html": [ - "5c7558610745466c0bacc100f92cd3d8cca36a60", + "60d03a4d4c3412f15607721dae5d04dbdbf2c682", [ null, {} @@ -536479,14 +537559,14 @@ ], "intrinsic-size": { "col-wrap-004.html": [ - "00cfa520690374562242cbca8fa19c0e1ca44520", + "83b119e3f16ff6612047dae0cbdb439028704025", [ null, {} ] ], "col-wrap-005.html": [ - "a753619c62f51b85fa0b51f0cb058bec589707c5", + "15ca5a57ec49e68d2f1e071b3d387a28b8d052e6", [ null, {} @@ -536775,7 +537855,7 @@ ] ], "flex-shorthand.html": [ - "1d74df808341baa42914dec0c19359847e7188c9", + "d22957983b13b7a01875edbb56538785764f3c1a", [ null, {} @@ -544519,6 +545599,13 @@ {} ] ], + "overflow-outside-padding.html": [ + "792f7b87351bfcbda7baecc67ea6dedc2b05f3a5", + [ + null, + {} + ] + ], "overflow-padding.html": [ "2d6efc391a48781096cd2263575523c52bd4085e", [ @@ -544540,13 +545627,6 @@ {} ] ], - "overfow-outside-padding.html": [ - "792f7b87351bfcbda7baecc67ea6dedc2b05f3a5", - [ - null, - {} - ] - ], "parsing": { "block-ellipsis-invalid.html": [ "2b9c059a45d0e315a350e0c09fd7cd86be72c61e", @@ -546852,6 +547932,13 @@ ] ] }, + "position-relative.html": [ + "e3da0013101983e28cc2f1e59aa15a2e03a563db", + [ + null, + {} + ] + ], "rt-display-blockified.html": [ "b2b7989fddc2f18add83fd342aa75c44261d0b07", [ @@ -548655,7 +549742,14 @@ } ] ] - } + }, + "snapevents-at-document-bubble-to-window.html": [ + "e50be0b6b25e59c27d667c85e60e8defc7d97cde", + [ + null, + {} + ] + ] }, "css-scrollbars": { "inheritance.html": [ @@ -548976,7 +550070,7 @@ ] ], "invalidation-part-pseudo.html": [ - "fca4a964dce5c5c61b8f4fed4ef25510a9099298", + "66df33a4b7019768d29ea64fda7265d63d9436fc", [ null, { @@ -550998,21 +552092,21 @@ ] ], "colspan-001.html": [ - "e6cb440366cf0cecb94d0198315a909327c70a34", + "112055218011bec6c7ec2cbb890d294eaebea7a0", [ null, {} ] ], "colspan-002.html": [ - "144cbef4850f52c19163a793ff6b1f8f6b9b77a1", + "16db9eb8bad8986e6b40b570477b3f9bd83f85da", [ null, {} ] ], "colspan-003.html": [ - "58e02b92878269b6fbe79fdc6684fb969d1ec0dc", + "70e1b218f0510b2dd45a8fb09de76925305ca5d2", [ null, {} @@ -551268,7 +552362,7 @@ ] }, "percent-height-overflow-auto-in-restricted-block-size-cell.html": [ - "f532308484383dbbe086f7af9d90d0579b83608a", + "f5421c7365335b0c51b66674c3e28d1c9c2566c4", [ null, {} @@ -558930,6 +560024,15 @@ } ] ], + "text-overflow-017.html": [ + "7f61a57620c126c9ee99c7a2d41b567d84506bf1", + [ + null, + { + "testdriver": true + } + ] + ], "text-overflow-023.html": [ "b9c21ed8f22e5380773a6ebdf620913be7aa77e1", [ @@ -560269,7 +561372,7 @@ ] ], "duplicate-tag-rejects-start.html": [ - "6c99d6426c04f553dea129f0c0f978aba1c33c24", + "5c605fefbb3cc13538e4161bcb0f989a89a30e26", [ null, {} @@ -560290,7 +561393,7 @@ ] ], "hit-test-unpainted-element-from-point.html": [ - "c9650d97b9d1b1fe47443e83d776437b7ee77f49", + "b34d2b11df558327fbdd87dc3b4ded2b362bff14", [ null, {} @@ -560312,6 +561415,238 @@ {} ] ], + "navigation": { + "at-rule-cssom.html": [ + "6f8beb16731bec0dd1e4f90a9829cc8571cd84a2", + [ + null, + {} + ] + ], + "at-rule-in-layer-cascade-external-stylesheet.html": [ + "53c6135a566cb256079d480bb9b4b1f7a0be3ea4", + [ + null, + {} + ] + ], + "at-rule-in-layer-cascade.html": [ + "a38ca48e8c41426c73801173d1a9516b2a1caeff", + [ + null, + {} + ] + ], + "at-rule-in-layer.html": [ + "63ec4c3e25d24abd5e0e5e24cfd612487ae2c4c3", + [ + null, + {} + ] + ], + "at-rule-in-matching-media.html": [ + "77f2e05c340320fcc1a16c0135b0c85ef8157c91", + [ + null, + {} + ] + ], + "at-rule-in-non-matching-media.html": [ + "ac9dbde37e183ac5f559b2a2af6434add43786f9", + [ + null, + {} + ] + ], + "at-rule-in-shadow-dom.html": [ + "7edd8e0749f7c77f1257423c5838ae0bcb0b263b", + [ + null, + {} + ] + ], + "at-rule-multiple-rules.html": [ + "5a84d46da1884016bdf40022473a732e94d7a423", + [ + null, + {} + ] + ], + "at-rule-opt-in-change-with-script.html": [ + "12452f67634e42746871a74701c87dfeef165048", + [ + null, + {} + ] + ], + "hide-before-reveal.html": [ + "7cdbcb46280bd352c72f7ce9aa3802fae5e319e2", + [ + null, + { + "testdriver": true, + "timeout": "long" + } + ] + ], + "mismatched-snapshot-containing-block-size-skips.html": [ + "d18a40c9b6e38522f004394ac52494f58be4673d", + [ + null, + { + "testdriver": true + } + ] + ], + "old_vt_promises_bfcache.html": [ + "18397abbec7b2f5129d54b376b3b812f68ec4c53", + [ + null, + {} + ] + ], + "pagereveal-microtask-sequence.html": [ + "205f4d1ddcfb71d60788af58c77e6b12957336c3", + [ + null, + {} + ] + ], + "pagereveal-no-view-transition-new-opt-out.html": [ + "a8b314b751f57b7d237779b5cbf90c8cca66ab3f", + [ + null, + {} + ] + ], + "pagereveal-no-view-transition.html": [ + "a6ae95f9be12f158a3b5ce9b708d6e9b013f13a7", + [ + null, + {} + ] + ], + "pagereveal-updatecallbackdone-promise.html": [ + "3d259e66a2051dca2498f4ed4099c61d9f0dfb1c", + [ + null, + {} + ] + ], + "pagereveal-with-view-transition.html": [ + "3f21d56ed688bee743b13d7bdd7679f851f16485", + [ + null, + {} + ] + ], + "pageswap-in-hidden-doc-should-skip-transition.html": [ + "5be3b6cb27ce915eea1711caa93d4adee4e4f35b", + [ + null, + { + "testdriver": true + } + ] + ], + "pageswap-long-delay.html": [ + "e6ef6d80dc26b81dd7f99b0cb40c7e7c59bf3608", + [ + null, + {} + ] + ], + "pageswap-push-from-click.html": [ + "16e04c89bfe380e3c51b52dbd8e27db3316127f0", + [ + null, + { + "testdriver": true + } + ] + ], + "pageswap-push-navigation.html": [ + "50a43e70d90eb04251ab1017113b69f6120116db", + [ + null, + {} + ] + ], + "pageswap-push-with-redirect.html": [ + "d9d252f83ce7116754a65ee272c698b0e3c41b15", + [ + null, + {} + ] + ], + "pageswap-replace-navigation.html": [ + "18f63454fdf8ce59244ac6ff40563ba1461295a1", + [ + null, + {} + ] + ], + "pageswap-skip-transition.html": [ + "bfeee7827a31cb4ca0b78d4c43ccbf53f1d698cc", + [ + null, + {} + ] + ], + "pageswap-traverse-navigation-no-bfcache.https.html": [ + "9137dc4d1cd18da10ff2ac4c74e1e007d7fdfc04", + [ + null, + {} + ] + ], + "skip-outbound-vt-before-reveal.html": [ + "2fcac44d2494b6f25af528f8042f5de3fc5f4755", + [ + null, + { + "timeout": "long" + } + ] + ], + "with-types": { + "at-rule-with-types-parsing.html": [ + "431a0ec9f4de5888b498b850de6c2adfdcdea97a", + [ + null, + {} + ] + ], + "navigation-supersedes-types-same-rule.html": [ + "23dc9d4ca983d708a68279af1aadd107b2d6aed8", + [ + null, + {} + ] + ], + "navigation-supersedes-types-when-after.html": [ + "1fd28d97a6ee45010d19216b8f71bd9dd5017b43", + [ + null, + {} + ] + ], + "types-in-pagereveal-and-pageswap.html": [ + "2c12fece3c0990cf4991341b0dd0c75c927f7727", + [ + null, + {} + ] + ] + }, + "zero-named-elements.html": [ + "e6061de2a8b01584308a535a991f11927460e79c", + [ + null, + {} + ] + ] + }, "no-crash-set-exception.html": [ "bc0d764a590aaed95d2e6afe487f2477385a9c94", [ @@ -560561,6 +561896,20 @@ {} ] ], + "view-transition-types-mutable-no-document-element-crashtest.html": [ + "f1940c398695989d6cc569ffb25a03a83be1d064", + [ + null, + {} + ] + ], + "view-transition-types-mutable.html": [ + "86c77d615abf19471bc980f5cf6cf3fb7f9a97c4", + [ + null, + {} + ] + ], "web-animation-pseudo-incorrect-name.html": [ "e8d14f1bb08161169f436634fe9c4937759ed991", [ @@ -561324,8 +562673,8 @@ {} ] ], - "CSSStyleSheet-constructable-baseURL.tentative.html": [ - "8997a59e9c18238b661c5b3592bdfd86e266b754", + "CSSStyleSheet-constructable-baseURL.html": [ + "d0f0f828b03ead6083ca8e3aad6a9070bd2a1f97", [ null, {} @@ -567144,7 +568493,7 @@ ] ], "ShadowRoot-innerHTML-upgrade.tentative.html": [ - "e21c9dd03326d68976bffc99483d04edd1bb8145", + "11cecb1533b53839570387ff5d0c5e9e9df69f56", [ null, {} @@ -567517,16 +568866,21 @@ }, "direct-sockets": { "disabled-by-permissions-policy.https.sub.html": [ - "f2f6e50be0fd2274b7c3b7e453d7661b6dd99daa", + "cc2f58b76a6bdf533057e3d6f45ddac8c91b7b6b", [ null, - { - "testdriver": true - } + {} ] ], - "open-securecontext.http.html": [ - "c3a2a42a25bf186534b3addbc19cdae96ed7f956", + "tcp_socket.https.html": [ + "10d21ce42b9e6821512d24ba179819a541e9f6dc", + [ + null, + {} + ] + ], + "udp_socket.https.html": [ + "c95d41e2bdec79f5c2fffd7efe49376597c742f0", [ null, {} @@ -590219,21 +591573,10 @@ } ] ], - "eventsource-request-cancellation.any.window.js": [ + "eventsource-request-cancellation.window.js": [ "1cee9b742ea284f415d375bbdc19d8262ccdd3c6", [ - "eventsource/eventsource-request-cancellation.window.any.html", - { - "script_metadata": [ - [ - "title", - "EventSource: request cancellation" - ] - ] - } - ], - [ - "eventsource/eventsource-request-cancellation.window.any.worker.html", + "eventsource/eventsource-request-cancellation.window.html", { "script_metadata": [ [ @@ -599458,6 +600801,20 @@ ] ] }, + "response-arraybuffer-realm.window.js": [ + "19a5dfa5ff6e5d4cb2951919a6f4ba086e5056da", + [ + "fetch/api/response/response-arraybuffer-realm.window.html", + { + "script_metadata": [ + [ + "title", + "realm of Response arrayBuffer()" + ] + ] + } + ] + ], "response-body-read-task-handling.html": [ "64b0755666168d7cac9808fe1593a01889a19bff", [ @@ -602302,6 +603659,53 @@ } ] ], + "send-on-deactivate-with-background-sync.tentative.https.window.js": [ + "881bdd23f9371ac684b4aa58c2be23ac402cf4fe", + [ + "fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ], + [ + "script", + "/common/dispatcher/dispatcher.js" + ], + [ + "script", + "/common/get-host-info.sub.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js" + ], + [ + "script", + "/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js" + ], + [ + "script", + "/fetch/fetch-later/resources/fetch-later-helper.js" + ], + [ + "timeout", + "long" + ] + ], + "timeout": "long" + } + ] + ], "send-on-deactivate.tentative.https.window.js": [ "3bcf07483add874c42e6c26cc4343905fcddc596", [ @@ -602412,10 +603816,17 @@ ] ], "resources-with-0x00-in-header.window.js": [ - "37a61c12b561b260725f8da61b8478c5d9b713af", + "b617911105acb45f5881f1988b52162702f31841", [ "fetch/h1-parsing/resources-with-0x00-in-header.window.html", - {} + { + "script_metadata": [ + [ + "script", + "/common/get-host-info.sub.js" + ] + ] + } ] ], "status-code.window.js": [ @@ -607677,7 +609088,7 @@ ] ], "auction-config.https.window.js": [ - "057b4d7f785cbe05f676b45ffc33551f51cf5e85", + "b5f551491645c46713692b1574a8074f4c244d8b", [ "fledge/tentative/auction-config.https.window.html?1-5", { @@ -613813,7 +615224,7 @@ ] ], "network.https.window.js": [ - "fe287767c8d051328b82e7501a64f0ad86cc0505", + "0b41662155a67ba5e14c383d7f7075f9d808cecf", [ "fledge/tentative/network.https.window.html?1-5", { @@ -613852,14 +615263,18 @@ ], [ "variant", - "?11-last" + "?11-15" + ], + [ + "variant", + "?16-last" ] ], "timeout": "long" } ], [ - "fledge/tentative/network.https.window.html?11-last", + "fledge/tentative/network.https.window.html?11-15", { "script_metadata": [ [ @@ -613896,7 +615311,59 @@ ], [ "variant", - "?11-last" + "?11-15" + ], + [ + "variant", + "?16-last" + ] + ], + "timeout": "long" + } + ], + [ + "fledge/tentative/network.https.window.html?16-last", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/resources/testdriver-vendor.js" + ], + [ + "script", + "/common/subset-tests.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.sub.js" + ], + [ + "timeout", + "long" + ], + [ + "variant", + "?1-5" + ], + [ + "variant", + "?6-10" + ], + [ + "variant", + "?11-15" + ], + [ + "variant", + "?16-last" ] ], "timeout": "long" @@ -613940,7 +615407,11 @@ ], [ "variant", - "?11-last" + "?11-15" + ], + [ + "variant", + "?16-last" ] ], "timeout": "long" @@ -615093,7 +616564,7 @@ ] ], "trusted-bidding-signals.https.window.js": [ - "905abf8381eaeaee800be38c25d44e5704be0247", + "205c6895a06b3235ef3d448d16fad85743d14e31", [ "fledge/tentative/trusted-bidding-signals.https.window.html?1-5", { @@ -616568,7 +618039,7 @@ ] ], "trusted-scoring-signals.https.window.js": [ - "105b09fb3bec40b36ce4bda2d1d6aa809f3a0152", + "46570da3e41a26dac8d7fb3e2007d8a7df87b51c", [ "fledge/tentative/trusted-scoring-signals.https.window.html?1-5", { @@ -616631,7 +618102,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -616699,7 +618174,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -616767,7 +618246,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -616835,7 +618318,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -616903,7 +618390,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -616971,7 +618462,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -617039,7 +618534,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -617107,14 +618606,90 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" + ] + ], + "timeout": "long" + } + ], + [ + "fledge/tentative/trusted-scoring-signals.https.window.html?45-50", + { + "script_metadata": [ + [ + "script", + "/resources/testdriver.js" + ], + [ + "script", + "/common/utils.js" + ], + [ + "script", + "resources/fledge-util.sub.js" + ], + [ + "script", + "/common/subset-tests.js" + ], + [ + "timeout", + "long" + ], + [ + "variant", + "?1-5" + ], + [ + "variant", + "?6-10" + ], + [ + "variant", + "?11-15" + ], + [ + "variant", + "?16-20" + ], + [ + "variant", + "?21-25" + ], + [ + "variant", + "?26-30" + ], + [ + "variant", + "?31-35" + ], + [ + "variant", + "?36-40" + ], + [ + "variant", + "?41-45" + ], + [ + "variant", + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" } ], [ - "fledge/tentative/trusted-scoring-signals.https.window.html?45-last", + "fledge/tentative/trusted-scoring-signals.https.window.html?50-last", { "script_metadata": [ [ @@ -617175,7 +618750,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -617243,7 +618822,11 @@ ], [ "variant", - "?45-last" + "?45-50" + ], + [ + "variant", + "?50-last" ] ], "timeout": "long" @@ -622533,6 +624116,15 @@ ] ], "pagereveal": { + "order-in-bfcache-restore-iframe.html": [ + "f98cb61ad32bd9df42aefe6291f0c27902f4f2ad", + [ + null, + { + "timeout": "long" + } + ] + ], "order-in-bfcache-restore.html": [ "f453c80a2aee8c2cff5bca12f361a6a7b7683be8", [ @@ -622542,6 +624134,13 @@ } ] ], + "order-in-new-document-navigation-iframe.html": [ + "b982025bc78cfc2ec72f2c3de9eae80da0ba646a", + [ + null, + {} + ] + ], "order-in-new-document-navigation.html": [ "d2c44511d3a3a175ceb09298302baec088ddbf76", [ @@ -667363,6 +668962,15 @@ } ] ], + "select-option-hover-styles.tentative.html": [ + "4361229b8f15dfcdfbe4ae71824d42f67eceb174", + [ + null, + { + "testdriver": true + } + ] + ], "select-parsing.tentative.html": [ "31133446d4d140d5c13f33038617d8baf022e970", [ @@ -668928,6 +670536,15 @@ null, {} ] + ], + "no-focus.tentative.html": [ + "6e81a20962c26051aa0f1f6f9d458eb7d24fc88e", + [ + null, + { + "testdriver": true + } + ] ] }, "popovers": { @@ -669067,11 +670684,12 @@ ] ], "popover-focus-2.html": [ - "8f24ace91956610b065a3f853046c9fd7ac2fb45", + "552c8d8206b7b682f422bc8a5e2017f66983d198", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], @@ -680312,6 +681930,13 @@ } ] ], + "dynamic-integrity.html": [ + "7a6fed71086b24bae362e21303544d90291df733", + [ + null, + {} + ] + ], "http-url-like-specifiers.sub.html": [ "ba5182354cbcdda4386eea7730701a45460c443c", [ @@ -680351,6 +681976,27 @@ ] ] }, + "no-referencing-script-integrity-valid.html": [ + "2594459fcbfbcfc76e80670412f18a44c5c328a9", + [ + null, + {} + ] + ], + "no-referencing-script-integrity.html": [ + "8025ba3b8993d8f382a290b9d42522ee5a9e184c", + [ + null, + {} + ] + ], + "nonimport-integrity.html": [ + "1157ee64ee781b97a3cff9f5f8158ee72deb498d", + [ + null, + {} + ] + ], "not-as-classic-script.html": [ "5f97394e4408bc8db5624e5d0c6f1b2fa1b028dd", [ @@ -680364,6 +682010,13 @@ null, {} ] + ], + "static-integrity.html": [ + "d1d3649339e5b2dd0bcd7bfbe0118a9f2405b287", + [ + null, + {} + ] ] }, "inert": { @@ -683880,6 +685533,20 @@ {} ] ], + "transparent-text-with-shadow.html": [ + "8231ed9ff115ca88fe59a0a3e4ebd3d14a678b70", + [ + null, + {} + ] + ], + "transparent-text-with-text-stroke.html": [ + "2c81ff8aad70d71e92340dcd9d5a1001533a7bd2", + [ + null, + {} + ] + ], "transparent-text.html": [ "9eb978ab5cd8316cc1ae4f116a96a2271a2e9c96", [ @@ -686878,7 +688545,7 @@ ] ], "width-height-004.html": [ - "7133573b04d82664d7c0885c0bca9bc7c745d50f", + "10ece249ca0b51d4b63c865703ee43b7f95eda30", [ null, {} @@ -689581,7 +691248,7 @@ ] ], "mediametadata.html": [ - "f87e71d969004ee575300fb2f914c8d122dddf48", + "d73a43125160ecd1f6a45ac094490bfb4fc13a8f", [ null, {} @@ -691808,7 +693475,7 @@ ] ], "event-constructor.html": [ - "863681ced730d1c3f441a6f8b21db7b890301d25", + "89ac934020eec9c7771b2fbd608a95e730b5d093", [ null, {} @@ -691955,14 +693622,14 @@ ] ], "navigate-anchor-cross-origin.html": [ - "62e5adb20ae88c33c3f76b527d98502d38db3a52", + "a69b78196ff288fb251a1393436e4714d7925701", [ null, {} ] ], "navigate-anchor-download-userInitiated.html": [ - "69181425292e758ac5bdccaec51b95f3670ecb71", + "17109a2ae82049bba0afbec4df059fe43150164d", [ null, { @@ -691971,28 +693638,28 @@ ] ], "navigate-anchor-download.html": [ - "d04245ec253ce0b9f56afa9fbc598730924ba40e", + "fbeeb69b9563f7246079242a31063e584e3e420a", [ null, {} ] ], "navigate-anchor-fragment.html": [ - "6443ccecd1d702cc1210857bd9c7013721d88fa6", + "69400c3d2f31f8df45dfef9062904035800c4ac5", [ null, {} ] ], "navigate-anchor-same-origin-cross-document.html": [ - "5a6dce7ec8bcc9b349494ff151428d219ee7bfc0", + "084993540a18dc90da1cd747de05fdcef6cc093a", [ null, {} ] ], "navigate-anchor-userInitiated.html": [ - "bb76e7a3fbe65121452fb39218f89c567bafac48", + "686d7ad6ee393e6ca5cc65193e35f7bdf8fda416", [ null, { @@ -692001,7 +693668,7 @@ ] ], "navigate-anchor-with-target.html": [ - "e4b897d82f3ddc62e64f9a7489969425338b29f9", + "de74239b3bee8b3cc0e7e27c899e8b620245d925", [ null, {} @@ -692022,35 +693689,35 @@ ] ], "navigate-destination-getState-back-forward.html": [ - "869fc1648157b25f296c69f8163a441a0101277b", + "b206981821b5441534f2c19b3f8076308ec3e0bf", [ null, {} ] ], "navigate-destination-getState-navigate.html": [ - "d19a16851453a0ea5f9b7ac72ea2bb9e70e98199", + "1e622f99117c192a0081cdf92e2d2b9605fa182c", [ null, {} ] ], "navigate-destination-getState-reload.html": [ - "ac6528ce7ef261ac087105f54d52d0ef381cb231", + "be33b8120da70a1269efeb6cef3beb2c8a9922a6", [ null, {} ] ], "navigate-form-get.html": [ - "7a71a1c3050a0cceca5ca0e9415a830ae8210356", + "59661a1caf77a5da1672bf0fb4ace357e970292a", [ null, {} ] ], "navigate-form-reload.html": [ - "217169053722c2b4c4ecdbaed4b9a8e263fbb97a", + "cdd3ade4ff2c54e889183a852bc4d42611e8e19f", [ null, {} @@ -692064,14 +693731,14 @@ ] ], "navigate-form-traverse.html": [ - "b9665c805665956fe57bf6640cb292be71f447f3", + "72b8dc36acb3a7d64f91cc59a261b971d0836312", [ null, {} ] ], "navigate-form-userInitiated.html": [ - "246e028a0dbf241f1667c380a0255396d13b1553", + "079f546771ff669f48c69bb8ead2932ceeb24324", [ null, { @@ -692080,28 +693747,28 @@ ] ], "navigate-form-with-target.html": [ - "4b1a8ce9d3a975f839f0af2a91e0a600a8ea827e", + "07418366a7644104ac31db6ef0bb881a7b499cd4", [ null, {} ] ], "navigate-form.html": [ - "653ef3b8eba65a79f631ac392c9cdf8b0ec77d9b", + "8cea889bec185a26797b8df559682a78cfe9b14b", [ null, {} ] ], "navigate-history-back-after-fragment.html": [ - "9da4ddcd50779229c550452987ce153671a4e093", + "4529fe25ac3b4f84410dad36a09a7dd5f0f4c036", [ null, {} ] ], "navigate-history-back-after-pushState.html": [ - "fdee41a312191455e0f7babdad75d281b6fc6755", + "06c3b89bbcf4141de35e8d65d002b798f3fea651", [ null, {} @@ -692115,7 +693782,7 @@ ] ], "navigate-history-back-cross-document.html": [ - "29c626a522145f5a26b050e9e97aeff4d213cad8", + "a34b20a5e539fae8437d112025e56b5924d182a8", [ null, {} @@ -692129,77 +693796,77 @@ ] ], "navigate-history-go-0.html": [ - "5508928e198dd9a4d88fe6ac3b50a99286c2e825", + "cd716bfafb1b4cc425ee0a387f590cc773340cd7", [ null, {} ] ], "navigate-history-pushState.html": [ - "5079b21078178175df99bdb1875889b9328fed34", + "f89288b6edf4685c24b974b34f2ae778efe7bb6c", [ null, {} ] ], "navigate-history-replaceState.html": [ - "444116a6324c361b6876f3370bbcf4f579c7f0f4", + "d18feb2bc1debbde82708d3442c46d387ca2394a", [ null, {} ] ], "navigate-iframe-location.html": [ - "1bd79188231b6ff973fe9e741f9d554be252bd72", + "c00a6e010db8e21cd5a01ec5972300792add9033", [ null, {} ] ], "navigate-location.html": [ - "a0ed4dc0aac5886cee3496a4aac007eaddaee46e", + "b1ce204a626a5ada1410426fcdbfd56e4337d628", [ null, {} ] ], "navigate-meta-refresh.html": [ - "d4d5b1c8e13927eaa3bbda1d973cc1413421c753", + "f64484c3055cbb2d761dd1a5cdc858f61d28d75d", [ null, {} ] ], "navigate-navigation-back-cross-document.html": [ - "084051539b8db3f50edb4e3037c9dd8882a6bbe6", + "de87fbbb800d1681c9d1b7ed925085dbac2ad7ba", [ null, {} ] ], "navigate-navigation-back-same-document-in-iframe.html": [ - "42c694e2905d73eb7ba92dc7a96c3c3152febf8e", + "3d810d2f1de5a8e2a3054465844a2edec7783901", [ null, {} ] ], "navigate-navigation-back-same-document.html": [ - "b08bbfcbf11430e3e5f6131e91fb8b90ea82a891", + "0f2faff7d7b06238d106b5f54210ab60d29c0cca", [ null, {} ] ], "navigate-navigation-navigate.html": [ - "c56af1b40df8fd0720f0114f687ef78fed88a074", + "5dd1892cc001a77ca24b530ca7c7bd8e017860d9", [ null, {} ] ], "navigate-svg-anchor-fragment.html": [ - "c6d210cccb1335983ba3df95788e1f7e7caa3dc8", + "647496fd5c6980e8a977317a40c5e7e0424573c5", [ null, {} @@ -692213,21 +693880,21 @@ ] ], "navigate-to-srcdoc.html": [ - "ea5c3f92168500ed6966dd1211447eb0bbcc7280", + "bb598d8b90292904fe669c6dd2414faa8460b586", [ null, {} ] ], "navigate-window-open-self.html": [ - "4e569b6d548f165cd7939b5e51d7da19957b0f69", + "1ef65ed82ba23a297e1a84eda5a200319e4db105", [ null, {} ] ], "navigate-window-open.html": [ - "42828308d7709e717402e126f7aebbf1d6e0896c", + "13cdefb5d3b559ec92a92d689d499727d02fac24", [ null, {} @@ -699165,7 +700832,7 @@ ] ], "pointer-event-has-device-properties-uniqueid-from-pointer-event-init.tentative.html": [ - "a37df4b4214501d4f7e5e7803ecfd3672c91b591", + "33b2354ec63935cd9cfc0320de022df7b2be163c", [ null, {} @@ -701344,6 +703011,13 @@ {} ] ], + "shared-storage-surface-filtering-id.https.html": [ + "53ed3a109bc1a025446072e1399f1859053c3d68", + [ + null, + {} + ] + ], "shared-storage-surface-success-2.https.html": [ "8203fd11eaa325c9c4e4bf294676287a4e86453b", [ @@ -718542,7 +720216,7 @@ ] ], "percent-encoding.html": [ - "1f1794bdae09db3a501479717121d93938e9869a", + "be688eabfc6222f80ea041a2317bb739d31f8f4c", [ null, { @@ -720985,6 +722659,13 @@ {} ] ], + "error-message-event.https.html": [ + "fc8edb4b8968ef2c3ec1503f61f188795f6648fb", + [ + null, + {} + ] + ], "extendable-message-event-constructor.https.html": [ "525245fe9ece73fde6e2408e76927bbfcd1b04cf", [ @@ -721662,7 +723343,7 @@ ] ], "fetch-request-resources.https.html": [ - "b4680c3ccd58d9d7def9d69ff1d1048a6ae02905", + "9524e6d4749b250f8e40e22306101bec8ceee406", [ null, {} @@ -722070,7 +723751,7 @@ ] ], "navigation-timing-sizes.https.html": [ - "a960cd57f3c73a8cfaa37f2c1278ad8b7dbf32b8", + "e726a31f17060f7c37ad07d15c1de4ab88bf4c44", [ null, {} @@ -722946,6 +724627,13 @@ } }, "shadow-dom": { + "Document-caretPositionFromPoint.tentative.html": [ + "2b97546d2e257ce0bf2cd5275058df01e40f6eed", + [ + null, + {} + ] + ], "Document-prototype-adoptNode.html": [ "6afd603618d7af99a9a71818a735b786efb36cd7", [ @@ -723706,6 +725394,15 @@ ], "reading-order": { "tentative": { + "grid-order-across-scopes.html": [ + "d505383e33899e86b4820b03943fecdba07b68b1", + [ + null, + { + "testdriver": true + } + ] + ], "grid-order-on-shadow-host.html": [ "a48eda1b57cd26b642edeed2d890bbf01a6043fe", [ @@ -723725,38 +725422,42 @@ ] ], "grid-order-with-nested-grids.html": [ - "d3da6682a3488e65bf2979aea344f5e43a956a49", + "15bdcf996fd4a2855ddd36995855d64f8593667e", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], "grid-order-with-popover.html": [ - "2e98c041570d935f89dd753e04460ab098d7dd89", + "c96a0c4fcf7712ae8365fd77f97b1ee9c7335a6e", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], "grid-order-with-slots.html": [ - "3045001e1d82525cbbf2e4524d86c28e4f208036", + "ed658b3510ae0ad983dbc53391f1ff90efb5d61a", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ], "grid-order.html": [ - "1b86ab0b25a1d0e92aeae09b6f55b17bb97f1ee7", + "3ee91358fd612dc83afb10038e52163dbecd6d8b", [ null, { - "testdriver": true + "testdriver": true, + "timeout": "long" } ] ] @@ -724710,29 +726411,29 @@ {} ] ], - "cross-origin-create-worklet-unrevealed-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html": [ - "f1f37b0affd66f4cdc736ada641947f4e6c9471b", + "cross-origin-create-worklet-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html": [ + "db361776f638731401883e8605c5e4f9d2a28411", [ null, {} ] ], - "cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-credentials.tentative.https.sub.html": [ - "dd6347e463171db65de24a9b57d6f1a754b78331", + "cross-origin-create-worklet-failure-missing-access-control-allow-credentials.tentative.https.sub.html": [ + "8887aad64dc72e5e36fc254c8a6b4221d4f0ef6b", [ null, {} ] ], - "cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-origin.tentative.https.sub.html": [ - "1f3223a5644372f1f76bcbe29bd8d064d7b41dce", + "cross-origin-create-worklet-failure-missing-access-control-allow-origin.tentative.https.sub.html": [ + "58a2f3a77bbfb402f425be9c8a7262a9e65a3df4", [ null, {} ] ], - "cross-origin-create-worklet-unrevealed-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html": [ - "f96e4d596e8df094c5dc30eac67c609205d0fa27", + "cross-origin-create-worklet-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html": [ + "5b140a8141c96473af0ba4e5135bd5099094359d", [ null, {} @@ -724950,6 +726651,13 @@ {} ] ], + "shared-storage-writable-fetch-request-in-sandboxed-frame.tentative.https.html": [ + "de935b22fe080ee5822c5ea868b15c870227550a", + [ + null, + {} + ] + ], "shared-storage-writable-forbidden-header-tentative.https.html": [ "896fb7924040459069b32e3c9918d88756608fe1", [ @@ -724985,6 +726693,13 @@ {} ] ], + "shared-storage-writable-iframe-request-in-sandboxed-frame.tentative.https.html": [ + "d2d07fcc330019b7eb593efc3a8bc1201ce61124", + [ + null, + {} + ] + ], "shared-storage-writable-img-content-attribute.tentative.https.sub.html": [ "5bce34d91a97c34d1a57f21cc4e27aadc55a91c1", [ @@ -725013,6 +726728,13 @@ {} ] ], + "shared-storage-writable-img-request-in-sandboxed-frame.tentative.https.html": [ + "a901500d66a4e46eeb722b5420d8d7c2235adccb", + [ + null, + {} + ] + ], "shared-storage-writable-insecure-context.tentative.http.sub.html": [ "debb6cf9c56fb4cda8e72293e0de4b533648c845", [ @@ -726218,13 +727940,21 @@ ] ], "navigation-timing-requestStart-responseStart.https.html": [ - "9c9371c4c31467cad8e3f1ed6f61685c9d1ed567", + "2687b5bf2c2d0aa46a202cd0552252c2735931e4", + [ + "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?include=afterResponse", + {} + ], [ - "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?default", + "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?include=noPrefetch", {} ], [ - "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?prefetch=true", + "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?include=waitingForRedirect", + {} + ], + [ + "speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html?include=waitingForResponse", {} ] ], @@ -729143,7 +730873,7 @@ ] ], "requestStorageAccess-dedicated-worker.tentative.sub.https.window.js": [ - "6c3d616e26aaa796e9aa7226621f0430cff2d4b2", + "5c3089bf3473156e66922a0c7eb0e3805f6b001d", [ "storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.html", { @@ -737821,7 +739551,7 @@ }, "reftests": { "paint-context-005.svg": [ - "8bbfff8d4744f69acdf79523df7bdc73f9ea0975", + "a76c7af88ffa36894476981e78e9148e9c92d88a", [ null, {} @@ -738753,6 +740483,13 @@ {} ] ], + "SVGLength-rlh.html": [ + "411013b65b5b1601d221dba99ee84efa9e990bbf", + [ + null, + {} + ] + ], "SVGLength-viewport.html": [ "2a29c0ba54978fa732b60460689e34d08db93448", [ @@ -739114,7 +740851,7 @@ ] ], "Document-write.html": [ - "87e9e724699efc3f0edde3afade4cf53ec2c9c3e", + "7902733f67c23bad9529505565308a6e5a8db887", [ null, {} @@ -739142,7 +740879,7 @@ ] ], "Element-setAttribute-respects-Elements-node-documents-globals-CSP.html": [ - "c0f72bb36ac09c19b779ca5da114080a46c96c7a", + "aafe3c70313cb420a1efede51891f949d7aa33b8", [ null, {} @@ -739403,7 +741140,7 @@ ] ], "block-string-assignment-to-Document-write.html": [ - "974203c1133a43afd87069b41b29ab1e5460a36d", + "d22be1118ce2b0bcc49c502f5bbaa6283d4c6552", [ null, {} @@ -753886,7 +755623,7 @@ ] ], "createcredential-passing.https.html": [ - "f64a4ff0397222b21379265591a2f09a9b906c97", + "4124c2247ea3af01eb89e7a4e0cc0b8c326d8527", [ null, { @@ -753906,7 +755643,7 @@ ] ], "createcredential-pubkeycredparams.https.html": [ - "d1df7952d6766744280b460a18d2e561a5527e5d", + "cb830bfe92aa1110ddb964c082daec0e13d6386d", [ null, { @@ -753964,6 +755701,16 @@ } ] ], + "getcredential-allowcredentials.https.html": [ + "0263774142c685af898135ce782475f75d559c3e", + [ + null, + { + "testdriver": true, + "timeout": "long" + } + ] + ], "getcredential-attachment.https.html": [ "7ab7235af501287bd9bc96d09ec549702e359dce", [ @@ -758829,7 +760576,7 @@ ] ], "videoFrame-copyTo-rgb.any.js": [ - "442efc4b0f487816631430b50cdd893c72767be3", + "146b6756cb467335087dd234e63b4e9afcd03adb", [ "webcodecs/videoFrame-copyTo-rgb.any.html", { @@ -761485,7 +763232,7 @@ ] ], "buffer.https.any.js": [ - "5a09b05c7dc1bafc125be7e46297422131c1fabc", + "51804e7224f8d845e8a59183cbb2e55db29707a0", [ "webnn/conformance_tests/buffer.https.any.html?cpu", { @@ -767114,7 +768861,7 @@ ] ], "elementwise-unary.https.any.js": [ - "f87c61b4e45689d4506bbef4a31aeb888c483b0a", + "c735183aab1d1410668b85a2d390800aa82b1525", [ "webnn/validation_tests/elementwise-unary.https.any.html", { @@ -767952,7 +769699,7 @@ ] ], "pooling.https.any.js": [ - "e8add0511f9ecc5b65604bedcb644b40ceac3105", + "08a78f25bafe92803968a88ea07e174d3cafbd78", [ "webnn/validation_tests/pooling.https.any.html", { @@ -767993,7 +769740,7 @@ ] ], "prelu.https.any.js": [ - "865f9f684c144bfc78933889f7f0dbdbc481312f", + "fa89df9631b0d11984f0240b42912ea426ef7400", [ "webnn/validation_tests/prelu.https.any.html", { @@ -768034,7 +769781,7 @@ ] ], "reduction.https.any.js": [ - "60f0978678870e8e78fc68b8dc6120041015556d", + "7da6b24dcf058383e12d2fbfe7f1f5dab4721350", [ "webnn/validation_tests/reduction.https.any.html", { @@ -768075,7 +769822,7 @@ ] ], "relu.https.any.js": [ - "237c1c3eda3a490c5a14d335b1897ccc22b21848", + "61b0d1938fe5365afc852db79beeddbedce97c37", [ "webnn/validation_tests/relu.https.any.html", { @@ -768116,7 +769863,7 @@ ] ], "resample2d.https.any.js": [ - "de44c6a333a660cfcfcb463759e56ce9f82d66ef", + "cc52cf97f4ff571cd9a6d7223fbece79a8c8cc3e", [ "webnn/validation_tests/resample2d.https.any.html", { @@ -768932,7 +770679,7 @@ ] ], "RTCPeerConnection-createAnswer.html": [ - "1970db0737ab2aaa52380e62a96a49647f4ad8b8", + "7e31dda62906c93fc2bd4907d09bc56e5c6c465f", [ null, {} @@ -768948,7 +770695,7 @@ ] ], "RTCPeerConnection-createOffer.html": [ - "7287980a5b4a5ed5116217914e7ddd9c885166ed", + "4eabdffa04afee71e89a3a5c56a8257d1c4663b0", [ null, {} @@ -786408,7 +788155,7 @@ ] ], "tree-building.html": [ - "6cd617decef98394beb152c6a1ebf862d6b40957", + "06bc8b9d62d56e7efdd3cf408404b4ad6b1b2a4e", [ null, {} @@ -815718,7 +817465,7 @@ ] ], "start_nodes.py": [ - "f44a6d4857c0b62d58adb844042617cc622d0111", + "351020af4c2d9f74a3aed55db014808af02ac622", [ null, {} @@ -815978,14 +817725,14 @@ "permissions": { "set_permission": { "invalid.py": [ - "5397dc7b62e7da62318d282dba621fe6d9274015", + "d7172160721cec9e5fec0e4b1fa70125e5da0ef2", [ null, {} ] ], "set_permission.py": [ - "45c50dbf88367185f72823aec9d72013f5c83d22", + "18f8e6fed000fe2cc6ae04adfa0cc965b89b5edc", [ null, {} @@ -816085,7 +817832,7 @@ ] ], "wheel.py": [ - "4f897479e235d82e6b1556acef68a5626eeb9f72", + "ee0d4d4600d4522ec405296468add02e053014b8", [ null, {} @@ -817818,7 +819565,7 @@ }, "get_element_text": { "get.py": [ - "924a4e8d79771d78de59e48f61bb6e88ab34a7b9", + "8f832077e1069c75ae9ff6362d49e7aad9fd7c4c", [ null, {} @@ -818344,7 +820091,7 @@ ] ], "wheel.py": [ - "a75a84378a6ada5623096f858363cb7d7a1c5a5c", + "6d0f9ddb11fbe2a6775fb63747b5dc601a0acb8a", [ null, {} diff --git a/tests/wpt/meta/css/css-content/parsing/content-valid.html.ini b/tests/wpt/meta/css/css-content/parsing/content-valid.html.ini index ec3fb653e49..030357bc4f9 100644 --- a/tests/wpt/meta/css/css-content/parsing/content-valid.html.ini +++ b/tests/wpt/meta/css/css-content/parsing/content-valid.html.ini @@ -214,3 +214,21 @@ [e.style['content'\] = "url(\\"https://www.example.com/picture.svg\\") \\"hello\\" / attr(foo)" should set the property value] expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / \\"alt text\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / \\"alt text\\" attr(foo) \\"bar\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") / attr(foo)" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / \\"alt text\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / \\"alt text\\" attr(foo) \\"bar\\"" should set the property value] + expected: FAIL + + [e.style['content'\] = "url(\\"picture.svg\\") \\"hello\\" / attr(foo)" should set the property value] + expected: FAIL diff --git a/tests/wpt/meta/css/css-lists/counters-005.html.ini b/tests/wpt/meta/css/css-lists/counters-005.html.ini new file mode 100644 index 00000000000..41b44b5559d --- /dev/null +++ b/tests/wpt/meta/css/css-lists/counters-005.html.ini @@ -0,0 +1,2 @@ +[counters-005.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/white-space/text-wrap-nowrap-001.html.ini b/tests/wpt/meta/css/css-text/white-space/text-wrap-nowrap-001.html.ini new file mode 100644 index 00000000000..bcca040350a --- /dev/null +++ b/tests/wpt/meta/css/css-text/white-space/text-wrap-nowrap-001.html.ini @@ -0,0 +1,2 @@ +[text-wrap-nowrap-001.html] + expected: FAIL diff --git a/tests/wpt/meta-legacy-layout/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html.ini b/tests/wpt/meta/css/cssom/CSSStyleSheet-constructable-baseURL.html.ini index 13602c25c9d..a9bad39b1da 100644 --- a/tests/wpt/meta-legacy-layout/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html.ini +++ b/tests/wpt/meta/css/cssom/CSSStyleSheet-constructable-baseURL.html.ini @@ -1,10 +1,9 @@ -[CSSStyleSheet-constructable-baseURL.tentative.html] +[CSSStyleSheet-constructable-baseURL.html] [Constructing sheet with custom base URL ueses that URL for CSS rules] expected: FAIL - [Constructing sheet with invalid base URL throws a NotAllowedError] - expected: FAIL - [Constructing sheet with relative URL adds to the constructor document's base URL] expected: FAIL + [Constructing sheet with invalid base URL throws a NotAllowedError] + expected: FAIL diff --git a/tests/wpt/meta/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini b/tests/wpt/meta/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini index 14c28753235..17c5362cdbb 100644 --- a/tests/wpt/meta/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini +++ b/tests/wpt/meta/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html.ini @@ -10,3 +10,6 @@ [Upgrade into customized built-in element when definition is added] expected: FAIL + + [Upgrade into autonomous custom element should not inherit from global registry for missing values] + expected: FAIL diff --git a/tests/wpt/meta/eventsource/eventsource-request-cancellation.any.window.js.ini b/tests/wpt/meta/eventsource/eventsource-request-cancellation.any.window.js.ini deleted file mode 100644 index 101e03a6b7d..00000000000 --- a/tests/wpt/meta/eventsource/eventsource-request-cancellation.any.window.js.ini +++ /dev/null @@ -1,5 +0,0 @@ -[eventsource-request-cancellation.window.any.html] - expected: TIMEOUT - -[eventsource-request-cancellation.window.any.worker.html] - expected: TIMEOUT diff --git a/tests/wpt/meta/fetch/api/response/response-arraybuffer-realm.window.js.ini b/tests/wpt/meta/fetch/api/response/response-arraybuffer-realm.window.js.ini new file mode 100644 index 00000000000..e273ea59211 --- /dev/null +++ b/tests/wpt/meta/fetch/api/response/response-arraybuffer-realm.window.js.ini @@ -0,0 +1,3 @@ +[response-arraybuffer-realm.window.html] + [realm of the ArrayBuffer from Response arrayBuffer()] + expected: FAIL diff --git a/tests/wpt/meta/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini b/tests/wpt/meta/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini new file mode 100644 index 00000000000..f0403ab2cb8 --- /dev/null +++ b/tests/wpt/meta/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js.ini @@ -0,0 +1,9 @@ +[send-on-deactivate-with-background-sync.tentative.https.window.html] + [fetchLater() does send on page entering BFCache even if BackgroundSync is on.] + expected: FAIL + + [fetchLater() with activateAfter=0 sends on page entering BFCache if BackgroundSync is on.] + expected: FAIL + + [fetchLater() with activateAfter=1m does send on page entering BFCache even if BackgroundSync is on.] + expected: FAIL diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini new file mode 100644 index 00000000000..31590bbd841 --- /dev/null +++ b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html.ini @@ -0,0 +1,4 @@ +[order-in-bfcache-restore-iframe.html] + expected: TIMEOUT + [pagereveal event in iframe fires and in correct order on restoration from BFCache] + expected: TIMEOUT diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini new file mode 100644 index 00000000000..f2af0d28013 --- /dev/null +++ b/tests/wpt/meta/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html.ini @@ -0,0 +1,3 @@ +[order-in-new-document-navigation-iframe.html] + [pagereveal event fires and in correct order on new-document navigation in an iframe] + expected: FAIL diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini new file mode 100644 index 00000000000..5d17a8e9419 --- /dev/null +++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini @@ -0,0 +1,3 @@ +[traverse_the_history_2.html] + [Multiple history traversals, last would be aborted] + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini b/tests/wpt/meta/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini new file mode 100644 index 00000000000..3e854890a7f --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/manual/filters/svg-filter-lh-rlh.html.ini @@ -0,0 +1,2 @@ +[svg-filter-lh-rlh.html] + expected: FAIL diff --git a/tests/wpt/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini b/tests/wpt/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini index 07d015249a0..a82f2a33c26 100644 --- a/tests/wpt/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini +++ b/tests/wpt/meta/html/dom/documents/dom-tree-accessors/Document.currentScript.html.ini @@ -1,4 +1,4 @@ [Document.currentScript.html] - expected: CRASH + expected: TIMEOUT [Script script-svg] expected: NOTRUN diff --git a/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini b/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini index 8b8af2b9c2e..2ef0896e3b3 100644 --- a/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini +++ b/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini @@ -1,3 +1,4 @@ [document-base-url-window-initiator-is-not-opener.https.window.html] + expected: TIMEOUT [window.open() gets base url from initiator not opener.] expected: [FAIL, PASS, TIMEOUT] diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini index d7d0d3ef89d..24903b5f66f 100644 --- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini +++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini @@ -1,4 +1,4 @@ [iframe_sandbox_popups_escaping-1.html] expected: TIMEOUT [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini index 6a420504feb..d4b2e4435a0 100644 --- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini +++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini @@ -1,3 +1,3 @@ [iframe_sandbox_popups_escaping-3.html] [Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation-sticky.tentative.sub.window.js.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation-sticky.tentative.sub.window.js.ini index c2f7bee1885..5bccf008873 100644 --- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation-sticky.tentative.sub.window.js.ini +++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/sandbox-top-navigation-user-activation-sticky.tentative.sub.window.js.ini @@ -1,3 +1,4 @@ [sandbox-top-navigation-user-activation-sticky.tentative.sub.window.html] + expected: TIMEOUT [Allow top with user activation + user activation] - expected: FAIL + expected: TIMEOUT diff --git a/tests/wpt/meta/mediasession/mediametadata.html.ini b/tests/wpt/meta/mediasession/mediametadata.html.ini index 5138a8e9292..695f7b35bbb 100644 --- a/tests/wpt/meta/mediasession/mediametadata.html.ini +++ b/tests/wpt/meta/mediasession/mediametadata.html.ini @@ -40,3 +40,15 @@ [Test that the base URL of MediaImage is the base URL of entry setting object] expected: FAIL + + [Test that MediaMetadata is read/write] + expected: FAIL + + [Test that MediaMetadata.artwork can't be modified] + expected: FAIL + + [Test that MediaMetadata.chapterInfo is Frozen] + expected: FAIL + + [Test that MediaMetadata.chapterInfo's artwork returns parsed urls] + expected: FAIL diff --git a/tests/wpt/meta/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js.ini b/tests/wpt/meta/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js.ini index ffbdcb66626..ff04c7a9e96 100644 --- a/tests/wpt/meta/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js.ini +++ b/tests/wpt/meta/performance-timeline/not-restored-reasons/performance-navigation-timing-iframes-without-attributes.tentative.window.js.ini @@ -1,4 +1,3 @@ [performance-navigation-timing-iframes-without-attributes.tentative.window.html] - expected: TIMEOUT [RemoteContextHelper navigation using BFCache] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/webmessaging/with-ports/018.html.ini b/tests/wpt/meta/webmessaging/with-ports/018.html.ini deleted file mode 100644 index b7b36c1d3a4..00000000000 --- a/tests/wpt/meta/webmessaging/with-ports/018.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[018.html] - expected: TIMEOUT - [origin of the script that invoked the method, javascript:] - expected: TIMEOUT diff --git a/tests/wpt/tests/.azure-pipelines.yml b/tests/wpt/tests/.azure-pipelines.yml index 36e745a87f1..c018c592d1d 100644 --- a/tests/wpt/tests/.azure-pipelines.yml +++ b/tests/wpt/tests/.azure-pipelines.yml @@ -103,23 +103,11 @@ jobs: - template: tools/ci/azure/install_fonts.yml - template: tools/ci/azure/install_certs.yml - template: tools/ci/azure/color_profile.yml - - template: tools/ci/azure/install_chrome.yml - - template: tools/ci/azure/install_firefox.yml - template: tools/ci/azure/install_safari.yml - template: tools/ci/azure/update_hosts.yml - template: tools/ci/azure/update_manifest.yml - script: | set -eux -o pipefail - ./wpt run --yes --no-manifest-update --manifest MANIFEST.json --metadata infrastructure/metadata/ --log-mach - --log-mach-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_macos_chrome.json --channel dev chrome infrastructure/ - condition: succeededOrFailed() - displayName: 'Run tests (Chrome Dev)' - - script: | - set -eux -o pipefail - ./wpt run --yes --no-manifest-update --manifest MANIFEST.json --metadata infrastructure/metadata/ --log-mach - --log-mach-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_macos_firefox.json --channel nightly firefox infrastructure/ - condition: succeededOrFailed() - displayName: 'Run tests (Firefox Nightly)' - - script: | - set -eux -o pipefail export SYSTEM_VERSION_COMPAT=0 ./wpt run --yes --no-manifest-update --manifest MANIFEST.json --metadata infrastructure/metadata/ --log-mach - --log-mach-level info --log-wptreport $(Build.ArtifactStagingDirectory)/wpt_report_macos_safari.json --channel preview safari infrastructure/ condition: succeededOrFailed() diff --git a/tests/wpt/tests/IndexedDB/idb-binary-key-detached.htm b/tests/wpt/tests/IndexedDB/idb-binary-key-detached.htm index ac6fc2ef980..a4ce3fbce00 100644 --- a/tests/wpt/tests/IndexedDB/idb-binary-key-detached.htm +++ b/tests/wpt/tests/IndexedDB/idb-binary-key-detached.htm @@ -23,7 +23,7 @@ indexeddb_test( worker.postMessage('', [buffer]); assert_equals(array.byteLength, 0); - assert_throws_js(TypeError, () => { store.put('', buffer); }); + assert_throws_dom("DataError", () => { store.put('', buffer); }); t.done(); }, 'Detached ArrayBuffer' @@ -43,7 +43,7 @@ indexeddb_test( worker.postMessage('', [array.buffer]); assert_equals(array.length, 0); - assert_throws_js(TypeError, () => { store.put('', array); }); + assert_throws_dom("DataError", () => { store.put('', array); }); t.done(); }, 'Detached TypedArray' diff --git a/tests/wpt/tests/compute-pressure/WEB_FEATURES.yml b/tests/wpt/tests/compute-pressure/WEB_FEATURES.yml new file mode 100644 index 00000000000..ae8464657b1 --- /dev/null +++ b/tests/wpt/tests/compute-pressure/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: compute-pressure + files: "**" diff --git a/tests/wpt/tests/cookies/resources/cookie-test.js b/tests/wpt/tests/cookies/resources/cookie-test.js index a909e4d72fa..8299c473178 100644 --- a/tests/wpt/tests/cookies/resources/cookie-test.js +++ b/tests/wpt/tests/cookies/resources/cookie-test.js @@ -76,7 +76,6 @@ function httpCookieTest(cookie, expectedValue, name, defaultPath = true, } catch { if (allowFetchFailure) { skipAssertions = true; - resolve(); } else { reject('Failed to fetch /cookies/resources/cookie.py'); } diff --git a/tests/wpt/tests/credential-management/fedcm-authz/fedcm-disclosure-text-shown.https.html b/tests/wpt/tests/credential-management/fedcm-authz/fedcm-disclosure-text-shown.https.html new file mode 100644 index 00000000000..e3f303ec4c9 --- /dev/null +++ b/tests/wpt/tests/credential-management/fedcm-authz/fedcm-disclosure-text-shown.https.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>Federated Credential Management API network request tests.</title> +<link rel="help" href="https://fedidcg.github.io/FedCM"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<body> + +<script type="module"> +import {fedcm_test, + request_options_with_mediation_required, + fedcm_get_and_select_first_account} from '../support/fedcm-helper.sub.js'; + +fedcm_test(async t => { + let options = request_options_with_mediation_required("manifest_check_disclosure_shown_false.json"); + options.identity.providers[0].clientId = "0"; + options.identity.providers[0].scope = ["non_default_scope"]; + const cred = await fedcm_get_and_select_first_account(t, options); + assert_equals(cred.token, "token"); + assert_equals(cred.isAutoSelected, false); +}, "We should send disclosure_text_shown=false when custom scopes are passed."); + +</script> diff --git a/tests/wpt/tests/credential-management/support/fedcm/manifest_check_disclosure_shown_false.json b/tests/wpt/tests/credential-management/support/fedcm/manifest_check_disclosure_shown_false.json new file mode 100644 index 00000000000..47ca63edc4f --- /dev/null +++ b/tests/wpt/tests/credential-management/support/fedcm/manifest_check_disclosure_shown_false.json @@ -0,0 +1,7 @@ +{ + "accounts_endpoint": "accounts.py", + "client_metadata_endpoint": "client_metadata.py", + "id_assertion_endpoint": "token_check_disclosure_shown_false.py", + "login_url": "login.html" +} + diff --git a/tests/wpt/tests/credential-management/support/fedcm/token_check_disclosure_shown_false.py b/tests/wpt/tests/credential-management/support/fedcm/token_check_disclosure_shown_false.py new file mode 100644 index 00000000000..f4b732053ff --- /dev/null +++ b/tests/wpt/tests/credential-management/support/fedcm/token_check_disclosure_shown_false.py @@ -0,0 +1,16 @@ +import importlib +error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check") + +def main(request, response): + request_error = error_checker.tokenCheck(request) + if (request_error): + return request_error + + if request.POST.get(b"disclosure_text_shown") != b"false": + return (560, [], "disclosure_text_shown is not false") + + response.headers.set(b"Content-Type", b"application/json") + response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"Origin")) + response.headers.set(b"Access-Control-Allow-Credentials", "true") + + return "{\"token\": \"token\"}" diff --git a/tests/wpt/tests/css/compositing/background-blending/crashtests/bgblend-root-change.html b/tests/wpt/tests/css/compositing/background-blending/crashtests/bgblend-root-change.html new file mode 100644 index 00000000000..06db0535745 --- /dev/null +++ b/tests/wpt/tests/css/compositing/background-blending/crashtests/bgblend-root-change.html @@ -0,0 +1,17 @@ +<style> +* { + position: sticky; + border-left: double 488200679.54Q hsla(-39 5% 68% / 7%) !important; + box-shadow: 172vmax 60991vmax 32in 106cm hsl(-57532411.87deg, 70%, 54%); + background-blend-mode: overlay; + background: url(data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=) local content-box space space 0em / 15438983.37cm auto; +} +</style> +<script> +window.addEventListener("load", () => { + let a = document.createElementNS("http://www.w3.org/1998/Math/MathML", "math") + a.setAttribute("href", "x") + a.autofocus = true + document.documentElement.appendChild(a) +}) +</script> diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor-ref.html b/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor-ref.html new file mode 100644 index 00000000000..72026a2f63e --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor-ref.html @@ -0,0 +1,33 @@ +<!doctype html> +<style> +body { + width: 150vw; + height: 150vh; +} +.anchor { + width: 50px; + height: 50px; + background: orange; +} +#anchor1 { + position: absolute; + top: 100px; + left: 350px; +} +#anchor2 { + position:fixed; + right: 0; + bottom: 0; +} +#anchored { + position: absolute; + top: 50px; + left: 350px; + width: 50px; + height: 50px; + background: blue; +} +</style> +<div class="anchor" id="anchor1"></div> +<div class="anchor" id="anchor2"></div> +<div id="anchored"></div> diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor.html b/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor.html new file mode 100644 index 00000000000..904aa55180d --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-switch-from-fixed-anchor.html @@ -0,0 +1,57 @@ +<!doctype html> +<html class=reftest-wait> +<meta charset="utf-8"> +<title>CSS Anchor Positioning Test: @position-try with different default anchors, + switching to fixed-position anchor on scroll and back on another scroll</title> +<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-rule"> +<link rel="match" href="position-try-switch-from-fixed-anchor-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="/common/rendering-utils.js"></script> +<style> +body { + width: 150vw; + height: 150vh; +} +.anchor { + width: 50px; + height: 50px; + background: orange; +} +#anchor1 { + anchor-name: --anchor1; + position: absolute; + top: 100px; + left: 350px; +} +#anchor2 { + anchor-name: --anchor2; + position:fixed; + right: 0; + bottom: 0; +} +#anchored { + position-anchor: --anchor1; + inset-area: top; + position-try-options: --fixed; + position: fixed; + width: 50px; + height: 50px; + background: blue; +} +@position-try --fixed { + inset-area: top left; + position-anchor: --anchor2; +} +</style> +<div class="anchor" id="anchor1"></div> +<div class="anchor" id="anchor2"></div> +<div id="anchored"></div> +<script> +waitForAtLeastOneFrame().then(() => { + window.scrollTo(250, 100); + waitForAtLeastOneFrame().then(() => { + window.scrollTo(0, 0); + takeScreenshot(); + }); +}); +</script> diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor-ref.html b/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor-ref.html new file mode 100644 index 00000000000..254cbf3df45 --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor-ref.html @@ -0,0 +1,37 @@ +<!doctype html> +<meta charset="utf-8"> +<style> +body { + width: 150vw; + height: 150vh; +} +.anchor { + width: 50px; + height: 50px; + background: orange; +} +#anchor1 { + position: absolute; + top: 100px; + left: 350px; +} +#anchor2 { + position:fixed; + right: 0; + bottom: 0; +} +#anchored { + position: fixed; + right: 50px; + bottom: 50px; + width: 50px; + height: 50px; + background: blue; +} +</style> +<div class="anchor" id="anchor1"></div> +<div class="anchor" id="anchor2"></div> +<div id="anchored"></div> +<script> +window.scrollTo(250, 100); +</script> diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor.html b/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor.html new file mode 100644 index 00000000000..54fcb2e4df3 --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-switch-to-fixed-anchor.html @@ -0,0 +1,53 @@ +<!doctype html> +<html class=reftest-wait> +<meta charset="utf-8"> +<title>CSS Anchor Positioning Test: @position-try with different default anchors, switching to fixed-position anchor on scroll</title> +<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-rule"> +<link rel="match" href="position-try-switch-to-fixed-anchor-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="/common/rendering-utils.js"></script> +<style> +body { + width: 150vw; + height: 150vh; +} +.anchor { + width: 50px; + height: 50px; + background: orange; +} +#anchor1 { + anchor-name: --anchor1; + position: absolute; + top: 100px; + left: 350px; +} +#anchor2 { + anchor-name: --anchor2; + position:fixed; + right: 0; + bottom: 0; +} +#anchored { + position-anchor: --anchor1; + inset-area: top; + position-try-options: --fixed; + position: fixed; + width: 50px; + height: 50px; + background: blue; +} +@position-try --fixed { + inset-area: top left; + position-anchor: --anchor2; +} +</style> +<div class="anchor" id="anchor1"></div> +<div class="anchor" id="anchor2"></div> +<div id="anchored"></div> +<script> +waitForAtLeastOneFrame().then(() => { + window.scrollTo(250, 100); + takeScreenshot(); +}); +</script> diff --git a/tests/wpt/tests/css/css-break/relpos-inline-hit-testing.html b/tests/wpt/tests/css/css-break/relpos-inline-hit-testing.html index ca0c961ca22..aa7cd5ad97c 100644 --- a/tests/wpt/tests/css/css-break/relpos-inline-hit-testing.html +++ b/tests/wpt/tests/css/css-break/relpos-inline-hit-testing.html @@ -2,7 +2,6 @@ <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> <link rel="help" href="https://www.w3.org/TR/css-break-3/#transforms"> <link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#relative-positioning"> -<link rel="match" href="relpos-inline-ref.html"> <style> body { margin: 8px; diff --git a/tests/wpt/tests/css/css-color/LICENSE b/tests/wpt/tests/css/css-color/LICENSE deleted file mode 100644 index d47f50cca8a..00000000000 --- a/tests/wpt/tests/css/css-color/LICENSE +++ /dev/null @@ -1,41 +0,0 @@ -The tests in this directory are Copyright (c) 2007-2008, The -Mozilla Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or -without modification, are permitted provided that the following -conditions are met: - - * Redistributions of source code must retain the above - copyright notice, this list of conditions and the following - disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - * Neither the name of the The Mozilla Foundation nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - -Alternatively, these tests may be used under the terms of the W3C -Document License at -http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231 -in which case the provisions of the W3C Document License are -applicable instead of those above. diff --git a/tests/wpt/tests/css/css-color/WEB_FEATURES.yml b/tests/wpt/tests/css/css-color/WEB_FEATURES.yml index 8910deab28b..cbb0f23ede2 100644 --- a/tests/wpt/tests/css/css-color/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-color/WEB_FEATURES.yml @@ -16,6 +16,9 @@ features: files: - lab-* - lch-* +- name: light-dark + files: + - light-dark-* - name: oklab files: - oklab-* diff --git a/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html b/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html index ac2f9c87aac..5a58ae61798 100644 --- a/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html +++ b/tests/wpt/tests/css/css-color/parsing/color-computed-relative-color.html @@ -791,7 +791,6 @@ for (const colorSpace of ["xyz-d50", "xyz-d65"]) { fuzzy_test_computed_color(`color(from rgb(from color(${colorSpace} 0.99 0.88 0.77) r g b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); fuzzy_test_computed_color(`color(from hsl(from color(${colorSpace} 0.99 0.88 0.77) h s l) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); - fuzzy_test_computed_color(`color(from hwb(from color(${colorSpace} 0.99 0.88 0.77) h w b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); fuzzy_test_computed_color(`color(from lab(from color(${colorSpace} 0.99 0.88 0.77) l a b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); fuzzy_test_computed_color(`color(from lch(from color(${colorSpace} 0.99 0.88 0.77) l c h) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); fuzzy_test_computed_color(`color(from oklab(from color(${colorSpace} 0.99 0.88 0.77) l a b) ${colorSpace} x y z)`, `color(${colorSpace} 0.99 0.88 0.77)`, 0.0001); diff --git a/tests/wpt/tests/css/css-content/parsing/content-valid.html b/tests/wpt/tests/css/css-content/parsing/content-valid.html index 5c755861074..60d03a4d4c3 100644 --- a/tests/wpt/tests/css/css-content/parsing/content-valid.html +++ b/tests/wpt/tests/css/css-content/parsing/content-valid.html @@ -42,7 +42,7 @@ test_valid_value_combinations("content", `counters(counter-name, ".", counter-st test_valid_value_combinations("content", `counters(counter-name, ".", dECiMaL)`, `counters(counter-name, ".")`); test_valid_value_combinations("content", `counters(counter-name, ".", DECIMAL)`, `counters(counter-name, ".")`); -test_valid_value_combinations("content", `url("https://www.example.com/picture.svg")`); +test_valid_value_combinations("content", `url("picture.svg")`); test_valid_value_combinations("content", `"hello"`); @@ -52,7 +52,7 @@ test_valid_value_combinations("content", `counter(counter-name) "potato"`); test_valid_value_combinations("content", `counters(counter-name, ".") "potato"`); test_valid_value_combinations("content", `"(" counters(counter-name, ".", counter-style) ")"`); test_valid_value_combinations("content", `open-quote "hello" "world" close-quote`); -test_valid_value_combinations("content", `url("https://www.example.com/picture.svg") "hello"`); +test_valid_value_combinations("content", `url("picture.svg") "hello"`); </script> </body> </html> diff --git a/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-004.html b/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-004.html index 00cfa520690..83b119e3f16 100644 --- a/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-004.html +++ b/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-004.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> <link rel="help" href="https://drafts.csswg.org/css-flexbox/#intrinsic-sizes"> -<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/resources/check-layout-th.js"></script> diff --git a/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-005.html b/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-005.html index a753619c62f..15ca5a57ec4 100644 --- a/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-005.html +++ b/tests/wpt/tests/css/css-flexbox/intrinsic-size/col-wrap-005.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="David Grogan" href="mailto:dgrogan@chromium.org"> <link rel="help" href="https://drafts.csswg.org/css-flexbox/#intrinsic-sizes"> -<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/resources/check-layout-th.js"></script> diff --git a/tests/wpt/tests/css/css-flexbox/padding-overflow-crash.html b/tests/wpt/tests/css/css-flexbox/padding-overflow.html index 163be06a917..163be06a917 100644 --- a/tests/wpt/tests/css/css-flexbox/padding-overflow-crash.html +++ b/tests/wpt/tests/css/css-flexbox/padding-overflow.html diff --git a/tests/wpt/tests/css/css-flexbox/parsing/flex-shorthand.html b/tests/wpt/tests/css/css-flexbox/parsing/flex-shorthand.html index 1d74df80834..d22957983b1 100644 --- a/tests/wpt/tests/css/css-flexbox/parsing/flex-shorthand.html +++ b/tests/wpt/tests/css/css-flexbox/parsing/flex-shorthand.html @@ -64,6 +64,12 @@ test_shorthand_value('flex', '1 0 max-content', { 'flex-shrink': '0', 'flex-basis': 'max-content' }); + +test_shorthand_value('flex', 'auto 1 2', { + 'flex-grow': '1', + 'flex-shrink': '2', + 'flex-basis': 'auto' +}); </script> </body> </html> diff --git a/tests/wpt/tests/css/css-fonts/WEB_FEATURES.yml b/tests/wpt/tests/css/css-fonts/WEB_FEATURES.yml index 5e69c923abf..6739fa2d06a 100644 --- a/tests/wpt/tests/css/css-fonts/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-fonts/WEB_FEATURES.yml @@ -6,7 +6,19 @@ features: - palette-values-rule-* - name: font-synthesis files: - - font-synthesis-* + - font-synthesis-0*.html +- name: font-synthesis-position + files: + - font-synthesis-position* +- name: font-synthesis-small-caps + files: + - font-synthesis-small-caps* +- name: font-synthesis-style + files: + - font-synthesis-style* +- name: font-synthesis-weight + files: + - font-synthesis-weight* - name: font-variant-alternates files: - alternates-order.html diff --git a/tests/wpt/tests/css/css-fonts/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-fonts/parsing/WEB_FEATURES.yml index 6a24d269b48..a3bc09cb1f1 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-fonts/parsing/WEB_FEATURES.yml @@ -8,7 +8,21 @@ features: - font-palette-values-* - name: font-synthesis files: - - font-synthesis-* + - font-synthesis-computed.html + - font-synthesis-invalid.html + - font-synthesis-valid.html +- name: font-synthesis-position + files: + - font-synthesis-position* +- name: font-synthesis-small-caps + files: + - font-synthesis-small-caps* +- name: font-synthesis-style + files: + - font-synthesis-style* +- name: font-synthesis-weight + files: + - font-synthesis-weight* - name: font-variant-alternates files: - font-variant-alternates-* diff --git a/tests/wpt/tests/css/css-highlight-api/WEB_FEATURES.yml b/tests/wpt/tests/css/css-highlight-api/WEB_FEATURES.yml new file mode 100644 index 00000000000..0ce52013129 --- /dev/null +++ b/tests/wpt/tests/css/css-highlight-api/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: highlight + files: "**" diff --git a/tests/wpt/tests/css/css-images/WEB_FEATURES.yml b/tests/wpt/tests/css/css-images/WEB_FEATURES.yml new file mode 100644 index 00000000000..0a1af199830 --- /dev/null +++ b/tests/wpt/tests/css/css-images/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: conic-gradients + files: + - "*conic*" diff --git a/tests/wpt/tests/css/css-inline/baseline-source/WEB_FEATURES.yml b/tests/wpt/tests/css/css-inline/baseline-source/WEB_FEATURES.yml new file mode 100644 index 00000000000..f399a6dc6f7 --- /dev/null +++ b/tests/wpt/tests/css/css-inline/baseline-source/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: baseline-source + files: "**" diff --git a/tests/wpt/tests/css/css-lists/counter-set-001-ref.html b/tests/wpt/tests/css/css-lists/counter-set-001-ref.html index 301197904a5..2b5eb90ccfc 100644 --- a/tests/wpt/tests/css/css-lists/counter-set-001-ref.html +++ b/tests/wpt/tests/css/css-lists/counter-set-001-ref.html @@ -21,17 +21,17 @@ html,body { <span>6</span><!-- "6" --> <span>0</span><!-- "0" --> <x> - <span>2</span><!-- "2" --> + <span>0.2</span><!-- "0.2" --> </x> -<span>3</span><!-- "3" --> +<span>0.3</span><!-- "0.3" --> <x> - <span>0</span><!-- "0" --> - <span>2</span><!-- "2" --> + <span>0.3.0</span><!-- "0.3.0" --> + <span>0.3.2</span><!-- "0.3.2" --> <x> - <span>2.5</span><!-- "2.5" --> + <span>0.3.2.5</span><!-- "0.3.2.5" --> </x> </x> -<span>3</span><!-- "3" --> +<span>0.3.3</span><!-- "0.3.3" --> </body> </html> diff --git a/tests/wpt/tests/css/css-lists/counter-set-001.html b/tests/wpt/tests/css/css-lists/counter-set-001.html index 4e28367798a..6ec53e3bfa1 100644 --- a/tests/wpt/tests/css/css-lists/counter-set-001.html +++ b/tests/wpt/tests/css/css-lists/counter-set-001.html @@ -24,17 +24,17 @@ span::before { content: counters(n, '.'); } <span style="counter-set: n 6; counter-increment: n 2"></span><!-- "6" --> <span style="counter-set: n; counter-increment: n 2"></span><!-- "0" --> <x style="counter-reset: n 9"> - <span style="counter-set: n 2"></span><!-- "2" --> + <span style="counter-set: n 2"></span><!-- "0.2" --> </x> -<span style="counter-increment: n"></span><!-- "3" --> +<span style="counter-increment: n"></span><!-- "0.3" --> <x style="counter-reset: n 9"> - <span style="counter-set: n"></span><!-- "0" --> - <span style="counter-set: n 2"></span><!-- "2" --> + <span style="counter-set: n"></span><!-- "0.3.0" --> + <span style="counter-set: n 2"></span><!-- "0.3.2" --> <x style="counter-reset: n 1"> - <span style="counter-set: n 5"></span><!-- "2.5" --> + <span style="counter-set: n 5"></span><!-- "0.3.2.5" --> </x> </x> -<span style="counter-increment: n"></span><!-- "3" --> +<span style="counter-increment: n"></span><!-- "0.3.3" --> </body> </html> diff --git a/tests/wpt/tests/css/css-lists/counters-005-ref.html b/tests/wpt/tests/css/css-lists/counters-005-ref.html new file mode 100644 index 00000000000..232bab76a10 --- /dev/null +++ b/tests/wpt/tests/css/css-lists/counters-005-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Lists Ref Test: Implied counter scopes by 'counter-increment'</title> + <link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org"> + <link rel="help" href="https://drafts.csswg.org/css-lists/#propdef-counter-increment"> + <style type="text/css"> + body { white-space: nowrap; } + </style> + </head> + <body> + + <p>The following two lines should be identical:</p> + + <div>B 1 1.0 1 1.0</div> + <div>B 1 1.0 1 1.0</div> + + </body> +</html> diff --git a/tests/wpt/tests/css/css-lists/counters-005.html b/tests/wpt/tests/css/css-lists/counters-005.html new file mode 100644 index 00000000000..12908e64720 --- /dev/null +++ b/tests/wpt/tests/css/css-lists/counters-005.html @@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Lists: Implied counter scopes by 'counter-increment'</title> + <link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org"> + <link rel="help" href="https://drafts.csswg.org/css-lists/#propdef-counter-increment"> + <link rel="match" href="counters-005-ref.html"> + <style type="text/css"> + body { white-space: nowrap; } + .i { counter-increment: c 1; } + .ib:before { counter-increment: c 1; content: "B" } + .r { counter-reset: c 0; } + .u:before { content: counters(c, ".") " "; } + </style> + </head> + <body> + + <p>The following two lines should be identical:</p> + + <div> + <span class="ib"> + <span class="u"></span> + <span class="r"> + <span class="u"></span> + </span> + </span> + <span class="i"> + <span class="u"></span> + <span class="r"> + <span class="u"></span> + </span> + </span> + </div> + + <div>B 1 1.0 1 1.0</div> + + </body> +</html> diff --git a/tests/wpt/tests/css/css-lists/li-without-ul-counter-crash.html b/tests/wpt/tests/css/css-lists/li-without-ul-counter-crash.html new file mode 100644 index 00000000000..e95c675eea4 --- /dev/null +++ b/tests/wpt/tests/css/css-lists/li-without-ul-counter-crash.html @@ -0,0 +1,6 @@ +<!doctype html> +<html> +<link rel="help" href="http://crbug.com/339592908"> +<div><li></li></div> +<div><li style="display: inline-flex;"></li></div> +</html> diff --git a/tests/wpt/tests/css/css-masking/WEB_FEATURES.yml b/tests/wpt/tests/css/css-masking/WEB_FEATURES.yml new file mode 100644 index 00000000000..76ea5c208e9 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/WEB_FEATURES.yml @@ -0,0 +1,6 @@ +features: +- name: masks + # To match the scope of the feature in web-features, this should only include + # tests for https://drafts.fxtf.org/css-masking-1/#positioned-masks. + files: + - mask-shorthand-subproperties-reset.html diff --git a/tests/wpt/tests/css/css-masking/animations/WEB_FEATURES.yml b/tests/wpt/tests/css/css-masking/animations/WEB_FEATURES.yml new file mode 100644 index 00000000000..758ef35275e --- /dev/null +++ b/tests/wpt/tests/css/css-masking/animations/WEB_FEATURES.yml @@ -0,0 +1,8 @@ +features: +- name: masks + # To match the scope of the feature in web-features, this should only include + # tests for https://drafts.fxtf.org/css-masking-1/#positioned-masks. + files: + - mask-image-interpolation.html + - mask-no-interpolation.html + - mask-position-interpolation.html diff --git a/tests/wpt/tests/css/css-masking/mask-image/WEB_FEATURES.yml b/tests/wpt/tests/css/css-masking/mask-image/WEB_FEATURES.yml new file mode 100644 index 00000000000..b5bbd438dac --- /dev/null +++ b/tests/wpt/tests/css/css-masking/mask-image/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: masks + files: "**" diff --git a/tests/wpt/tests/css/css-masking/mask-image/mask-image-svg-viewport-changed.html b/tests/wpt/tests/css/css-masking/mask-image/mask-image-svg-viewport-changed.html new file mode 100644 index 00000000000..156317b2517 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/mask-image/mask-image-svg-viewport-changed.html @@ -0,0 +1,18 @@ +<!doctype html> +<title>Change of viewport affecting mask content</title> +<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#the-mask-image"> +<link rel="help" href="https://drafts.fxtf.org/css-masking-1/#svg-masks"> +<link rel="match" href="../clip-path/reference/green-100x100.html"> +<div id="container" style="width: 0%"> + <svg style="width: 100%"> + <mask id="mask"> + <rect width="100%" height="100%" fill="white"/> + </mask> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" mask="url(#mask)"/> + </svg> +</div> +<script> + document.body.offsetTop; + document.getElementById('container').style.width = '100%'; +</script> diff --git a/tests/wpt/tests/css/css-masking/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-masking/parsing/WEB_FEATURES.yml new file mode 100644 index 00000000000..0837d0ddf90 --- /dev/null +++ b/tests/wpt/tests/css/css-masking/parsing/WEB_FEATURES.yml @@ -0,0 +1,10 @@ +features: +- name: masks + # To match the scope of the feature in web-features, this should only include + # tests for https://drafts.fxtf.org/css-masking-1/#positioned-masks. + files: + - mask-composite-* + - mask-computed.html + - mask-invalid.html + - mask-position-* + - mask-repeat-* diff --git a/tests/wpt/tests/css/css-overflow/WEB_FEATURES.yml b/tests/wpt/tests/css/css-overflow/WEB_FEATURES.yml new file mode 100644 index 00000000000..81358de0c75 --- /dev/null +++ b/tests/wpt/tests/css/css-overflow/WEB_FEATURES.yml @@ -0,0 +1,30 @@ +features: +- name: overflow-shorthand + files: + # This is all overflow-* except overflow-auto-scrollbar-gutter-intrinsic-* and + # overflow-scroll-*. TODO: convert to an exclusion patterns, or rename tests + # to make overflow-* only match the below. + - overflow-abpos-transform.html + - overflow-body-propagation-* + - overflow-canvas.html + - overflow-clip-* + - overflow-codependent-scrollbars.html + - overflow-ellipsis-dynamic-001.html + - overflow-empty-child-box.html + - overflow-hidden-resize-with-stacking-context-child.html + - overflow-img-* + - overflow-img.html + - overflow-inline-block-with-opacity.html + - overflow-inline-transform-relative.html + - overflow-negative-margin-dynamic.html + - overflow-negative-margin.html + - overflow-no-frameset-propagation.html + - overflow-no-interpolation.html + - overflow-overlay.html + - overflow-padding.html + - overflow-recalc-001.html + - overflow-replaced-element-001.html + - overflow-shorthand-001.html + - overflow-video.html + - rounded-overflow-* + - select-size-overflow-001.html diff --git a/tests/wpt/tests/css/css-overflow/overfow-outside-padding.html b/tests/wpt/tests/css/css-overflow/overflow-outside-padding.html index 792f7b87351..792f7b87351 100644 --- a/tests/wpt/tests/css/css-overflow/overfow-outside-padding.html +++ b/tests/wpt/tests/css/css-overflow/overflow-outside-padding.html diff --git a/tests/wpt/tests/css/css-page/page-box-001-print-ref.html b/tests/wpt/tests/css/css-page/page-box-001-print-ref.html new file mode 100644 index 00000000000..d9ab323877f --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-001-print-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + @page { + margin: 0; + } + body { + margin: 100px; + background: yellow; + } +</style> +The entire page should be yellow. diff --git a/tests/wpt/tests/css/css-page/page-box-001-print.html b/tests/wpt/tests/css/css-page/page-box-001-print.html new file mode 100644 index 00000000000..35c2f06c93b --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-001-print.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-properties"> +<link rel="match" href="page-box-001-print-ref.html"> +<style> + @page { + margin: 0; + background: yellow; + } + body { + margin: 100px; + } +</style> +The entire page should be yellow. diff --git a/tests/wpt/tests/css/css-page/page-box-002-print-ref.html b/tests/wpt/tests/css/css-page/page-box-002-print-ref.html new file mode 100644 index 00000000000..e1ee4ab5d14 --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-002-print-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + @page { + margin: 0; + } + body { + margin: 0; + background: #00f; + } +</style> +<div style="display:grid; height:100vh; background:#f008;"> + <div style="margin:8px;"> + This page should have a violet-ish background, not red, not blue. + </div> +</div> diff --git a/tests/wpt/tests/css/css-page/page-box-002-print.html b/tests/wpt/tests/css/css-page/page-box-002-print.html new file mode 100644 index 00000000000..3b87b6903dd --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-002-print.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-properties"> +<link rel="match" href="page-box-002-print-ref.html"> +<style> + @page { + margin: 0; + background: #00f; + } + body { + background: #f008; + } +</style> +This page should have a violet-ish background, not red, not blue. diff --git a/tests/wpt/tests/css/css-page/page-box-003-print-ref.html b/tests/wpt/tests/css/css-page/page-box-003-print-ref.html new file mode 100644 index 00000000000..e1ee4ab5d14 --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-003-print-ref.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + @page { + margin: 0; + } + body { + margin: 0; + background: #00f; + } +</style> +<div style="display:grid; height:100vh; background:#f008;"> + <div style="margin:8px;"> + This page should have a violet-ish background, not red, not blue. + </div> +</div> diff --git a/tests/wpt/tests/css/css-page/page-box-003-print.html b/tests/wpt/tests/css/css-page/page-box-003-print.html new file mode 100644 index 00000000000..44cc13555b5 --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-box-003-print.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-page-3/#page-properties"> +<link rel="match" href="page-box-003-print-ref.html"> +<style> + @page { + margin: 0; + background: #00f; + } + body { + background: linear-gradient(#f008, #f008); + } +</style> +This page should have a violet-ish background, not red, not blue. diff --git a/tests/wpt/tests/css/css-page/page-margin-007-print-ref.html b/tests/wpt/tests/css/css-page/page-margin-007-print-ref.html new file mode 100644 index 00000000000..20d16df19de --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-margin-007-print-ref.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<style> + @page { + size: 400px 200px; + margin: 0; + } + body { + margin: 0; + } + .pagebox { + display: flow-root; + } + .pagebox > div { + width: 300px; + background: gray; + } + .pagebox > div > div { + box-sizing: border-box; + border: solid; + width: 250px; + height: 100%; + } + .left { + margin: 50px; + height: 100px; + } + .left > div { + background: hotpink; + } + .left > div::before { + content: "Margins on every side."; + } + .right { + height: 200px; + } + .right > div { + background: cyan; + } + .right > div::before { + content: "No page margins."; + } + .first { + height: 200px; + margin-left: 50px; + } + .first > div { + background: yellow; + } +</style> + +<div class="pagebox"> + <div class="first"> + <div> + Every page should have a colored box as tall as the page area (gray area).<br> + This particular page should have a left-margin.<br> + There should be 7 pages. + </div> + </div> +</div> +<div class="pagebox"> + <div class="left"><div></div></div> +</div> +<div class="pagebox"> + <div class="right"><div></div></div> +</div> +<div class="pagebox"> + <div class="left"><div></div></div> +</div> +<div class="pagebox"> + <div class="right"><div></div></div> +</div> +<div class="pagebox"> + <div class="left"><div></div></div> +</div> +<div class="pagebox"> + <div class="right"><div></div></div> +</div> diff --git a/tests/wpt/tests/css/css-page/page-margin-007-print.html b/tests/wpt/tests/css/css-page/page-margin-007-print.html new file mode 100644 index 00000000000..c2045d0dac2 --- /dev/null +++ b/tests/wpt/tests/css/css-page/page-margin-007-print.html @@ -0,0 +1,62 @@ +<!DOCTYPE html> +<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> +<link rel="help" href="https://drafts.csswg.org/css-page-3/#at-page-rule"> +<link rel="match" href="page-margin-007-print-ref.html"> +<style> + @page { + size: 400px 200px; + margin: 0; + } + @page :first { + margin-left: 50px; + } + @page :left { + margin: 50px; + } + body { + margin: 0; + } + .container { + width: 300px; + background: gray; + } + .container > div { + box-sizing: border-box; + border: solid; + width: 250px; + } + .left { + height: 100px; + background: hotpink; + } + .left::before { + content: "Margins on every side."; + } + .right { + height: 200px; + background: cyan; + } + .right::before { + content: "No page margins."; + } + .first { + height: 200px; + background: yellow; + } +</style> + +<div class="container"> + <div class="first"> + Every page should have a colored box as tall as the page area (gray area).<br> + This particular page should have a left-margin.<br> + There should be 7 pages. + </div> + <div class="left"></div> + <div class="right"></div> + <div class="left"></div> +</div> +<div class="container" style="position:absolute;"> + <div class="right"></div> + <div class="left"></div> + <div class="right"></div> +</div> diff --git a/tests/wpt/tests/css/css-properties-values-api/crashtests/computed-property-universal-syntax.html b/tests/wpt/tests/css/css-properties-values-api/crashtests/computed-property-universal-syntax.html new file mode 100644 index 00000000000..b87f03b2df3 --- /dev/null +++ b/tests/wpt/tests/css/css-properties-values-api/crashtests/computed-property-universal-syntax.html @@ -0,0 +1,20 @@ +<!doctype html> +<meta charset=utf8> +<style> +@property --my-registered-property { + syntax: "<color>"; + inherits: false; + initial-value: #f0f2f5; +} + +.outer { + --unregistered-property: var(--my-registered-property); +} + +.inner { + --unregistered-property: #c6cfdb; +} +</style> +<div class="outer"> + <div class="inner"></div> +</div> diff --git a/tests/wpt/tests/css/css-pseudo/WEB_FEATURES.yml b/tests/wpt/tests/css/css-pseudo/WEB_FEATURES.yml new file mode 100644 index 00000000000..5dd44e39c8b --- /dev/null +++ b/tests/wpt/tests/css/css-pseudo/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: target-text + files: + - target-text-* diff --git a/tests/wpt/tests/css/css-pseudo/get-computed-style-crash.html b/tests/wpt/tests/css/css-pseudo/get-computed-style-crash.html new file mode 100644 index 00000000000..60e097cc8d1 --- /dev/null +++ b/tests/wpt/tests/css/css-pseudo/get-computed-style-crash.html @@ -0,0 +1,7 @@ +<!doctype html> +<body> +<script> + const PA_SIZE = 10; + window.getComputedStyle(document.body,'\\q' + 'q'.repeat(PA_SIZE)); + </script> +</body> diff --git a/tests/wpt/tests/css/css-ruby/position-relative.html b/tests/wpt/tests/css/css-ruby/position-relative.html new file mode 100644 index 00000000000..e3da0013101 --- /dev/null +++ b/tests/wpt/tests/css/css-ruby/position-relative.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-ruby/#ruby-layout"> +<link rel="stylesheet" href="/fonts/ahem.css"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +body { + font: 20px/1 Ahem; +} +</style> +<body> +<div id=container></div> +<script> +const container = document.querySelector('#container'); +test(() => { + container.innerHTML = '<ruby style="position:relative">base<rt>annotation</ruby>'; + const rtBefore = document.querySelector('rt').getBoundingClientRect(); + document.querySelector('ruby').style.left = '100px'; + const rtAfter = document.querySelector('rt').getBoundingClientRect(); + assert_equals(rtBefore.x + 100, rtAfter.x); +}, 'position:relative on a ruby should move the annotation together'); + +test(() => { + container.innerHTML = `<span style="position:relative"> + <ruby>base<rt>annotation</ruby></span>`; + const rubyBefore = document.querySelector('ruby').getBoundingClientRect(); + const rtBefore = document.querySelector('rt').getBoundingClientRect(); + document.querySelector('span').style.left = '100px'; + const rubyAfter = document.querySelector('ruby').getBoundingClientRect(); + const rtAfter = document.querySelector('rt').getBoundingClientRect(); + assert_equals(rubyBefore.x + 100, rubyAfter.x); + assert_equals(rtBefore.x + 100, rtAfter.x); +}, 'position:relative on a ruby parent should move the ruby and the annotation'); + +test(() => { + container.innerHTML = `b<ruby style="position:relative">base + <rt style="position:relative">annotation</ruby>`; + const rtBefore = document.querySelector('rt').getBoundingClientRect(); + document.querySelector('ruby').style.left = '100px'; + document.querySelector('rt').style.left = '10px'; + document.querySelector('rt').style.top = '-50px'; + const rtAfter = document.querySelector('rt').getBoundingClientRect(); + assert_equals(rtBefore.x + 110, rtAfter.x); + assert_equals(rtBefore.y - 50, rtAfter.y); +}, 'Accumulate position:relative offsets'); +</script> +</body> diff --git a/tests/wpt/tests/css/css-ruby/pseudo-first-line-ref.html b/tests/wpt/tests/css/css-ruby/pseudo-first-line-ref.html new file mode 100644 index 00000000000..55c96fb2d3c --- /dev/null +++ b/tests/wpt/tests/css/css-ruby/pseudo-first-line-ref.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<div>foo <ruby style="ruby-position:under">base<rt>annotation</rt></ruby><br> +bar <ruby>base<rt>annotation</rt></ruby></div> diff --git a/tests/wpt/tests/css/css-ruby/pseudo-first-line.html b/tests/wpt/tests/css/css-ruby/pseudo-first-line.html new file mode 100644 index 00000000000..180420d98a4 --- /dev/null +++ b/tests/wpt/tests/css/css-ruby/pseudo-first-line.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-ruby/#placement"> +<link rel="help" href="https://drafts.csswg.org/css-pseudo/#first-line-styling"> +<link rel="match" href="pseudo-first-line-ref.html"> +<style> +div::first-line { + ruby-position: under; +} +</style> +<div>foo <ruby>base<rt>annotation</rt></ruby><br> +bar <ruby>base<rt>annotation</rt></ruby></div> diff --git a/tests/wpt/tests/css/css-scroll-snap-2/resources/common.js b/tests/wpt/tests/css/css-scroll-snap-2/resources/common.js index 8dce29474d8..d95b605120b 100644 --- a/tests/wpt/tests/css/css-scroll-snap-2/resources/common.js +++ b/tests/wpt/tests/css/css-scroll-snap-2/resources/common.js @@ -9,7 +9,8 @@ function checkSnapEventSupport(event_type) { } function assertSnapEvent(evt, expected_ids) { - assert_equals(evt.bubbles, false, "snap events don't bubble"); + assert_equals(evt.bubbles, evt.target == document, + "snap events don't bubble except when fired at the document"); assert_false(evt.cancelable, "snap events are not cancelable."); assert_equals(evt.snapTargetBlock, expected_ids.block, "snap event supplied expected target in block axis"); diff --git a/tests/wpt/tests/css/css-scroll-snap-2/snapevents-at-document-bubble-to-window.html b/tests/wpt/tests/css/css-scroll-snap-2/snapevents-at-document-bubble-to-window.html new file mode 100644 index 00000000000..e50be0b6b25 --- /dev/null +++ b/tests/wpt/tests/css/css-scroll-snap-2/snapevents-at-document-bubble-to-window.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title> CSS Scroll Snap 2 Test: snapchanged event on the document bubbles</title> + <link rel="help" href="https://drafts.csswg.org/css-scroll-snap-2/#snap-events"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/css/css-scroll-snap-2/resources/common.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> +</head> + +<body> + <style> + :root { + margin: 0; + padding: 0; + scroll-snap-type: y mandatory; + } + + div { + position: absolute; + margin: 0px; + } + + #spacer { + width: 200vw; + height: 200vh; + } + + .snap_point { + width: 40vw; + height: 40vh; + scroll-snap-align: start; + } + + #snap_point_1 { + left: 0px; + top: 0px; + background-color: red; + } + + #snap_point_2 { + top: 40vh; + left: 40vw; + background-color: orange; + } + + #snap_point_3 { + left: 80vw; + top: 80vh; + background-color: blue; + } + </style> + <div id="spacer"></div> + <div id="snap_point_1" class="snap_point"></div> + <div id="snap_point_2" class="snap_point"></div> + <div id="snap_point_3" class="snap_point"></div> + + <script> + + promise_test(async(t) => { + await waitForCompositorCommit(); + + let snapchanging_promise = waitForSnapEvent(window, "snapchanging"); + let snapchanged_promise = waitForSnapEvent(window, "snapchanged"); + document.scrollingElement.scrollTo(0, snap_point_2.offsetTop); + let snapchanging_evt = await snapchanging_promise; + let snapchanged_evt = await snapchanged_promise; + + assertSnapEvent(snapchanging_evt, { inline: null, block: snap_point_2 }); + assertSnapEvent(snapchanged_evt, { inline: null, block: snap_point_2 }); + }, "snapchanged bubbles when fired at the document (addEventListener)."); + + promise_test(async(t) => { + await waitForScrollReset(t, document.scrollingElement); + await waitForCompositorCommit(); + + let snapchanging_promise = waitForSnapEvent(window, "snapchanging", + /*scroll_happens=*/true, + /*use_onsnap_member=*/true); + let snapchanged_promise = waitForSnapEvent(window, "snapchanged", + /*scroll_happens=*/true, + /*use_onsnap_member=*/true); + document.scrollingElement.scrollTo(0, snap_point_2.offsetTop); + let snapchanging_evt = await snapchanging_promise; + let snapchanged_evt = await snapchanged_promise; + + assertSnapEvent(snapchanging_evt, { inline: null, block: snap_point_2 }); + assertSnapEvent(snapchanged_evt, { inline: null, block: snap_point_2 }); + }, "snapchanged bubbles when fired at the document (onsnapchanged)."); + </script> +</body> + +</html> diff --git a/tests/wpt/tests/css/css-scroll-snap/WEB_FEATURES.yml b/tests/wpt/tests/css/css-scroll-snap/WEB_FEATURES.yml new file mode 100644 index 00000000000..d285b01e868 --- /dev/null +++ b/tests/wpt/tests/css/css-scroll-snap/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: scroll-snap + files: "**" diff --git a/tests/wpt/tests/css/css-shadow-parts/invalidation-part-pseudo.html b/tests/wpt/tests/css/css-shadow-parts/invalidation-part-pseudo.html index fca4a964dce..66df33a4b70 100644 --- a/tests/wpt/tests/css/css-shadow-parts/invalidation-part-pseudo.html +++ b/tests/wpt/tests/css/css-shadow-parts/invalidation-part-pseudo.html @@ -3,7 +3,6 @@ <link rel="help" href="https://drafts.csswg.org/css-shadow-parts" > <link rel="help" href="https://drafts.csswg.org/selectors/#matches"> <link href="https://drafts.csswg.org/selectors/#matches" rel="help"> -<link rel="match" href="interaction-with-nested-pseudo-class-ref.html"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> <script src="/resources/testdriver.js"></script> diff --git a/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003-ref.html b/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003-ref.html new file mode 100644 index 00000000000..2b19a838143 --- /dev/null +++ b/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<link rel="author" title="David Shin" href="dshin@mozilla.com"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871609"> +<style> +table { + border-collapse: collapse; +} +tr { + border: 1px solid grey; +} +</style> +<table> + <tr> + <td>X</td> + <td>X</td> + </tr> +</table> diff --git a/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003.html b/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003.html new file mode 100644 index 00000000000..073f67e669d --- /dev/null +++ b/tests/wpt/tests/css/css-tables/collapsed-border-partial-invalidation-003.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<link rel="author" title="David Shin" href="dshin@mozilla.com"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1871609"> +<link rel="match" href="collapsed-border-partial-invalidation-003-ref.html"> +<meta name="assert" content="Invalidating part of a border-collapsed table keeps border styling correctly."> +<style> +table { + border-collapse: collapse; +} +tr { + border: 1px solid grey; +} + +.foo { + border-right: 20px solid black; +} + +</style> +<table> + <tr> + <td id="cell" class="foo">X</td> + <td>X</td> + </tr> +</table> +<script> +onload = function () { + cell.classList.remove("foo"); + document.documentElement.className = ""; +} +</script> +</html> diff --git a/tests/wpt/tests/css/css-tables/colspan-001.html b/tests/wpt/tests/css/css-tables/colspan-001.html index e6cb440366c..11205521801 100644 --- a/tests/wpt/tests/css/css-tables/colspan-001.html +++ b/tests/wpt/tests/css/css-tables/colspan-001.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1430449"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> <p>There should be five squares.</p> <table cellspacing="0" cellpadding="0"> <tr> diff --git a/tests/wpt/tests/css/css-tables/colspan-002.html b/tests/wpt/tests/css/css-tables/colspan-002.html index 144cbef4850..16db9eb8bad 100644 --- a/tests/wpt/tests/css/css-tables/colspan-002.html +++ b/tests/wpt/tests/css/css-tables/colspan-002.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1430449"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> <p>There should be five squares.</p> <table cellspacing="0" cellpadding="0"> <tr> diff --git a/tests/wpt/tests/css/css-tables/colspan-003.html b/tests/wpt/tests/css/css-tables/colspan-003.html index 58e02b92878..70e1b218f05 100644 --- a/tests/wpt/tests/css/css-tables/colspan-003.html +++ b/tests/wpt/tests/css/css-tables/colspan-003.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> <link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1430449"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> <p>There should be five squares.</p> <table cellspacing="0" cellpadding="0"> <tr> diff --git a/tests/wpt/tests/css/css-tables/percent-height-overflow-auto-in-restricted-block-size-cell.html b/tests/wpt/tests/css/css-tables/percent-height-overflow-auto-in-restricted-block-size-cell.html index f5323084843..f5421c73653 100644 --- a/tests/wpt/tests/css/css-tables/percent-height-overflow-auto-in-restricted-block-size-cell.html +++ b/tests/wpt/tests/css/css-tables/percent-height-overflow-auto-in-restricted-block-size-cell.html @@ -1,7 +1,6 @@ <!DOCTYPE html> <link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org"> <link rel="help" href="https://drafts.csswg.org/css-tables-3/#row-layout"> -<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> <style> .table { display:table; height:100px; background:pink; } .cell { overflow:auto; width:100px; height:100%; background:blue; } diff --git a/tests/wpt/tests/css/css-text/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-text/parsing/WEB_FEATURES.yml index e06782e8f5b..fa39887d528 100644 --- a/tests/wpt/tests/css/css-text/parsing/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-text/parsing/WEB_FEATURES.yml @@ -2,3 +2,6 @@ features: - name: text-spacing-trim files: - text-spacing-trim-* +- name: text-wrap-pretty + files: + - text-wrap-pretty.html diff --git a/tests/wpt/tests/css/css-text/white-space/WEB_FEATURES.yml b/tests/wpt/tests/css/css-text/white-space/WEB_FEATURES.yml new file mode 100644 index 00000000000..89253912e85 --- /dev/null +++ b/tests/wpt/tests/css/css-text/white-space/WEB_FEATURES.yml @@ -0,0 +1,7 @@ +features: +- name: text-wrap-balance + files: + - text-wrap-balance-* +- name: text-wrap-nowrap + files: + - text-wrap-nowrap-* diff --git a/tests/wpt/tests/css/css-text/white-space/break-spaces-008.html b/tests/wpt/tests/css/css-text/white-space/break-spaces-008.html index 4612996c52c..dc9f5934f41 100644 --- a/tests/wpt/tests/css/css-text/white-space/break-spaces-008.html +++ b/tests/wpt/tests/css/css-text/white-space/break-spaces-008.html @@ -8,7 +8,7 @@ <link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all"> <link rel="match" href="reference/white-space-break-spaces-005-ref.html"> <meta name="flags" content="ahem"> -<meta name="assert" content="White spaces are preserved, honoring the 'white-space: break-spaces', which may lead to overfow. However, we can break before the las letter in the word honoring the 'break-all' value."> +<meta name="assert" content="White spaces are preserved, honoring the 'white-space: break-spaces', which may lead to overflow. However, we can break before the las letter in the word honoring the 'break-all' value."> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style> div { diff --git a/tests/wpt/tests/css/css-text/white-space/break-spaces-with-ideographic-space-008.html b/tests/wpt/tests/css/css-text/white-space/break-spaces-with-ideographic-space-008.html index 7102439d469..d222e1b7535 100644 --- a/tests/wpt/tests/css/css-text/white-space/break-spaces-with-ideographic-space-008.html +++ b/tests/wpt/tests/css/css-text/white-space/break-spaces-with-ideographic-space-008.html @@ -8,7 +8,7 @@ <link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-break-all"> <link rel="match" href="reference/white-space-break-spaces-005-ref.html"> <meta name="flags" content="ahem"> -<meta name="assert" content="Ideographic spaces can be wrapped, honoring the 'white-space: break-spaces', which may lead to overfow. However, we can break before the las letter in the word honoring the 'break-all' value."> +<meta name="assert" content="Ideographic spaces can be wrapped, honoring the 'white-space: break-spaces', which may lead to overflow. However, we can break before the las letter in the word honoring the 'break-all' value."> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style> div { diff --git a/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-mis-ref.html b/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-mis-ref.html new file mode 100644 index 00000000000..ca73318ecf3 --- /dev/null +++ b/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-mis-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<style> +div { + width: 20ch; +} +</style> +<div>Pass if this is a single line of text without breaks.</div> diff --git a/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-ref.html b/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-ref.html new file mode 100644 index 00000000000..bd5b231d831 --- /dev/null +++ b/tests/wpt/tests/css/css-text/white-space/reference/text-wrap-nowrap-001-ref.html @@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div>Pass if this is a single line of text without breaks.</div> diff --git a/tests/wpt/tests/css/css-text/white-space/text-wrap-nowrap-001.html b/tests/wpt/tests/css/css-text/white-space/text-wrap-nowrap-001.html new file mode 100644 index 00000000000..94437df6dee --- /dev/null +++ b/tests/wpt/tests/css/css-text/white-space/text-wrap-nowrap-001.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-wrap"> +<link rel="match" href="reference/text-wrap-nowrap-001-ref.html"> +<link rel="mismatch" href="reference/text-wrap-nowrap-001-mis-ref.html"> +<style> +div { + width: 20ch; + text-wrap: nowrap; +} +</style> +<div>Pass if this is a single line of text without breaks.</div> diff --git a/tests/wpt/tests/css/css-transforms/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transforms/WEB_FEATURES.yml index ca13ab5ae1b..bb44025b80b 100644 --- a/tests/wpt/tests/css/css-transforms/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-transforms/WEB_FEATURES.yml @@ -1,4 +1,7 @@ features: +- name: individual-transforms + files: + - transform-and-individual-transform-properties-computed-style.html - name: transforms3d files: - "*3d*" diff --git a/tests/wpt/tests/css/css-transforms/animation/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transforms/animation/WEB_FEATURES.yml index 831086f99e9..9116c202c42 100644 --- a/tests/wpt/tests/css/css-transforms/animation/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-transforms/animation/WEB_FEATURES.yml @@ -1,4 +1,11 @@ features: +- name: individual-transforms + files: + - rotate-animation-on-svg.html + - rotate-animation-with-will-change-transform-001.html + - scale-and-rotate-both-specified-on-animation-keyframes.html + - scale-animation-on-svg.html + - translate-animation-on-svg.html - name: transforms3d files: - backface-visibility-* diff --git a/tests/wpt/tests/css/css-transforms/individual-transform/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transforms/individual-transform/WEB_FEATURES.yml new file mode 100644 index 00000000000..8fa77e513de --- /dev/null +++ b/tests/wpt/tests/css/css-transforms/individual-transform/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: individual-transforms + files: "**" diff --git a/tests/wpt/tests/css/css-transforms/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transforms/parsing/WEB_FEATURES.yml index 831086f99e9..1bf7e23a0b4 100644 --- a/tests/wpt/tests/css/css-transforms/parsing/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-transforms/parsing/WEB_FEATURES.yml @@ -1,4 +1,8 @@ features: +- name: individual-transforms + files: + - rotate-parsing-computed.html + - rotate-parsing-valid.html - name: transforms3d files: - backface-visibility-* diff --git a/tests/wpt/tests/css/css-transforms/transform3d-preserve3d-014.html b/tests/wpt/tests/css/css-transforms/transform3d-preserve3d-014.html new file mode 100644 index 00000000000..e8d7a4805b0 --- /dev/null +++ b/tests/wpt/tests/css/css-transforms/transform3d-preserve3d-014.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSS Test (Transforms): Preserve-3D With display:contents intermediate</title> + <link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com"> + <link rel="help" href="http://www.w3.org/TR/css-transforms-2/#transform-style-property"> + <meta name="assert" content="This tests that when preserve-3d is specified, + a 90-degree rotation on the parent plus a 90-degree rotation on the child + cancel out, adding to a 180-degree rotation (which has no visible effect on + a lime square). This still happens despite an intermediary div with display:contents. + scale(2) is added to ensure that the test doesn't pass if the transforms are just ignored."> + <link rel="match" href="transform-lime-square-ref.html"> + </head> + <body style="padding:25px"> + <div style="transform: rotatex(90deg); transform-style: preserve-3d"> + <div style="display: contents"> + <div style="transform: rotatex(90deg) scale(2); width: 50px; height: 50px; background: lime"></div> + </div> + </div> + </body> +</html> diff --git a/tests/wpt/tests/css/css-transitions/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transitions/WEB_FEATURES.yml new file mode 100644 index 00000000000..4da279daa39 --- /dev/null +++ b/tests/wpt/tests/css/css-transitions/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: starting-style + files: + - starting-style-* diff --git a/tests/wpt/tests/css/css-transitions/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-transitions/parsing/WEB_FEATURES.yml new file mode 100644 index 00000000000..4da279daa39 --- /dev/null +++ b/tests/wpt/tests/css/css-transitions/parsing/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: starting-style + files: + - starting-style-* diff --git a/tests/wpt/tests/css/css-ui/parsing/WEB_FEATURES.yml b/tests/wpt/tests/css/css-ui/parsing/WEB_FEATURES.yml new file mode 100644 index 00000000000..b4ae339c2f3 --- /dev/null +++ b/tests/wpt/tests/css/css-ui/parsing/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: field-sizing + files: + - field-sizing-* diff --git a/tests/wpt/tests/css/css-ui/text-overflow-017.html b/tests/wpt/tests/css/css-ui/text-overflow-017.html index 561d4d0b6fe..7f61a57620c 100644 --- a/tests/wpt/tests/css/css-ui/text-overflow-017.html +++ b/tests/wpt/tests/css/css-ui/text-overflow-017.html @@ -1,11 +1,13 @@ <!DOCTYPE html> -<html class="reftest-wait"> +<html> <meta charset="utf-8"> <title>CSS Basic User Interface Test: interacting with the ellipsis</title> <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/"> <link rel="help" href="http://www.w3.org/TR/css3-ui/#text-overflow"> -<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> -<meta name="flags" content="ahem interact dom"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> <meta name="assert" content="Ellipsing must not prevent dispatching of pointer events."> <link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> <style> @@ -19,18 +21,28 @@ font: 100px/1 Ahem; color: blue; } -#discard { +#desc { float: left; } </style> -<div id=discard>First, click the blue box. </div> -<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> -<div id="test" onclick="green()"> </div> +<div id="desc">First, click the blue box. </div> +<div id="test"> </div> <script> -function green() { - document.getElementById("test").style.color="green"; - document.getElementById("discard").remove(); - document.children[0].className=""; -} + +let test = document.getElementById("test"); + +promise_test(async t => { + await document.fonts.ready; + + let clicked = false; + test.addEventListener("click", () => { + clicked = true; + }); + + await test_driver.click(test); + + assert_true(clicked); +}); + </script> diff --git a/tests/wpt/tests/css/css-values/WEB_FEATURES.yml b/tests/wpt/tests/css/css-values/WEB_FEATURES.yml index dc7331ab954..526bb67def5 100644 --- a/tests/wpt/tests/css/css-values/WEB_FEATURES.yml +++ b/tests/wpt/tests/css/css-values/WEB_FEATURES.yml @@ -19,3 +19,7 @@ features: files: - round-function.html - round-mod-rem-* +- name: trig-functions + files: + - acos-asin-atan-atan2-* + - sin-cos-tan-* diff --git a/tests/wpt/tests/css/css-view-transitions/duplicate-tag-rejects-start.html b/tests/wpt/tests/css/css-view-transitions/duplicate-tag-rejects-start.html index 6c99d6426c0..5c605fefbb3 100644 --- a/tests/wpt/tests/css/css-view-transitions/duplicate-tag-rejects-start.html +++ b/tests/wpt/tests/css/css-view-transitions/duplicate-tag-rejects-start.html @@ -33,18 +33,18 @@ promise_test(async t => { let updateCallbackDoneResolved = false; transition.updateCallbackDone.then(() => { updateCallbackDoneResolved = true; }, reject); - // Then finished resolves since updateCallbackDone was already resolved. - let finishResolved = false; - transition.updateCallbackDone.then(() => { - assert_true(updateCallbackDoneResolved, "updateCallbackDone not resolved before finish"); - finishResolved = true; - }, reject); - - // Finally ready rejects. + // Ready rejects. + let readyRejected = false; transition.ready.then(reject, () => { - assert_true(finishResolved, "finish not resolved before ready"); - resolve(); + readyRejected = true; + assert_true(updateCallbackDoneResolved, "updateCallbackDone should resolve before ready was rejected"); }); + + // Then finished resolves since updateCallbackDone was already resolved. + transition.finished.then(() => { + assert_true(readyRejected, "finished should resolve after ready was rejected"); + resolve(); + }, reject); }); }, "Two different elements with the same name in the new DOM should skip the transition"); </script> diff --git a/tests/wpt/tests/css/css-view-transitions/hit-test-unpainted-element-from-point.html b/tests/wpt/tests/css/css-view-transitions/hit-test-unpainted-element-from-point.html index c9650d97b9d..b34d2b11df5 100644 --- a/tests/wpt/tests/css/css-view-transitions/hit-test-unpainted-element-from-point.html +++ b/tests/wpt/tests/css/css-view-transitions/hit-test-unpainted-element-from-point.html @@ -2,7 +2,6 @@ <title>View transitions: hit test shared element at the real dom location</title> <link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> <link rel="author" href="mailto:vmpstr@chromium.org"> -<link rel="match" href="hit-test-unpainted-element-ref.html"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> diff --git a/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped-ref.html b/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped-ref.html new file mode 100644 index 00000000000..62419b07ee1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html> +<title>View transitions: view-transition-names are tree scoped (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<style> +div { + width: 100px; + height: 100px; + background: green; +} +</style> + +<div></div> diff --git a/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped.html b/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped.html new file mode 100644 index 00000000000..efca07e209d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/names-are-tree-scoped.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<title>View transitions: view-transition-names are tree scoped</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="names-are-tree-scoped-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +div { + width: 100px; + height: 100px; + background: red; +} + +#one { + view-transition-name: light1; +} +#two { + view-transition-name: light2; +} +#three { + view-transition-name: light3; +} + +:root { view-transition-name: none; } +html::view-transition-group(*) { animation-play-state: paused; } +html::view-transition-old(*) { animation: unset; opacity: 0 } +html::view-transition-new(*) { animation: unset; opacity: 0 } +</style> + +<custom-component> + <template shadowrootmode="open"> + <style> + div { + width: 100px; + height: 100px; + background: green; + view-transition-name: shadow; + } + </style> + <div> + <slot></slot> + </div> + <slot></slot> + </template> + <div id=one></div> + <div id=two></div> +</custom-component> + +<div id=three></div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + document.startViewTransition().ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</body> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-cssom.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-cssom.html new file mode 100644 index 00000000000..6f8beb16731 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-cssom.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>View transitions: CSSOM for @view-transition rule</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style></style> +<script> +function resetStateAndTest(testFunction) { + const sheet = document.styleSheets[0]; + while (sheet.cssRules.length > 0) sheet.deleteRule(0); + testFunction(); +} + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + } + `); + let rule = document.styleSheets[0].cssRules[0]; + assert_true(rule instanceof CSSViewTransitionRule); + assert_equals(rule.type, 0); + assert_equals(rule.cssText, "@view-transition { }"); + assert_equals(rule.navigation, ''); + + }); +}, "CSSViewTransitionRule is correctly parsed and accessible via CSSOM."); + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: auto; + } + `); + let rule = document.styleSheets[0].cssRules[0]; + assert_equals(rule.cssText, + "@view-transition { navigation: auto; }"); + assert_equals(rule.navigation, 'auto'); + + }); +}, "`navigation: auto` is correctly parsed."); + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: none; + } + `); + let rule = document.styleSheets[0].cssRules[0]; + assert_equals(rule.cssText, "@view-transition { navigation: none; }"); + assert_equals(rule.navigation, 'none'); + }); +}, "`navigation: none` is correctly parsed."); + +test(function () { + resetStateAndTest(() => { + assert_throws_dom('SyntaxError', () => { + document.styleSheets[0].insertRule('@view-transition foo {}'); + }, "Failed to execute 'insertRule' on 'CSSStyleSheet': " + + "Failed to parse the rule '@view-transition foo {}'"); + assert_equals(document.styleSheets[0].cssRules.length, 0); + }); +}, "@view-transition fails parsing with a preamble"); + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: foo; + } + `); + let rule = document.styleSheets[0].cssRules[0]; + assert_equals(rule.cssText, "@view-transition { }"); + }); +}, "Invalid `navigation` value fails to parse."); + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: none !important; + } + `); + let rule = document.styleSheets[0].cssRules[0]; + assert_equals(rule.cssText, "@view-transition { }"); + }); +}, "`navigation` with !important flag should fail to parse."); + +test(function () { + resetStateAndTest(() => { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: none; + } + `); + let rule = document.styleSheets[0].cssRules[0]; + rule.navigation = "auto"; + assert_equals(rule.navigation, "none"); + }); +}, "`navigation` descriptor cannot be set."); + +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade-external-stylesheet.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade-external-stylesheet.html new file mode 100644 index 00000000000..53c6135a566 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade-external-stylesheet.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition cascaldes correclty with layers in separate external stylesheets.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + @layer inertA, inertB, active; +</style> +<style> + @import "resources/opt-out-style.css" layer(inertA); +</style> +<style> + @import "resources/opt-in-style.css" layer(active); +</style> +<style> + @import "resources/opt-out-style.css" layer(inertB); +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_not_equals(event.viewTransition, null, + "ViewTransition must be triggered."); + }); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade.html new file mode 100644 index 00000000000..a38ca48e8c4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer-cascade.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition cascaldes correclty with layers.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@layer inertA, inertB, active; + +@layer inertA { + @view-transition { + navigation: none; + } +} +@layer active { + @view-transition { + navigation: auto; + } +} +@layer inertB { + @view-transition { + navigation: none; + } +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_not_equals(event.viewTransition, null, + "ViewTransition must be triggered."); + }); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer.html new file mode 100644 index 00000000000..63ec4c3e25d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-layer.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition nested in a @layer rule.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@layer transition { + @view-transition { + navigation: auto; + } +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_not_equals(event.viewTransition, null, + "ViewTransition must be triggered."); + }); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-matching-media.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-matching-media.html new file mode 100644 index 00000000000..77f2e05c340 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-matching-media.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition nested in a matching @media rule.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@media screen { + @view-transition { + navigation: auto; + } +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_not_equals(event.viewTransition, null, + "ViewTransition must be triggered."); + }); + }); +} +</script>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-non-matching-media.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-non-matching-media.html new file mode 100644 index 00000000000..ac9dbde37e1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-non-matching-media.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition nested in a non-matching @media rule.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@media print { + @view-transition { + navigation: auto; + } +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_equals(event.viewTransition, null, + "ViewTransition must not be triggered."); + }); + }); +} +</script>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-shadow-dom.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-shadow-dom.html new file mode 100644 index 00000000000..7edd8e0749f --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-in-shadow-dom.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition not applied from shadow tree.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => { + const host = document.querySelector("#host"); + const shadow = host.attachShadow({ mode: "open" }); + const style = document.createElement("style"); + style.textContent = `@view-transition { + navigation: auto; + }`; + shadow.appendChild(style); + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} else { + // Can't use the opt-in from shadow DOM on the new page since the opt-in must + // be effective by the time the <body> element is parsed and only elements in + // <body> can be a shadow root. + const style = document.createElement("style"); + style.textContent = `@view-transition { + navigation: auto; + }`; + document.head.appendChild(style); + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_equals(event.viewTransition, null, + "ViewTransition must not be triggered."); + }); + }); +} +</script> +<div id="host"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-multiple-rules.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-multiple-rules.html new file mode 100644 index 00000000000..5a84d46da18 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-multiple-rules.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<title>View Transitions: Multiple @view-transition, last one wins.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +@view-transition { + navigation: none; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_equals(event.viewTransition, null, + "ViewTransition must not be triggered."); + }); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html new file mode 100644 index 00000000000..be8cc501cf0 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto-ref.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition opt in for cross-document (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> +.old { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; + background: blue; +} + +.new { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + background: grey; +} +</style> +<div class="old"></div> +<div class="new"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto.html new file mode 100644 index 00000000000..8993cf1a677 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-auto.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in for auto</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="at-rule-opt-in-auto-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: auto; +} + +html { + background: blue; +} +</style> +<script> +function runTest() { + const url = "resources/at-rule-opt-in-auto.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-change-with-script.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-change-with-script.html new file mode 100644 index 00000000000..12452f67634 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-change-with-script.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition opt-in programmatically.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style id="vt-style"> +@view-transition { + navigation: none; +} +</style> +<script> +function optIn() { + document.querySelector("#vt-style").innerHTML = `@view-transition { navigation: auto }`; +} +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (!is_new_page) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(() => { + optIn(); + location.replace(location.href + '?new'); + })); +} else { + promise_test(() => { + optIn(); + return new Promise((resolve) => { + addEventListener('pagereveal', resolve); + }).then(event => { + assert_not_equals(event.viewTransition, null, + "ViewTransition must be triggered."); + }); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-new.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-new.html new file mode 100644 index 00000000000..2aecb7b9135 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-new.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt out in new document.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="at-rule-opt-in-none-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: auto; +} +html { + background: blue; +} +</style> +<script> +function runTest() { + const url = "resources/at-rule-opt-in-none.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-old.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-old.html new file mode 100644 index 00000000000..b5b0b3a1104 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-in-old.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt out in new document.</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="at-rule-opt-in-none-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: none; +} +html { + background: blue; +} +</style> +<script> +function runTest() { + const url = "resources/at-rule-opt-in-auto.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-ref.html new file mode 100644 index 00000000000..59e3342daeb --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/at-rule-opt-in-none-ref.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition opt out in new ocument (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> +:root { + /* + * There should be no transition due to `navigation: none` in the + * new or old page. + */ + background: grey; +} +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout-ref.html new file mode 100644 index 00000000000..90267e3a84a --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout-ref.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>View Transitions: paint holding timeout cancels transition (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<style> +.left { + width: 100px; + height: 100px; + position: relative; + left: 300px; + background: green; +} +</style> +<div class=left></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html b/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html new file mode 100644 index 00000000000..83596940fa4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/chromium-paint-holding-timeout.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: paint holding timeout cancels transition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="chromium-paint-holding-timeout-ref.html"> +<link rel="assert" content="Ensures paint holding timeout cancels transition. Note that this is a Chromium only test"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: auto; +} +.left { + view-transition-name: target; + width: 100px; + height: 100px; + background: red; +} +</style> + +<div class=left></div> +<script> +function runTest() { + const url = "resources/chromium-paint-holding-timeout.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/hide-before-reveal.html b/tests/wpt/tests/css/css-view-transitions/navigation/hide-before-reveal.html new file mode 100644 index 00000000000..7cdbcb46280 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/hide-before-reveal.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<title>View transitions: pagereveal event provides viewTransition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<meta name="timeout" content="long"> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/page-visibility/resources/window_state_context.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + const params = new URLSearchParams(location.search); + const is_initial_page = !params.has('new'); + + // This test navigates to itself with a changed query parameter. The test + // checks are performed on the navigated-to document. + if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + } else { + promise_test(async t => { + const render_blocker = document.createElement("script"); + render_blocker.blocking = "render"; + render_blocker.src = "/loading/resources/dummy.js?pipe=trickle(d10)"; + render_blocker.type = "module"; + document.head.append(render_blocker); + const ev_promise = new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + const wsc = window_state_context(t); + await wsc.minimize(); + render_blocker.remove(); + await wsc.restore(); + + const ev = await ev_promise; + + assert_equals(ev.viewTransition, null, + "Transition should have been skipped when document was minimized"); + }, "Inbound cross-document view-transition should be skipped if document is hidden"); + } +</script> +<style> + @view-transition { + navigation: auto; + } +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/mismatched-snapshot-containing-block-size-skips.html b/tests/wpt/tests/css/css-view-transitions/navigation/mismatched-snapshot-containing-block-size-skips.html new file mode 100644 index 00000000000..d18a40c9b6e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/mismatched-snapshot-containing-block-size-skips.html @@ -0,0 +1,127 @@ +<!DOCTYPE html> +<title> +View transitions: mismatched snapshot containing block size skips transition. +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/common/utils.js"></script> +<script src="resources/common.js"></script> +<style> +@view-transition { + navigation: auto; +} +::view-transition-group(root) { + animation-duration: 3s; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_harness_page = !params.has('popup'); +const is_old_page = params.has('popup') && params.get('popup') == 'old'; +const is_new_page = params.has('popup') && params.get('popup') == 'new'; + +const uuid = token(); + +const popup_old_size = 300; +const popup_new_size = 200; + +// This test opens a popup to its own URL but using a param to execute different +// script between the initial "harness" and popup. It then navigates the popup +// to a new page to start a view transition. Popup script is below. + +if (is_harness_page) { + // ========= Test Harness Script ============= + + const popup_old_url = `${location.href.split('?')[0]}?popup=old`; + const popup_new_url = `${location.href.split('?')[0]}?popup=new`; + + async function popupEventPromise(event_name) { + return new Promise(resolve => { + addEventListener('message', e => { + if (e.data === event_name) + resolve(); + }, {once: true}); + }); + } + + promise_test(async t => { + assertViewTransitionOnNavigationImplemented(); + + addEventListener('message', e => { + if (e.data.startsWith('FAIL:')) { + const message = e.data.substring(5); + t.step(() => assert_unreached(`Failure in test code: ${message}`)); + } + }); + + let popup = null; + + const load_event_in_popup = popupEventPromise('load'); + await test_driver.bless('Open a popup in a new window', () => { + const features = `width=${popup_old_size},height=${popup_old_size}`; + popup = window.open(popup_old_url, 'popup', features); + }); + await load_event_in_popup; + + // Pagehide is fired after capturing the outgoing state. + popup.onpagehide = () => popup.resizeTo(popup_new_size, popup_new_size); + + // Navigate the popup to the new page and wait for pagereveal. + const pagereveal_in_popup = popupEventPromise('pagereveal'); + popup.location = popup_new_url; + await pagereveal_in_popup; + + // Ensure the transition is skipped and `ready` rejected. + let did_finish = false; + popup.viewTransition.finished.then(() => { did_finish = true; }); + + await promise_rejects_dom(t, "InvalidStateError", popup.DOMException, + popup.viewTransition.ready, 'Resize must reject `ready`.'); + assert_true(did_finish, "Transition must be skipped by window resize."); + }); + +} else { + + // ========= Popup Script ============= + + if (is_old_page) { + addEventListener('load', () => window.opener.postMessage('load')); + } else if (is_new_page) { + function errorHandler(e) { + window.opener.postMessage(`FAIL: ${e}`); + } + // Hold rendering until the asynchronous resize from `resizeTo` above has + // been received. + const rendering_blocked_promise = blockRendering(); + rendering_blocked_promise.catch(errorHandler); + + let rendering_unblocked_promise = null; + + const interval_id = setInterval(() => { + // Since rendering is blocked - the resize event isn't fired. The + // innerWidth is also not updated (at least in Chrome) so use the + // outerWidth to wait on the size change. allow a bit of slop in case of + // window decorations. + if (window.outerWidth < popup_new_size + 15) { + rendering_unblocked_promise = unblockRendering(); + rendering_unblocked_promise.catch(errorHandler); + clearInterval(interval_id); + } + }, 100); + + addEventListener('pagereveal', e => { + // This simply ensures the test only runs if render blocking was + // successful since a fetch failure looks the same as never blocking + // rendering. + Promise.all([rendering_blocked_promise, rendering_unblocked_promise]).then(() => { + window.viewTransition = e.viewTransition; + window.opener.postMessage('pagereveal'); + }, () => {}); + }); + } +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload-ref.html new file mode 100644 index 00000000000..ed12194c310 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation (ref)</title> +<style> +html { + background: limegreen; +} +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload.html b/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload.html new file mode 100644 index 00000000000..c0fb61a4b0a --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/navigation-auto-excludes-reload.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="navigation-auto-excludes-reload-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: auto; +} +html { + background: limegreen; +} +::view-transition { + background-color: red; +} +::view-transition-group(root) { + animation-duration: 300s; +} +::view-transition-old(root), +::view-transition-new(root) { + opacity: 0; + animation: none; +} +</style> +<script> +if (location.hash == '#loaded') { + onload = () => requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); +} else { + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +} + +function runTest() { + location.hash = 'loaded'; + location.reload(); +} +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect-ref.html new file mode 100644 index 00000000000..91f24f877bd --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<title>navigation with a same-origin final url with cross-origin redirects (ref)</title> +<style> +html { + background: grey; +} +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect.sub.html b/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect.sub.html new file mode 100644 index 00000000000..8780310af2f --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/no-view-transition-with-cross-origin-redirect.sub.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>navigation with a same-origin final url with cross-origin redirects</title> +<link rel="help" href="https://html.spec.whatwg.org/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="no-view-transition-with-cross-origin-redirect-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + @view-transition { + navigation: auto; + } + + .new { + background: grey; + } + + ::view-transition { + background: red; + } + ::view-transition-group(*) { + animation-duration: 300s; + opacity: 0; + } +</style> +<script> + function runTest() { + let crossOriginPath = "http://{{hosts[][www]}}:{{ports[http][1]}}"; + let newUrl = crossOriginPath + "/common/redirect.py?location=" + location.href.split('?')[0] + "?new"; + location.href = newUrl; + } + + const params = new URLSearchParams(location.search); + if (params.has('new')) { + document.documentElement.classList.add('new'); + onload = () => requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + } else { + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); + } +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/old_vt_promises_bfcache.html b/tests/wpt/tests/css/css-view-transitions/navigation/old_vt_promises_bfcache.html new file mode 100644 index 00000000000..18397abbec7 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/old_vt_promises_bfcache.html @@ -0,0 +1,115 @@ +<!DOCTYPE html> +<title>VT object created on the old Document is skipped before persisting in BFCache</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> +<script> +// runBfcacheTest opens a popup to pageA which navigates to pageB and then +// back, ensuring pageA is stored in the BFCache. + +runBfcacheTest({ + funcBeforeNavigation: async () => { + // This function executes in pageA + + function addTransitionOptIn() { + let css = '@view-transition { navigation: auto; }'; + let style = document.createElement('style'); + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + } + addTransitionOptIn(); + + // Wait for at least one frame to ensure there is a transition on the + // navigation. + function waitForAtLeastOneFrame() { + return new Promise(resolve => { + // Different web engines work slightly different on this area but waiting + // for two requestAnimationFrames() to happen, one after another, should be + // sufficient to ensure at least one frame has been generated anywhere. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + resolve(); + }); + }); + }); + } + await waitForAtLeastOneFrame(); + + onpageswap = (e) => { + if (e.viewTransition == null) + return; + + document.documentElement.classList.add('transition'); + + e.viewTransition.updateCallbackDone.then(() => { + document.documentElement.classList.add('updateCallbackDone'); + }); + + e.viewTransition.ready.catch(() => { + document.documentElement.classList.add('ready'); + }); + + e.viewTransition.finished.then(() => { + document.documentElement.classList.add('finished'); + }); + } + }, + funcBeforeBackNavigation: async () => { + // This function executes in pageB + + function addTransitionOptIn() { + let css = '@view-transition { navigation: auto; }'; + let style = document.createElement('style'); + style.appendChild(document.createTextNode(css)); + document.head.appendChild(style); + } + addTransitionOptIn(); + + // Wait for at least one frame to ensure there is a transition on the + // navigation. + function waitForAtLeastOneFrame() { + return new Promise(resolve => { + // Different web engines work slightly different on this area but waiting + // for two requestAnimationFrames() to happen, one after another, should be + // sufficient to ensure at least one frame has been generated anywhere. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(() => { + resolve(); + }); + }); + }); + } + await waitForAtLeastOneFrame(); + }, + funcAfterAssertion: async (pageA, pageB, t) => { + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('transition'); + }), + 'navigation had viewTransition'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('updateCallbackDone'); + }), + 'updateCallbackDone was resolved'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('ready'); + }), + 'ready was rejected'); + + assert_true( + await pageA.execute_script(() => { + return document.documentElement.classList.contains('finished'); + }), + 'finished was resolved'); + }, + targetOrigin: originSameOrigin, +}); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition-ref.html new file mode 100644 index 00000000000..f2b0dbfd338 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<title>View Transitions: @view-transition removing opt-in doesn't skip active transition (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> + :root { + background-color: pink; + } + #target { + background-color: limegreen; + width: 100px; + height: 100px; + } +</style> +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition.html new file mode 100644 index 00000000000..eb2295f2f03 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-removed-during-transition.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition removing opt-in doesn't skip active transition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="opt-in-removed-during-transition-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + @view-transition { + navigation: auto; + } + :root { + view-transition-name: none; + } + ::view-transition { + background-color: pink; + } + ::view-transition-new(target) { + animation: none; + opacity: 0; + } + ::view-transition-old(target) { + animation: none; + opacity: 1; + } + ::view-transition-group(target) { + animation-play-state: paused; + } + #target { + background-color: limegreen; + width: 100px; + height: 100px; + view-transition-name: target; + } + #target.transitioned { + background-color: red; + } +</style> +<script> +const params = new URLSearchParams(location.search.substr(1)); +const is_starting_page = !params.has('new'); + +if (is_starting_page) { + requestAnimationFrame(() => requestAnimationFrame( () => { + location.replace(location.href + '?new'); + })); +} else { + addEventListener('pagereveal', async e => { + document.getElementById('target').classList.add('transitioned'); + await e.viewTransition.ready; + await new Promise(resolve => requestAnimationFrame(resolve)); + + // Remove the opt-in after the view transition has started. + document.styleSheets[0].cssRules[0].navigation = 'none'; + + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + }); +} +</script> +<div id="target"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-without-frame-crash.html b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-without-frame-crash.html new file mode 100644 index 00000000000..01c4d723498 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/opt-in-without-frame-crash.html @@ -0,0 +1,16 @@ +<!DOCTYPE html> +<title>View transitions: opt in without frame crash</title> +<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> + +<script> +const htmlString = ` +<!doctype html> +<style> +@view-transition { navigation: auto; } +</style> +<div>Hello!</div>`; + +const parser = new DOMParser(); +const doc = parser.parseFromString(htmlString, "text/html"); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise-ref.html new file mode 100644 index 00000000000..64aa26f6547 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title> + View transitions: Test pagereveal.finished and skipTransition (ref) +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 300px; + top: 100px; +} +</style> +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise.html new file mode 100644 index 00000000000..baac948bac4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-finished-promise.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title> + View transitions: Test pagereveal.finished and skipTransition +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="pagereveal-finished-promise-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (is_new_page) { + document.documentElement.classList.add('newPage'); + + addEventListener('pagereveal', e => { + e.viewTransition.finished.then(() => { + // Animations are finished so the screenshot should contain live DOM. + takeScreenshot(); + }); + e.viewTransition.skipTransition(); + }); +} else { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(window.location.href + '?new'); + })); + }; +} +</script> +<style> +@view-transition { + navigation: auto; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; + view-transition-name: target; +} +.newPage #target { + left: 300px; +} + +/* Long duration to ensure skipTransition aborts the transition */ +::view-transition-group(target) { + animation-duration: 300s; +} + +/* Ensure view-transition snapshots are easily distinguished from live DOM */ +:root { + view-transition-name: unset; +} +::view-transition { + background-color: thistle; +} +</style> +<div id="target"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-microtask-sequence.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-microtask-sequence.html new file mode 100644 index 00000000000..205f4d1ddcf --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-microtask-sequence.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<title> + View transition promise reactions in incoming page should resolve before + the rendering continues (rAF, style/layout etc) +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const params = new URLSearchParams(location.search.substr(1)); +const is_starting_page = !params.has('new'); + +if (is_starting_page) { + requestAnimationFrame(() => requestAnimationFrame( () => { + location.replace(location.href + '?new'); + })); +} else { + promise_test(async () => { + const sequence = []; + requestAnimationFrame(() => { + sequence.push("rAF"); + Promise.resolve().then(() => { + sequence.push("rAF-microtask"); + }) + }); + const transition = await new Promise(resolve => addEventListener('pagereveal', event => { + sequence.push("pagereveal"); + assert_true("viewTransition" in event, "PageRevealEvent should have a viewTransition"); + assert_not_equals(event.viewTransition, null, "PageRevealEvent should have a non-null viewTransition"); + + event.viewTransition.ready.then(() => { + sequence.push("ready"); + }); + event.viewTransition.updateCallbackDone.then(() => { + sequence.push("updateCallbackDone"); + }); + + resolve(event.viewTransition); + })); + + await transition.finished; + sequence.push("finished"); + assert_array_equals(sequence, ["pagereveal", "updateCallbackDone", "ready", "rAF", "rAF-microtask", "finished"]); + }); +} +</script> +<style> + @view-transition { + navigation: auto; + } +</style>
\ No newline at end of file diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition-new-opt-out.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition-new-opt-out.html new file mode 100644 index 00000000000..a8b314b751f --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition-new-opt-out.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title> + View transitions: null event.viewTransition when new page removes opt-in + before pagereveal +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style id="vt-style"> + @view-transition { + navigation: auto; + } +</style> +<script> +const params = new URLSearchParams(location.search.substr(1)); +const is_starting_page = !params.has('new'); + +if (is_starting_page) { + requestAnimationFrame(() => requestAnimationFrame( () => { + location.replace(location.href + '?new'); + })); +} else { + // Remove the opt-in from the destination page. + document.querySelector("#vt-style").remove(); + promise_test(async () => { + const pagereveal = await new Promise(resolve => { + addEventListener('pagereveal', e => resolve(e)); + }); + assert_true('viewTransition' in pagereveal, + '`pagereveal` must have a `viewTransition` property.'); + assert_equals(pagereveal.viewTransition, null, + '`viewTransition` must be null when there is no opt-in.'); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition.html new file mode 100644 index 00000000000..a6ae95f9be1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-no-view-transition.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title> + View transitions: in navigation without transition, pagereveal event has + null viewTransition +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +promise_test(async () => { + const pagereveal = await new Promise(resolve => { + addEventListener('pagereveal', e => resolve(e)); + }); + assert_true('viewTransition' in pagereveal, + '`pagereveal` must have a `viewTransition` property.'); + assert_equals(pagereveal.viewTransition, null, + '`viewTransition` must be null when there is no transition.'); +}); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise-ref.html new file mode 100644 index 00000000000..0c1ed276565 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>View transitions: Test pagereveal.ready (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> +:root { + background-color: thistle; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; +} +</style> +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise.html new file mode 100644 index 00000000000..65b370c9c05 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-ready-promise.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: Test pagereveal.ready</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="pagereveal-ready-promise-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (is_new_page) { + document.documentElement.classList.add('newPage'); + addEventListener('pagereveal', e => { + e.viewTransition.ready.then(() => { + document.getAnimations().forEach(anim => anim.pause()); + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + }); + }); +} else { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} +</script> +<style> +@view-transition { + navigation: auto; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; + view-transition-name: target; +} +.newPage #target { + left: 300px; +} + +/* Ensure view-transition snapshots are easily distinguished from live DOM */ +:root { + view-transition-name: unset; +} +::view-transition { + background-color: thistle; +} +</style> +<div id="target"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition-ref.html new file mode 100644 index 00000000000..cda9820d536 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>View transitions: setup transition from pagereveal (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<style> +:root { + background-color: thistle; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 300px; + top: 100px; +} +</style> +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition.html new file mode 100644 index 00000000000..7407824ea73 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-setup-transition.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: setup transition from pagereveal</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="pagereveal-setup-transition-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); +if (is_new_page) { + document.documentElement.classList.add('newPage'); + + addEventListener('pagereveal', e => { + // Setup the view-transition-name from the event. Ensure this is not + // too late to be discovered to create a shared element animation. + document.getElementById('target').classList.add('transition'); + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + }); +} else { + onload = () => { + document.getElementById('target').classList.add('transition'); + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} +</script> +<style> +@view-transition { + navigation: auto; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; +} +#target.transition { + view-transition-name: target; +} +.newPage #target { + left: 300px; +} +/* Hold the transition in the ending location indefinitely. If the transition + * name was correctly captured in the new page, this will cause the green box + * to locate at the new position (left: 300px) */ +::view-transition-group(target) { + animation-duration: 300s; + animation-timing-function: steps(1, jump-start); +} +/* Ensure view-transition snapshots are easily distinguished from live DOM */ +:root { + view-transition-name: unset; +} +::view-transition { + background-color: thistle; +} +</style> +<div id="target"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-updatecallbackdone-promise.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-updatecallbackdone-promise.html new file mode 100644 index 00000000000..3d259e66a20 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-updatecallbackdone-promise.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<title> + View transitions: Test pagereveal.updateCallbackDone promise is immediately resolved. +</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_initial_page = !params.has('new'); + +// Ensures microtasks in the current event loop are flushed before control flow +// resumes. +function flushMicrotasks() { + return new Promise(resolve => resolve()); +} + +// This test navigates to itself with a changed query parameter. The test +// checks are performed on the navigated-to document. +if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + + let updateCallbackDoneResolved = false; + ev.viewTransition.updateCallbackDone.then( + () => {updateCallbackDoneResolved = true;}); + await flushMicrotasks(); + assert_true(updateCallbackDoneResolved, + "updateCallbackDone must be resolved immediately."); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-with-view-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-with-view-transition.html new file mode 100644 index 00000000000..3f21d56ed68 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pagereveal-with-view-transition.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<title>View transitions: pagereveal event provides viewTransition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_initial_page = !params.has('new'); + +// This test navigates to itself with a changed query parameter. The test +// checks are performed on the navigated-to document. +if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + + assert_not_equals(ev.viewTransition, null, + 'Navigation with transition must have a viewTransition.'); + + assert_true('skipTransition' in ev.viewTransition, + 'skipTransition in viewTransition'); + assert_true('finished' in ev.viewTransition, 'finished in viewTransition'); + assert_true('ready' in ev.viewTransition, 'ready in viewTransition'); + assert_true('updateCallbackDone' in ev.viewTransition, + 'updateCallbackDone in viewTransition'); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture-ref.html new file mode 100644 index 00000000000..bda333066a3 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>View transitions: Test pageswap fires before document capture (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> +:root { + background-color: thistle; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; +} +</style> +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture.html new file mode 100644 index 00000000000..8ce791bcaec --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-fired-before-old-state-capture.html @@ -0,0 +1,63 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: Test pageswap fires before document capture</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="pageswap-fired-before-old-state-capture-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +const params = new URLSearchParams(location.search); +const is_new_page = params.has('new'); + +if (is_new_page) { + document.documentElement.classList.add('newPage'); + addEventListener('pagereveal', e => { + e.viewTransition.ready.then(() => { + document.getAnimations().forEach(anim => anim.pause()); + requestAnimationFrame(() => requestAnimationFrame(takeScreenshot)); + }); + }); +} else { + addEventListener('pageswap', e => { + document.documentElement.classList.add('oldPage'); + }); + + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; +} +</script> +<style> +@view-transition { + navigation: auto; +} +#target { + width: 100px; + height: 100px; + background-color: limegreen; + position: absolute; + left: 20px; + top: 100px; +} + +.oldPage #target { + view-transition-name: target; +} + +.newPage #target { + left: 300px; + view-transition-name: target; +} + +/* Ensure view-transition snapshots are easily distinguished from live DOM */ +:root { + view-transition-name: unset; +} +::view-transition { + background-color: thistle; +} +</style> +<div id="target"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-in-hidden-doc-should-skip-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-in-hidden-doc-should-skip-transition.html new file mode 100644 index 00000000000..5be3b6cb27c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-in-hidden-doc-should-skip-transition.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<title>Tests pageswap dispatch on hidden Documents</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script> + const expectedUrl = location.href + '?new'; + + const params = new URLSearchParams(location.search); + // The page the popup navigates to. + const is_new_page = params.has('new'); + // The initial page in the popup. + const is_popup_page = params.has('popup'); + // The test page itself. + const is_test_page = !is_popup_page && !is_new_page; + + if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", expectedUrl, "push", "from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = async () => { + window.events = []; + popup = window.open('?popup'); + }; + + const result = await new Promise(resolve => { + window.popup_done = resolve; + }); + assert_equals(result, null); + }, "Outbound cross-document view transition is not allowed when document is hidden"); + } else if (is_popup_page) { + onload = async () => { + await test_driver.minimize_window(); + assert_equals(document.visibilityState, "hidden"); + assert_equals(document.hidden, true); + + location.href = location.href.split('?')[0] + '?new'; + }; + + onpageswap = (e) => { + window.opener.popup_done(e.viewTransition); + }; + } +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-long-delay.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-long-delay.html new file mode 100644 index 00000000000..e6ef6d80dc2 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-long-delay.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<title>View transitions: long delay in pageswap aborts the transition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_initial_page = !params.has('new'); + +// This test navigates to itself with a changed query parameter. The test +// checks are performed on the navigated-to document. +if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + onpageswap = (e) => { + assert_not_equals(e.viewTransition, null); + + // Busy loop for 4.5 seconds in order to "synchronously block" + var start = Date.now(); + var end = start + 4500; + while (end - Date.now() > 0); + }; +} else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + + assert_equals(ev.viewTransition, null, + 'viewTransition must have been skipped.'); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-from-click.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-from-click.html new file mode 100644 index 00000000000..16e04c89bfe --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-from-click.html @@ -0,0 +1,80 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for push navigations from user click</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + document.getElementById('nav_link').remove(); + window.events = []; + popup = window.open("?popup"); + + popup.addEventListener("load", () => { + popup.requestAnimationFrame( + () => popup.requestAnimationFrame(() => { + let nav_link = popup.document.getElementById('nav_link'); + test_driver + .click(nav_link) + .catch(() => assert_unreached("click failed")); + })); + }); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from user click`); +} else if (is_popup_page) { + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; +} +</script> +<body> + <a id="nav_link" href='/css/css-view-transitions/navigation/pageswap-push-from-click.html?new'>Click me</a> + </body> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-navigation.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-navigation.html new file mode 100644 index 00000000000..50a43e70d90 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-navigation.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for push navigations</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = location.href.split('?')[0] + '?new'; + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-with-redirect.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-with-redirect.html new file mode 100644 index 00000000000..d9d252f83ce --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-push-with-redirect.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for push navigations with a same-origin redirect</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href + "?new"; + const expectedEvents = ["pageswap", "transition", expectedUrl, "push","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on navigation with same-origin redirect`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = "/common/redirect.py?location=/css/css-view-transitions/navigation/pageswap-push-with-redirect.html?new"; + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-replace-navigation.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-replace-navigation.html new file mode 100644 index 00000000000..18f63454fdf --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-replace-navigation.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for replace navigations</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?new"; + const expectedEvents = ["pageswap", "transition", expectedUrl, "replace","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on replace navigation from script`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href.split('?')[0] + '?new'); + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; + }; +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-skip-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-skip-transition.html new file mode 100644 index 00000000000..bfeee7827a3 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-skip-transition.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<title>View transitions: skipTransition() in pageswap aborts the transition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const is_initial_page = !params.has('new'); + +// This test navigates to itself with a changed query parameter. The test +// checks are performed on the navigated-to document. +if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + onpageswap = (e) => { + assert_not_equals(e.viewTransition, null); + e.viewTransition.skipTransition(); + }; +} else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + + assert_equals(ev.viewTransition, null, + 'viewTransition must have been skipped.'); + }); +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-traverse-navigation-no-bfcache.https.html b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-traverse-navigation-no-bfcache.https.html new file mode 100644 index 00000000000..9137dc4d1cd --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/pageswap-traverse-navigation-no-bfcache.https.html @@ -0,0 +1,85 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for traverse navigations</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="resources/common.js"></script> +<style></style> +<script> +const channel = new BroadcastChannel("testchannel"); + +const params = new URLSearchParams(location.search); +const is_initial_page_first_navigation = params.has('popup') && navigation.entries().length == 1; +const is_new_page = params.has('new'); +const is_test_page = !params.has('popup') && !params.has('new'); + +function enableViewTransition() { + document.styleSheets[0].insertRule(` + @view-transition { + navigation: auto; + } + `); +} + +if (is_new_page) + enableViewTransition(); + +// The test page which opens a popup for the navigation sequence. +if (is_test_page) { + const expectedUrl = location.href.split('?')[0] + "?popup"; + const expectedEvents = ["pageswap", "transition", expectedUrl, "traverse","from", "pagehide"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `pageswap on traverse navigation from script`); +} else if (is_initial_page_first_navigation) { + // The popup page which the user navigates back to. + onload = async () => { + await disableBFCache(); + requestAnimationFrame(() => requestAnimationFrame(() => { + location.href = location.href.split('?')[0] + '?new'; + })); + }; + + onpageshow = (e) => { + assert_false(e.persisted, 'the test should run without BFCache'); + } +} else if (is_new_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + navigation.back(); + })); + }; + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + if (e.viewTransition != null) + window.opener.events.push("transition"); + window.opener.events.push(e.activation.entry.url); + window.opener.events.push(e.activation.navigationType); + if (e.activation.from == navigation.currentEntry) + window.opener.events.push("from"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + channel.postMessage("nav"); + }; +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation-ref.html new file mode 100644 index 00000000000..cbcfd19d950 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation-ref.html @@ -0,0 +1,7 @@ +<!DOCTYPE html> +<title>View transitions: cross-document navigation to a prerender cancelled before commit (ref)</title> +<style> + html { + background-color: hotpink; + } +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation.html b/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation.html new file mode 100644 index 00000000000..d261b0df552 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/prerender-removed-during-navigation.html @@ -0,0 +1,96 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: cross-document navigation to a prerender cancelled before commit</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="prerender-removed-during-navigation-ref.html"> +<script src="/common/utils.js"></script> +<script src="/common/reftest-wait.js"></script> +<script src="/speculation-rules/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<style> +@view-transition { + navigation: auto; +} +html { + background-color: red; +} +html.outgoing { + background-color: cornflowerblue; +} +html.incoming { + background-color: hotpink; +} +::view-transition { + background-color: limegreen; +} +::view-transition-new(root) { + transform: translateY(55vh); + animation: none; + opacity: 1; +} +::view-transition-old(root) { + transform: translateY(-55vh); + animation: none; + opacity: 1; +} +::view-transition-group(root) { + animation-duration: 300s; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const uid = params.has('uid') ? params.get('uid') : token(); +const ready_channel = new PrerenderChannel('ready-to-activate', uid); + +if (!implementsSpeculationRules()) { + onload = () => { + document.body.innerText = 'This test requires speculation rules.'; + takeScreenshot(); + } +} else { + if (!params.has('next')) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); + } else if (document.prerendering) { + onload = prerenderedPage; + } else { + onload = incomingPage; + } +} + +async function runTest() { + document.documentElement.classList.add('outgoing'); + const next_url = + new URL(`prerender-removed-during-navigation.html?next&uid=${uid}`, window.location).href; + + const ready_to_activate = new Promise(resolve => { + ready_channel.addEventListener('message', resolve, {once: true}); + }); + + let prerender_script = startPrerendering(next_url); + + await ready_to_activate; + + onpageswap = () => { + prerender_script.remove(); + } + + window.location.replace(new URL(next_url, window.location)); +} + +function prerenderedPage() { + ready_channel.postMessage('readyToActivateMessage'); + ready_channel.close(); +} + +function incomingPage() { + document.documentElement.classList.add('incoming'); + requestAnimationFrame(takeScreenshot); +} + +function implementsSpeculationRules() { + return ('supports' in HTMLScriptElement) && + HTMLScriptElement.supports('speculationrules'); +} +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/reload-crash.html b/tests/wpt/tests/css/css-view-transitions/navigation/reload-crash.html new file mode 100644 index 00000000000..a2bf11b31dc --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/reload-crash.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: reload crash</title> +<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = () => requestAnimationFrame(() => requestAnimationFrame(() => requestAnimationFrame(() => { + let run = (new URLSearchParams(window.location.search)).get('run') || 0; + if (run > 5) { + takeScreenshot(); + } else { + const url = window.location.href.split('?')[0]; + window.location.href = url + `?run=${run + 1}`; + } +}))); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types-mutable.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types-mutable.html new file mode 100644 index 00000000000..ef4a540d040 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types-mutable.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in for auto with types (new page)</title> +<link rel="help" href="https://github.com/WICG/view-transitions"> +<script src="/common/reftest-wait.js"></script> +<script> + onload = takeScreenshot; +</script> +<style> + @view-transition { + navigation: auto; + types: check-new; + } + + html { + background: grey; + } + + html:active-view-transition-type(new-type)::view-transition-group(root) { + animation-duration: 300s; + } + + /* Hold the old image for the entire duration. */ + html:active-view-transition-type(new-type)::view-transition-old(root) { + animation: none; + opacity: 1; + } + + html:active-view-transition-type(new-type)::view-transition-new(root) { + animation: none; + opacity: 0; + } + + html:active-view-transition-type(new-type)::view-transition-old(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + left: 0px; + top: 0px; + } + + html:active-view-transition-type(new-type)::view-transition-new(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + } +</style> +<script> + onpagereveal = e => { + if (!e.viewTransition.types.has("check-new") || e.viewTransition.types.size !== 1) + e.viewTransition.skipTransition(); + + e.viewTransition.types.add("new-type"); + e.viewTransition.types.delete("check-new"); + }; +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types.html new file mode 100644 index 00000000000..b30d3791d6e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto-with-types.html @@ -0,0 +1,40 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in for auto with types (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +@view-transition { + navigation: auto; + types: new-type; +} +html { + background: grey; +} +html:active-view-transition-type(new-type)::view-transition-group(root) { animation-duration: 300s; } +/* Hold the old image for the entire duration. */ +html:active-view-transition-type(new-type)::view-transition-old(root) { + animation: none; + opacity: 1; + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html:active-view-transition-type(new-type)::view-transition-new(root) { + animation: none; + opacity: 0; + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; +} +</style> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto.html new file mode 100644 index 00000000000..e887d4b2107 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-auto.html @@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in for auto (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +@view-transition { + navigation: auto; +} +html { + background: grey; +} +html::view-transition-group(root) { animation-duration: 300s; } +/* Hold the old image for the entire duration. */ +html::view-transition-old(root) { + animation: none; + opacity: 1; +} +html::view-transition-new(root) { + animation: none; + opacity: 0; +} +html::view-transition-old(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; +} +</style> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-none.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-none.html new file mode 100644 index 00000000000..bf5a73c73ee --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/at-rule-opt-in-none.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt out in new document (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +@view-transition { + navigation: none; +} +html { + background: grey; +} +html::view-transition-group(root) { animation-duration: 3s; } +html::view-transition-old(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + animation-duration: 3s; + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; +} +</style> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/chromium-paint-holding-timeout.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/chromium-paint-holding-timeout.html new file mode 100644 index 00000000000..3964199c54c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/chromium-paint-holding-timeout.html @@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> +<title>View Transitions: paint holding timeout cancels transition (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="chromium-paint-holding-timeout-ref.html"> +<link rel="assert" content="Ensures paint holding timeout cancels transition. Note that this is a Chromium only test"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { + navigation: auto; +} +.right { + view-transition-name: target; + width: 100px; + height: 100px; + position: relative; + left: 300px; + background: green; +} +::view-transition-group(*), +::view-transition-new(*), +::view-transition-old(*) { + animation-play-state: paused; +} +</style> +<link rel=expect href="#target" blocking=render> +</head> + +<!-- delay for 3 seconds, then 1 second, then 1 second, then 1 second --> +<script src="/loading/resources/dummy.js?pipe=trickle(d3)"></script> +<script src="/loading/resources/dummy.js?pipe=trickle(d1)"></script> +<script src="/loading/resources/dummy.js?pipe=trickle(d1)"></script> +<script src="/loading/resources/dummy.js?pipe=trickle(d1)"></script> + +<div id=target class=right></div> + +<script> +takeScreenshot(); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/common.js b/tests/wpt/tests/css/css-view-transitions/navigation/resources/common.js new file mode 100644 index 00000000000..cbe023a3d9e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/common.js @@ -0,0 +1,71 @@ +function assertViewTransitionOnNavigationImplemented() { + assert_implements( + window.CSSViewTransitionRule, "ViewTransition-on-navigation not implemented."); +} + +const render_blocking_url = `resources/render-blocking-stylesheet.py`; +let render_block_uuid = null; +let render_block_reject = null; +let render_block_resolve = null; + +function renderBlockingOnError() { + render_block_reject('Error while loading render blocking stylesheet.'); +} +function renderBlockingOnLoad() { + render_block_resolve(); +} + +function blockRendering() { + if (document.body) + throw new Error('Cannot block rendering after body has been parsed.'); + + if (render_block_uuid) + throw new Error('Rendering already blocked.'); + + return new Promise((resolve, reject) => { + render_block_reject = reject; + render_block_resolve = resolve; + render_block_uuid = token(); + const href = `${render_blocking_url}?key=${render_block_uuid}`; + // Need to use document.write since only parser-encountered stylesheets + // cause render blocking. + document.write(`<link rel="stylesheet" onerror="renderBlockingOnError()" onload="renderBlockingOnLoad()" href="${href}">`); + document.close(); + }); +} + +function unblockRendering() { + if (!render_block_uuid) + throw new Error('Rendering not blocked.'); + + const url = `${render_blocking_url}?key=${render_block_uuid}`; + return fetch(url, { method: 'POST' }).then(response => { + if (response.status != 200) { + return response.text().then((body) => { + throw new Error('Failed to unblock rendering: ' + body); + }); + } + }); +} + +// Use external/wpt/html/browsers/browsing-the-web/back-forward-cache/resources/executor.js +// when migrating to external WPTs. +window.disableBFCache = () => { + return new Promise(resolve => { + // Use page's UUID as a unique lock name. + navigator.locks.request("test", () => { + resolve(); + return new Promise(() => {}); + }); + }); +}; + +function waitForMessage(msg) { + return new Promise(resolve => { + window.addEventListener( + "message", (e) => { + if (e.data === msg) + resolve(); + } + )}); +} diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-in-style.css b/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-in-style.css new file mode 100644 index 00000000000..9aac2b4e85b --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-in-style.css @@ -0,0 +1,3 @@ +@view-transition { + navigation: auto; +} diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-out-style.css b/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-out-style.css new file mode 100644 index 00000000000..f01d587ddad --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/opt-out-style.css @@ -0,0 +1,3 @@ +@view-transition { + navigation: none; +} diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/outbound-before-render.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/outbound-before-render.html new file mode 100644 index 00000000000..0815c3b3d76 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/outbound-before-render.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<head> + <style> + @view-transition { + navigation: auto; + } +</style> +<script id="blocker" async src="common.js?pipe=trickle(d10)" blocking="render"></script> +<script src="/resources/testharness.js"></script> +<script> +const params = new URLSearchParams(location.search); +const bc_channel = new BroadcastChannel(params.get("channel")); + +window.addEventListener("pagereveal", e => { + if (params.get("phase") === "old") { + bc_channel.postMessage(`did reveal old page`); + } else { + bc_channel.postMessage(`did reveal new page ${e.viewTransition ? "with" : "without"} transition`); + } +}); + +if (params.get("phase") === "new") { + document.getElementById("blocker").remove(); +} else { + step_timeout(() => { + location.href = `?phase=new&channel=${bc_channel.name}`; + }, 100); +} +</script> +</head> + +<body> + Content +</body> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/render-blocking-stylesheet.py b/tests/wpt/tests/css/css-view-transitions/navigation/resources/render-blocking-stylesheet.py new file mode 100644 index 00000000000..15ae6aba6ff --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/render-blocking-stylesheet.py @@ -0,0 +1,24 @@ +import time + + +# This handler blocks a GET request for the given key until a matching POST is +# made with the same key. This allows a test to load a resource and manually +# control when the response is received. +def main(request, response): + key = request.GET.first(b'key') + + if request.method == 'POST': + # Received result data from target page + request.server.stash.put(key, 'doResponse') + return 'done' + else: + poll_delay_sec = 0.1 + + # Wait until the caller POSTs before responding. + while request.server.stash.take(key) is None: + time.sleep(poll_delay_sec) + + status = 200 + headers = [('Content-Type', 'text/css')] + body = '' + return (status, headers, body) diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-and-nested-element-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-and-nested-element-transition.html new file mode 100644 index 00000000000..c572ce9798b --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-and-nested-element-transition.html @@ -0,0 +1,74 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation with nested element (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +@view-transition { navigation: auto; } + +html { + background: orange; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +.target { + width: 100px; + height: 100px; + background: lightgreen; + contain: layout; + view-transition-name: target; + overflow: visible; +} +.inner { + width: 100px; + height: 100px; + position: relative; + top: 50px; + left: 50px; + border: 5px solid blue; +} +html::view-transition-group(hidden) { animation-duration: 300s; } +html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; } +html::view-transition-new(*), html::view-transition-old(*) { + opacity: 1; + animation: unset; +} +html::view-transition-old(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; +} +html::view-transition-old(target) { + top: 0px; + left: 0px; +} +html::view-transition-new(target) { + top: 200px; + left: 0px; +} +</style> +<div class="target"> + This is new element + <div class="inner"></div> +</div> +<div class="hidden"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe-inner-result.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe-inner-result.html new file mode 100644 index 00000000000..65f14843d9c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe-inner-result.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> +.old { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; + background: blue; +} +.new { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + background: grey; +} +</style> +<div class="old"></div> +<div class="new"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe.html new file mode 100644 index 00000000000..7f008442f77 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-iframe.html @@ -0,0 +1,66 @@ +<!DOCTYPE html> +<html> +<head> +<script src="/common/rendering-utils.js"></script> +<style> +@view-transition { navigation: auto; } + +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; +} +html::view-transition-group(hidden) { animation-duration: 300s; } +html::view-transition-image-pair(hidden) { opacity: 0; } + +html::view-transition-old(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; + opacity: 1; + animation: unset; +} +html::view-transition-new(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + opacity: 1; + animation: unset; +} +</style> +<script> + onload = () => { + window.parent.postMessage("loaded", '*'); + } + + const params = new URLSearchParams(location.search); + if (params.has("blue")) + document.documentElement.style.background = "blue"; + else if (params.has("grey")) + document.documentElement.style.background = "grey"; + + onpagereveal = async (e) => { + if (e.viewTransition != null) { + await e.viewTransition.ready; + window.parent.postMessage("transition", '*'); + } + } + + window.addEventListener( + "message", async (e) => { + if (e.data === "checkrendering") { + await waitForAtLeastOneFrame(); + await waitForAtLeastOneFrame(); + window.parent.postMessage("rendered", '*'); + } + } + ); +</script> +</head> +<div class="hidden"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-no-opt-in.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-no-opt-in.html new file mode 100644 index 00000000000..82d2bdc5597 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-no-opt-in.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +html { + background: grey; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +html::view-transition-group(hidden) { animation-duration: 300s; } +html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; } +html::view-transition-new(*), html::view-transition-old(*) { + opacity: 1; + animation: unset; +} +html::view-transition-old(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + opacity: 1; +} +</style> +<div class="hidden"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-opt-in-removed.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-opt-in-removed.html new file mode 100644 index 00000000000..83f5d76c163 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition-opt-in-removed.html @@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { navigation: auto; } + +html { + background: grey; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +html::view-transition-group(hidden) { animation-duration: 300s; } +html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; } +html::view-transition-new(*), html::view-transition-old(*) { + opacity: 1; + animation: unset; +} +html::view-transition-old(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + opacity: 1; +} +</style> +<body> +<div class="hidden"></div> +</body> +<script> +requestAnimationFrame(() => { + takeScreenshot(); +}); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition.html new file mode 100644 index 00000000000..af68ba00742 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/root-element-transition.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation (new page)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script> +onload = takeScreenshot; +</script> +<style> +@view-transition { navigation: auto; } + +html { + background: grey; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +html::view-transition-group(hidden) { animation-duration: 300s; } +html::view-transition-image-pair(hidden) { animation: unset; opacity: 0; } +html::view-transition-new(*), html::view-transition-old(*) { + opacity: 1; + animation: unset; +} +html::view-transition-old(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; +} +html::view-transition-new(root) { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + opacity: 1; +} +</style> +<div class="hidden"></div> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/transition-to-prerender.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/transition-to-prerender.html new file mode 100644 index 00000000000..63f810a2636 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/transition-to-prerender.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<title>View transitions: prerender navigation helper</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<style> +@view-transition { navigation: auto; } +html { background: red; } +div { + width: 200px; + height: 200px; + background: red; + color: black; + position: absolute; + top: 40px; + right: 8px; + view-transition-name: target; +} +::view-transition { + background: lightblue; +} +::view-transition-group(root) { + visibility: hidden; + animation-duration: 500s; +} +::view-transition-group(target) { + animation-play-state: paused; +} +::view-transition-new(target) { + animation: unset; + opacity: 1; +} +::view-transition-old(target) { + animation: unset; + opacity: 0; +} +</style> +<div id=target> + There should be a green square on the left side of the screen, + on a field of lightblue. There should be no red in the final state. +</div> +<script> +if (document.prerendering) { + target.style.background = "green"; +} +const channel = new PrerenderChannel('prerender-channel'); +channel.postMessage('loaded!'); +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition-ref.html new file mode 100644 index 00000000000..a0bb6180c4f --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition-ref.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> +.old { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; + background: grey; +} +.new { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + background: orange; +} +.old_text { + position: fixed; + top: 0px; + left: 0px; + width: 100px; + height: 100px; + background: lightblue; + transform: translate(8px, 8px); +} +.new_text { + position: fixed; + top: 200px; + left: 0; + width: 100px; + height: 100px; + background: lightgreen; + transform: translate(8px, 8px); +} +.inner { + width: 100px; + height: 100px; + position: relative; + top: 50px; + left: 50px; + border: 5px solid black; +} +</style> +<div class="old"></div> +<div class="new"></div> +<div class="old_text"> + This is old element + <div class="inner"></div> +</div> +<div class="new_text"> + This is new element + <div class="inner" style="border:5px solid blue"></div> +</div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition.html new file mode 100644 index 00000000000..457f263bf95 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-and-nested-element-transition.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation with nested element</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-and-nested-element-transition-ref.html"> +<meta name="fuzzy" content="root-and-nested-element-transition-ref.html:0-2;0-2000"> + +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { navigation: auto; } +html { + background: grey; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +.target { + width: 100px; + height: 100px; + background: lightblue; + contain: layout; + view-transition-name: target; + overflow: visible; +} +.inner { + width: 100px; + height: 100px; + position: relative; + top: 50px; + left: 50px; + border: 5px solid black; +} +</style> +<div class="target"> + This is old element + <div class="inner"></div> +</div> +<div class="hidden"></div> + +<script> +function runTest() { + const url = "resources/root-and-nested-element-transition.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-cross-origin.sub.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-cross-origin.sub.html new file mode 100644 index 00000000000..51a7c926e6d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-cross-origin.sub.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation in a cross-origin iframe</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-iframe-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/common.js"></script> +<script src="/common/get-host-info.sub.js"></script> + +<iframe id="inner"></iframe> +<script> +async function runTest() { + let frame = document.getElementById("inner"); + + let frameLoaded = waitForMessage("loaded"); + frame.src = get_host_info().HTTP_REMOTE_ORIGIN + "/css/css-view-transitions/navigation/resources/root-element-transition-iframe.html?blue"; + await frameLoaded; + frame.contentWindow.postMessage("checkrendering", '*'); + await waitForMessage("rendered"); + + frame.src = get_host_info().HTTP_REMOTE_ORIGIN + "/css/css-view-transitions/navigation/resources/root-element-transition-iframe.html?grey"; + await waitForMessage("transition"); + + takeScreenshot(); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-ref.html new file mode 100644 index 00000000000..576689af320 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-ref.html @@ -0,0 +1,8 @@ +<!DOCTYPE html> +<html> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> + +<iframe src="resources/root-element-transition-iframe-inner-result.html"></iframe> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main-ref.html new file mode 100644 index 00000000000..f350545c7f7 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<title>View transitions: basic cross-document navigation in an iframe while the main frame has a same-document transition (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> + html { + background: lightpink; + } + iframe { + border: 1px solid black; + } +</style> +<iframe src="resources/root-element-transition-iframe-inner-result.html"></iframe> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main.html new file mode 100644 index 00000000000..b7ef426121c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe-with-startVT-on-main.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation in an iframe while the main frame has a same-document transition</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-iframe-with-startVT-on-main-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/common.js"></script> + +<style> + #inner { + view-transition-name: inner + } + + ::view-transition { + background: lightpink; + } + ::view-transition-group(root) { + animation-duration: 300s; + opacity: 0; + } + + ::view-transition-old(inner), ::view-transition-new(inner) { + animation: unset; + } + ::view-transition-old(inner) { + opacity: 0; + } + ::view-transition-new(inner) { + opacity: 1; + } +</style> + +<iframe id="inner" src="resources/root-element-transition-iframe.html?blue"></iframe> +<script> +async function runTest() { + let frame = document.getElementById("inner"); + + await document.startViewTransition(() => { + document.documentElement.style.background = "orange"; + frame.style.border = "1px solid black"; + }).ready; + + frame.contentWindow.postMessage("checkrendering"); + await waitForMessage("rendered"); + + frame.src = "resources/root-element-transition-iframe.html?grey"; + await waitForMessage("transition"); + + takeScreenshot(); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe.html new file mode 100644 index 00000000000..a320d92c698 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-iframe.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation in an iframe</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-iframe-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/common.js"></script> + +<iframe id="inner" src="resources/root-element-transition-iframe.html?blue"></iframe> +<script> +async function runTest() { + let frame = document.getElementById("inner"); + frame.contentWindow.postMessage("checkrendering"); + await waitForMessage("rendered"); + + frame.src = "resources/root-element-transition-iframe.html?grey"; + await waitForMessage("transition"); + + takeScreenshot(); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-new.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-new.html new file mode 100644 index 00000000000..5cec74aac2d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-new.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { navigation: auto; } +html { + background: blue; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> +<script> +function runTest() { + const url = "resources/root-element-transition-no-opt-in.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-old.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-old.html new file mode 100644 index 00000000000..9d834ffd6a1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-on-old.html @@ -0,0 +1,28 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +html { + background: blue; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> +<script> +function runTest() { + const url = "resources/root-element-transition.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html new file mode 100644 index 00000000000..d38b8aa4cd7 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-no-opt-in-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> +html { + background: grey; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-new.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-new.html new file mode 100644 index 00000000000..46daf95e5e4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-new.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style id="vt-style"> +@view-transition { navigation: auto; } +</style> +<style> +html { + background: blue; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> +<script> +function runTest() { + document.querySelector("#vt-style").remove(); + const url = "resources/root-element-transition-opt-in-removed.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-old.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-old.html new file mode 100644 index 00000000000..5fab64a3067 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-opt-in-removed-on-old.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation opt-in removed</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-no-opt-in-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style id="vt-style"> +@view-transition { navigation: auto; } +</style> +<style> +html { + background: blue; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> +<script> +function runTest() { + document.querySelector("#vt-style").remove(); + const url = "resources/root-element-transition.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-ref.html new file mode 100644 index 00000000000..65f14843d9c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition-ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation (ref)</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<style> +.old { + width: 50vw; + height: 100vh; + position: fixed; + left: 0px; + top: 0px; + background: blue; +} +.new { + width: 50vw; + height: 100vh; + position: fixed; + left: 50vw; + top: 0px; + background: grey; +} +</style> +<div class="old"></div> +<div class="new"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition.html b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition.html new file mode 100644 index 00000000000..fb293b83994 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/root-element-transition.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<link rel="match" href="root-element-transition-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { navigation: auto; } +html { + background: blue; +} +.hidden { + width: 10px; + height: 10px; + view-transition-name: hidden; + background: green; + contain: layout; +} +</style> +<div class="hidden"></div> +<script> +function runTest() { + const url = "resources/root-element-transition.html"; + window.location.replace(new URL(url, window.location)); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/skip-outbound-vt-before-reveal.html b/tests/wpt/tests/css/css-view-transitions/navigation/skip-outbound-vt-before-reveal.html new file mode 100644 index 00000000000..2fcac44d249 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/skip-outbound-vt-before-reveal.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<title>View transitions: outbound cross-document transition before reveal</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:nrosenthal@chromium.org"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + promise_test(async t => { + const result = await new Promise(resolve => { + const channel_name = `outbound-vt-after-reveal-${new Date().valueOf()}`; + const bc = new BroadcastChannel(channel_name); + bc.addEventListener("message", e => { + resolve(e.data); + }); + const popup = window.open(`resources/outbound-before-render.html?phase=old&channel=${channel_name}`); + + t.add_cleanup(() => popup.close()); + }); + + assert_equals(result, "did reveal new page without transition"); + }, "when navigating away before revealing, never start a view transition"); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-manual.html b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-manual.html new file mode 100644 index 00000000000..7465065c5da --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-manual.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: prerender navigation</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<!-- TODO(crbug.com/1418681). This test should work automatically, + but doesn't due to the referenced bug. +<link rel="match" href="transition-to-prerender-ref.html"> +--> +<script src="/common/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<script src="/common/reftest-wait.js"></script> +<style> +@view-transition { navigation: auto; } +html { background: red; } +#target { + width: 200px; + height: 200px; + background: black; + color: white; + position: absolute; + top: 40px; + view-transition-name: target; +} +</style> +<div id="target"></div> +<script> +const uid = token(); + +function startTest() { + const old_url = "/transition-to-prerender-manual.html"; + const new_url = `/resources/transition-to-prerender.html?uid=${uid}`; + window.location.href = window.location.href.replace(old_url, new_url); +} + +async function waitForPrerender() { + const channel = new PrerenderChannel('prerender-channel', uid); + + const gotMessage = new Promise(resolve => { + channel.addEventListener('message', resolve) + }, { + once: true + }); + + startPrerendering(`resources/transition-to-prerender.html?uid=${uid}`); + await gotMessage; + startTest(); +} + +onload = waitForPrerender; +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-ref.html b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-ref.html new file mode 100644 index 00000000000..7df899fdca1 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender-ref.html @@ -0,0 +1,27 @@ +<!DOCTYPE html> +<title>View transitions: basic cross-document navigation to a prerender (ref)</title> +<style> +html,body { + margin: 0; + width: 100%; + height: 100%; + background-color: limegreen; +} +div { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; +} +div.outgoing { + background-color: cornflowerblue; + transform: translateY(-55vh); +} +div.incoming { + background-color: hotpink; + transform: translateY(55vh); +} +</style> +<div class="incoming"></div> +<div class="outgoing"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender.html b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender.html new file mode 100644 index 00000000000..bdc66708970 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/transition-to-prerender.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: basic cross-document navigation to a prerender</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:bokan@chromium.org"> +<link rel="match" href="transition-to-prerender-ref.html"> +<script src="/common/utils.js"></script> +<script src="/common/reftest-wait.js"></script> +<script src="/speculation-rules/resources/utils.js"></script> +<script src="/speculation-rules/prerender/resources/utils.js"></script> +<style> +@view-transition { + navigation: auto; +} +html { + background-color: red; +} +html.outgoing { + background-color: cornflowerblue; +} +html.incoming { + background-color: hotpink; +} +::view-transition { + background-color: limegreen; +} +::view-transition-new(root) { + transform: translateY(55vh); + animation: none; + opacity: 1; +} +::view-transition-old(root) { + transform: translateY(-55vh); + animation: none; + opacity: 1; +} +::view-transition-group(root) { + animation-duration: 300s; +} +</style> +<script> +const params = new URLSearchParams(location.search); +const uid = params.has('uid') ? params.get('uid') : token(); +const ready_channel = new PrerenderChannel('ready-to-activate', uid); + +if (!implementsSpeculationRules()) { + onload = () => { + document.body.innerText = 'This test requires speculation rules.'; + takeScreenshot(); + } +} else { + if (!params.has('next')) { + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); + } else { + onload = prerenderedPage; + } +} + +async function runTest() { + document.documentElement.classList.add('outgoing'); + const next_url = + new URL(`transition-to-prerender.html?next&uid=${uid}`, window.location).href; + + const ready_to_activate = new Promise(resolve => { + ready_channel.addEventListener('message', resolve, {once: true}); + }); + + startPrerendering(next_url); + + await ready_to_activate; + + window.location.replace(new URL(next_url, window.location)); +} + +function prerenderedPage() { + document.addEventListener('prerenderingchange', () => { + document.documentElement.classList.add('incoming'); + requestAnimationFrame(takeScreenshot); + }); + + ready_channel.postMessage('readyToActivateMessage'); + ready_channel.close(); +} + +function implementsSpeculationRules() { + return ('supports' in HTMLScriptElement) && + HTMLScriptElement.supports('speculationrules'); +} +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-mutable.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-mutable.html new file mode 100644 index 00000000000..307e8a8b747 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-mutable.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in with types, can mutate types in JS</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="../at-rule-opt-in-auto-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + @view-transition { + navigation: auto; + types: check; + } + + html:active-view-transition-type(old-type) { + background: blue; + } +</style> +<script> + function runTest() { + const url = "../resources/at-rule-opt-in-auto-with-types.html"; + window.location.replace(new URL(url, window.location)); + } + onpageswap = e => { + if (!e.viewTransition.types.has("check")) + e.viewTransition.skipTransition(); + e.viewTransition.types.add("old-type"); + e.viewTransition.types.delete("check"); + }; + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-no-cascade.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-no-cascade.html new file mode 100644 index 00000000000..5fec29db89c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types-no-cascade.html @@ -0,0 +1,33 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition types don't cascade</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="../at-rule-opt-in-auto-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + /* This should be ignored, because the following rule has the default "none" types */ + @view-transition { + types: old-type; + } + + @view-transition { + navigation: auto; + } + + html:active-view-transition { + background: blue; + } + + html:active-view-transition-type(old-type) { + background: red; + } +</style> +<script> + function runTest() { + const url = "../resources/at-rule-opt-in-auto-with-types.html"; + window.location.replace(new URL(url, window.location)); + } + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types.html new file mode 100644 index 00000000000..87503d9f1e3 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-opt-in-auto-with-types.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View Transitions: @view-transition opt in with types</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="match" href="../at-rule-opt-in-auto-ref.html"> +<script src="/common/reftest-wait.js"></script> +<style> + @view-transition { + navigation: auto; + types: old-type; + } + + html:active-view-transition-type(old-type) { + background: blue; + } +</style> +<script> + function runTest() { + const url = "../resources/at-rule-opt-in-auto-with-types.html"; + window.location.replace(new URL(url, window.location)); + } + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-with-types-parsing.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-with-types-parsing.html new file mode 100644 index 00000000000..431a0ec9f4d --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/at-rule-with-types-parsing.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>View transitions: parsing @view-transition rule with types</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + function parse_types(declaration) { + const stylesheet = new CSSStyleSheet(); + stylesheet.replaceSync(`@view-transition { types: ${declaration} }`); + return stylesheet.rules.length ? stylesheet.rules[0].types : null; + } + + function types_parser_test(declaration, expected) { + test(() => { + const result = parse_types(declaration); + assert_array_equals(result, expected); + }, `types: ${declaration} shoud result in ${JSON.stringify(expected)}`); + } + + types_parser_test("none", []); + types_parser_test("abc", ["abc"]); + types_parser_test("abc xyz", ["abc", "xyz"]); + types_parser_test(" abc \txyz ", ["abc", "xyz"]); + types_parser_test("abc none", []); + types_parser_test("abc -ua-something", []); + types_parser_test("abc -ok-something", ["abc", "-ok-something"]); + types_parser_test("abc abc", ["abc", "abc"]); + types_parser_test("abc ABC", ["abc", "ABC"]); + types_parser_test("123", []); + types_parser_test("*", []); + types_parser_test("*11 abc", []); +</script> +<script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-same-rule.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-same-rule.html new file mode 100644 index 00000000000..23dc9d4ca98 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-same-rule.html @@ -0,0 +1,31 @@ +<!DOCTYPE html> +<title>View transitions: types together with navigation:none doesn't apply</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + @view-transition { + navigation: none; + types: check; + } +</style> +<script> + const params = new URLSearchParams(location.search); + const is_initial_page = !params.has('new'); + + // This test navigates to itself with a changed query parameter. The test + // checks are performed on the navigated-to document. + if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + } else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + assert_equals(ev.viewTransition, null); + }); + } +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-when-after.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-when-after.html new file mode 100644 index 00000000000..1fd28d97a6e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/navigation-supersedes-types-when-after.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<title>View transitions: types are superseded by navigation:none</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + @view-transition { + navigation: auto; + types: check; + } + + @view-transition { + navigation: none; + } +</style> +<script> + const params = new URLSearchParams(location.search); + const is_initial_page = !params.has('new'); + + // This test navigates to itself with a changed query parameter. The test + // checks are performed on the navigated-to document. + if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + } else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + assert_equals(ev.viewTransition, null); + }); + } +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/with-types/types-in-pagereveal-and-pageswap.html b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/types-in-pagereveal-and-pageswap.html new file mode 100644 index 00000000000..2c12fece3c0 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/with-types/types-in-pagereveal-and-pageswap.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<title>View transitions: types from rule are reflected in pagereveal and pageswap</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + @view-transition { + navigation: auto; + types: check; + } +</style> +<script> + const params = new URLSearchParams(location.search); + const is_initial_page = !params.has('new'); + + // This test navigates to itself with a changed query parameter. The test + // checks are performed on the navigated-to document. + if (is_initial_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href + '?new'); + })); + }; + onpageswap = (e) => { + assert_not_equals(e.viewTransition, null); + if (!e.viewTransition.types.has("check")) + e.viewTransition.skipTransition(); + }; + } else { + promise_test(async () => { + const ev = await new Promise( + resolve => addEventListener('pagereveal', e => resolve(e))); + + assert_array_equals([...ev.viewTransition.types], ["check"]); + }); + } +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/zero-named-elements.html b/tests/wpt/tests/css/css-view-transitions/navigation/zero-named-elements.html new file mode 100644 index 00000000000..e6061de2a8b --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/navigation/zero-named-elements.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<title>View transitions: pageswap navigationactivation for replace navigations</title> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/"> +<link rel="author" href="mailto:khushalsagar@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +@view-transition { + navigation: auto; +} + +html { + view-transition-name: none; +} +</style> +<script> +const expectedUrl = location.href + '?new'; + +const params = new URLSearchParams(location.search); +// The page the popup navigates to. +const is_new_page = params.has('new'); +// The initial page in the popup. +const is_popup_page = params.has('popup'); +// The test page itself. +const is_test_page = !is_popup_page && !is_new_page; + +const channel = new BroadcastChannel("testchannel"); + +if (is_test_page) { + const expectedEvents = ["pageswap", "pagehide", "pagereveal", "finished"]; + + promise_test(async t => { + let popup; + onload = () => { + window.events = []; + popup = window.open("?popup"); + }; + + await new Promise(resolve => { + channel.addEventListener( + "message", t.step_func(async (e) => { + if (e.data === "nav") { + assert_array_equals(window.events, expectedEvents, 'incorrect event order'); + popup.close(); + resolve(); + } + })); + }); + }, `transition finishes with no named elements`); +} else if (is_popup_page) { + onload = () => { + requestAnimationFrame(() => requestAnimationFrame(() => { + location.replace(location.href.split('?')[0] + '?new'); + })); + + onpageswap = (e) => { + window.opener.events.push("pageswap"); + }; + + onpagehide = () => { + window.opener.events.push("pagehide"); + }; + }; +} else if (is_new_page) { + onpagereveal = (e) => { + window.opener.events.push("pagereveal"); + e.viewTransition.finished.then(() => { + window.opener.events.push("finished"); + channel.postMessage("nav"); + }); + } +} +</script> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early-mutation.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early-mutation.html new file mode 100644 index 00000000000..24737d9050e --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early-mutation.html @@ -0,0 +1,57 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type activates early when set immediately view token list</title> + +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + html:active-view-transition-type(type-name) #target { + background: green; + view-transition-name: target; + } + + #target { + background: red; + width: 100px; + height: 100px; + } + + html::view-transition-group(target) { + animation-play-state: paused; + } + + html::view-transition-new(target) { + animation: unset; + opacity: 0; + } + + html::view-transition-old(target) { + animation: unset; + opacity: 1; + } + + html::view-transition-group(root) { + display: none; + } + + html::view-transition { + background: lightpink; + } +</style> + +<div id="target"></div> + +<script> + failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + + function runTest() { + let transition = document.startViewTransition(); + transition.types.add("type-name"); + transition.ready.then(takeScreenshot); + } + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early.html new file mode 100644 index 00000000000..b62e8a71679 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-early.html @@ -0,0 +1,56 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type activates early (before tag discovery)</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +html:active-view-transition-type(type-name) #target { + background: green; + view-transition-name: target; +} + +#target { + background: red; + width: 100px; + height: 100px; +} + +html::view-transition-group(target) { + animation-play-state: paused; +} + +html::view-transition-new(target) { + animation: unset; + opacity: 0; +} + +html::view-transition-old(target) { + animation: unset; + opacity: 1; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: lightpink; } +</style> + +<div id="target"></div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition({ + types: ["type-name"] + }); + transition.ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-late-mutation.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-late-mutation.html new file mode 100644 index 00000000000..dbceba111ee --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-match-late-mutation.html @@ -0,0 +1,61 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type activates when set on ready promise</title> + +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + #target { + background: green; + width: 100px; + height: 100px; + view-transition-name: target; + } + + html::view-transition-group(*) {} + + html:active-view-transition-type(type-name)::view-transition-group(target) { + animation-play-state: paused; + width: 100px; + height: 100px; + background: green; + } + + html:active-view-transition-type(type-name)::view-transition-new(target) { + animation: unset; + opacity: 0; + } + + html:active-view-transition-type(type-name)::view-transition-old(target) { + animation: unset; + opacity: 0; + } + + html::view-transition-group(root) { + display: none; + } + + html::view-transition { + background: lightpink; + } +</style> + +<div id="target"></div> + +<script> + failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + + function runTest() { + let transition = document.startViewTransition(); + transition.ready.then(() => { + transition.types.add("type-name"); + takeScreenshot(); + + }); + } + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches-ref.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches-ref.html new file mode 100644 index 00000000000..80b1c6a1000 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches-ref.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title>View transitions: active-view-transition various matches (ref)</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<style> + +.test { + width: 100px; + height: 100px; + background: green; +} +#container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; +} +body { background: lightpink; } +</style> + +<div id="container"> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> +</div> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches.html new file mode 100644 index 00000000000..ef15d97fb99 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-matches.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition various matches</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-matches-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +html:active-view-transition #positive1 { background: green; } +html:active-view-transition-type(foo) #positive2 { background: green; } +html:active-view-transition-type(foo, bar) #positive3 { background: green; } +html:active-view-transition-type(bar, baz, ba0) #positive4 { background: green; } +html:has(:active-view-transition-type(bar)) #positive5 { background: green; } +html:active-view-transition:active-view-transition-type(foo) #positive6 { background: green; } + +/* specificity checks, both a-v-t and a-v-t-t are equal */ +html:active-view-transition-type(foo, bar) #positive7 { background: red; } +html:active-view-transition #positive7 { background: green; } + +html:active-view-transition #positive8 { background: red; } +html:active-view-transition-type(foo, bar) #positive8 { background: green; } + +/* negative checks */ +html:active-view-transition-type(fooo) #negative1 { background: red; } +html:active-view-transition-type(foo1, bar2) #negative2 { background: red; } +/* invalid syntax */ +html:active-view-transition-type(*) #negative3 { background: red; } +html:active-view-transition(foo) #negative4 { background: red; } +html:active-view-transition-type(foo,) #negative5 { background: red; } +html:active-view-transition-type() #negative6 { background: red; } +html:active-view-transition-type(,) #negative7 { background: red; } + +.test { + width: 100px; + height: 100px; +} +#positive1 { view-transition-name: positive1; background: red } +#positive2 { view-transition-name: positive2; background: red } +#positive3 { view-transition-name: positive3; background: red } +#positive4 { view-transition-name: positive4; background: red } +#positive5 { view-transition-name: positive5; background: red } +#positive6 { view-transition-name: positive6; background: red } +#positive7 { view-transition-name: positive7; background: yellow } +#positive8 { view-transition-name: positive8; background: yellow } +#negative1 { view-transition-name: negative1; background: green } +#negative2 { view-transition-name: negative2; background: green } +#negative3 { view-transition-name: negative3; background: green } +#negative4 { view-transition-name: negative4; background: green } +#negative5 { view-transition-name: negative5; background: green } +#negative6 { view-transition-name: negative6; background: green } +#negative7 { view-transition-name: negative7; background: green } + +#container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; +} + +html::view-transition-group(*) { + animation-play-state: paused; +} + +html::view-transition-new(*) { + animation: unset; + opacity: 0; +} + +html::view-transition-old(*) { + animation: unset; + opacity: 1; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: red; } +/* also test this type of construct */ +html:active-view-transition::view-transition { background: lightpink } +</style> + +<div id="container"> + <div class="test" id="positive1"></div> + <div class="test" id="positive2"></div> + <div class="test" id="positive3"></div> + <div class="test" id="positive4"></div> + <div class="test" id="positive5"></div> + <div class="test" id="positive6"></div> + <div class="test" id="positive7"></div> + <div class="test" id="positive8"></div> + <div class="test" id="negative1"></div> + <div class="test" id="negative2"></div> + <div class="test" id="negative3"></div> + <div class="test" id="negative4"></div> + <div class="test" id="negative5"></div> + <div class="test" id="negative6"></div> + <div class="test" id="negative7"></div> +</div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition({ + types: ["foo", "bar"] + }); + transition.ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html new file mode 100644 index 00000000000..f1940c39869 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>ViewTransitionTypeSet should not crash when documentElement is null</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + + test(() => { + assert_implements(document.startViewTransition); + + const { types } = document.startViewTransition(); + document.documentElement.remove(); + types.add("a"); + assert_array_equals([...types], ["a"]); + }, "ViewTransitionTypeSet should not crash when documentElement is null"); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable.html new file mode 100644 index 00000000000..86c77d615ab --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<title>View behavior of ViewTransitionTypeSet</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + + test(() => { + assert_implements(document.startViewTransition); + const { types } = document.startViewTransition(); + assert_true(types instanceof ViewTransitionTypeSet); + }, "ViewTransition.types is a ViewTransitionTypeSet"); + + test(() => { + assert_implements(document.startViewTransition); + const { types } = document.startViewTransition(); + types.add("a"); + types.add("b"); + assert_array_equals([...types], ["a", "b"]); + assert_array_equals(Array.from(types), ["a", "b"]); + types.delete("b"); + assert_array_equals([...types], ["a"]); + assert_true(types.has("a")); + types.add("a"); + assert_array_equals([...types], ["a"]); + types.add("."); + types.add(""); + types.add("123"); + assert_array_equals([...types], ["a", ".", "", "123"]); + }, "ViewTransitionTypeSet behaves like an ordinary Set of strings"); + + promise_test(async () => { + assert_implements(document.startViewTransition); + const transition = document.startViewTransition(); + transition.types.add("a"); + await transition.finished; + assert_array_equals([...transition.types], ["a"]); + transition.types.add("b"); + assert_array_equals([...transition.types], ["a", "b"]); + }, "ViewTransitionTypeSet should reflect its members for a non-active transition"); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-one-green-square-ref.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-one-green-square-ref.html new file mode 100644 index 00000000000..4e66b92bc49 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-one-green-square-ref.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>View transitions: reference that has one green square</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> + +<style> +#target { + width: 100px; + height: 100px; + background: green; +} +body { + background: lightpink; +} +</style> + +<div id="target"></div> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-removed.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-removed.html new file mode 100644 index 00000000000..fe458efafd3 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-removed.html @@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type no longer matches after transition</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +body { background: lightpink; } +html:active-view-transition-type(type-name) #target { + background: red; +} + +#target { + view-transition-name: target; + background: green; + width: 100px; + height: 100px; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: white; } +</style> + +<div id="target"></div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition({ + types: ["type-name"] + }); + transition.finished.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-mutation.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-mutation.html new file mode 100644 index 00000000000..ba8b5e1e3c8 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-mutation.html @@ -0,0 +1,94 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type reserved keywords</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-reserved-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + html:active-view-transition-type(foo) #positive1 { + background: green; + } + + html:active-view-transition-type(none, NoNe) #negative1 { + background: red; + } + + html:active-view-transition-type(-ua-foo, -UA-foo) #negative2 { + background: red; + } + + .test { + width: 100px; + height: 100px; + } + + #positive1 { + view-transition-name: positive1; + background: red + } + + #negative1 { + view-transition-name: negative1; + background: green + } + + #negative2 { + view-transition-name: negative2; + background: green + } + + #container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; + } + + html::view-transition-group(*) { + animation-play-state: paused; + } + + html::view-transition-new(*) { + animation: unset; + opacity: 0; + } + + html::view-transition-old(*) { + animation: unset; + opacity: 1; + } + + html::view-transition-group(root) { + display: none; + } + + html::view-transition { + background: red; + } + + /* also test this type of construct */ + html:active-view-transition::view-transition { + background: lightpink + } +</style> + +<div id="container"> + <div class="test" id="positive1"></div> + <div class="test" id="negative1"></div> + <div class="test" id="negative2"></div> +</div> + +<script> + failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + + function runTest() { + let transition = document.startViewTransition(); + for (const type of ["-ua-foo", "none", "foo", "NoNe", "-UA-foo"]) + transition.types.add(type); + transition.ready.then(takeScreenshot); + } + onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> + +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-ref.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-ref.html new file mode 100644 index 00000000000..9195d081147 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved-ref.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>View transitions: active-view-transition-type reserved keywords (ref)</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<style> + +.test { + width: 100px; + height: 100px; + background: green; +} +#container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; +} +body { background: lightpink; } +</style> + +<div id="container"> + <div class="test"></div> + <div class="test"></div> + <div class="test"></div> +</div> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved.html new file mode 100644 index 00000000000..1dca3774aa4 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-reserved.html @@ -0,0 +1,69 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type reserved keywords</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-reserved-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +html:active-view-transition-type(foo) #positive1 { background: green; } +html:active-view-transition-type(none, NoNe) #negative1 { background: red; } +html:active-view-transition-type(-ua-foo, -UA-foo) #negative2 { background: red; } + +.test { + width: 100px; + height: 100px; +} +#positive1 { view-transition-name: positive1; background: red } +#negative1 { view-transition-name: negative1; background: green } +#negative2 { view-transition-name: negative2; background: green } + +#container { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-gap: 10px; +} + +html::view-transition-group(*) { + animation-play-state: paused; +} + +html::view-transition-new(*) { + animation: unset; + opacity: 0; +} + +html::view-transition-old(*) { + animation: unset; + opacity: 1; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: red; } +/* also test this type of construct */ +html:active-view-transition::view-transition { background: lightpink } +</style> + +<div id="container"> + <div class="test" id="positive1"></div> + <div class="test" id="negative1"></div> + <div class="test" id="negative2"></div> +</div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition({ + types: ["-ua-foo", "none", "foo", "NoNe", "-UA-foo"] + }); + transition.ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-stay.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-stay.html new file mode 100644 index 00000000000..dc738e6912c --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-stay.html @@ -0,0 +1,58 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition-type stays active into animation</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +html:active-view-transition-type(type-name) #target { + background: green; + view-transition-name: target; +} + +#target { + background: red; + width: 100px; + height: 100px; +} + +html::view-transition-group(target) { + animation-play-state: paused; +} + +html::view-transition-new(target) { + animation: unset; + opacity: 1; +} + +html::view-transition-old(target) { + animation: unset; + opacity: 0; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: lightpink; } +</style> + +<div id="target"></div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition({ + types: ["type-name"] + }); + transition.ready.then(() => requestAnimationFrame(() => { + requestAnimationFrame(takeScreenshot); + })); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-universal-match.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-universal-match.html new file mode 100644 index 00000000000..534c144ecf0 --- /dev/null +++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-universal-match.html @@ -0,0 +1,54 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>View transitions: active-view-transition matches callback syntax</title> +<link rel="help" href="https://www.w3.org/TR/css-transitions-2/"> +<link rel="author" href="mailto:vmpstr@chromium.org"> +<link rel="match" href="view-transition-types-one-green-square-ref.html"> + +<script src="/common/reftest-wait.js"></script> +<style> + +html:active-view-transition #target { + background: green; + view-transition-name: target; +} + +#target { + background: red; + width: 100px; + height: 100px; +} + +html::view-transition-group(target) { + animation-play-state: paused; +} + +html::view-transition-new(target) { + animation: unset; + opacity: 0; +} + +html::view-transition-old(target) { + animation: unset; + opacity: 1; +} + +html::view-transition-group(root) { + display: none; +} + +html::view-transition { background: lightpink; } +</style> + +<div id="target"></div> + +<script> +failIfNot(document.startViewTransition, "Missing document.startViewTransition"); + +function runTest() { + let transition = document.startViewTransition(); + transition.ready.then(takeScreenshot); +} +onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest)); +</script> +</html> diff --git a/tests/wpt/tests/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html b/tests/wpt/tests/css/cssom/CSSStyleSheet-constructable-baseURL.html index 8997a59e9c1..d0f0f828b03 100644 --- a/tests/wpt/tests/css/cssom/CSSStyleSheet-constructable-baseURL.tentative.html +++ b/tests/wpt/tests/css/cssom/CSSStyleSheet-constructable-baseURL.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <title>CSSStyleSheet baseURL</title> <link rel="author" title="Erik Nordin" href="mailto:enordin@mozilla.com"> -<link rel="help" href="https://github.com/WICG/construct-stylesheets/issues/95#issuecomment-593545252"> +<link rel="help" href="https://drafts.csswg.org/cssom-1/#dom-cssstylesheetinit-baseurl"> <div id="target"></div> <script src='/resources/testharness.js'></script> <script src='/resources/testharnessreport.js'></script> diff --git a/tests/wpt/tests/css/motion/WEB_FEATURES.yml b/tests/wpt/tests/css/motion/WEB_FEATURES.yml new file mode 100644 index 00000000000..0a436801cb7 --- /dev/null +++ b/tests/wpt/tests/css/motion/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: motion-path + files: "**" diff --git a/tests/wpt/tests/custom-elements/form-associated/WEB_FEATURES.yml b/tests/wpt/tests/custom-elements/form-associated/WEB_FEATURES.yml new file mode 100644 index 00000000000..e40f6e12ae4 --- /dev/null +++ b/tests/wpt/tests/custom-elements/form-associated/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: form-associated-custom-elements + files: "**" diff --git a/tests/wpt/tests/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html b/tests/wpt/tests/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html index e21c9dd0332..11cecb1533b 100644 --- a/tests/wpt/tests/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html +++ b/tests/wpt/tests/custom-elements/scoped-registry/ShadowRoot-innerHTML-upgrade.tentative.html @@ -9,6 +9,9 @@ <div id="testdiv"></div> <script> +class GloballyScopedElement extends HTMLElement {}; +customElements.define('globally-scoped', GloballyScopedElement); + class TestAutonomous extends HTMLElement {}; class TestCustomizedBuiltIn extends HTMLParagraphElement {}; @@ -113,4 +116,13 @@ test(t => { assert_false(shadow3.firstChild instanceof TestCustomizedBuiltIn, 'tree scope with different registry'); assert_false(testdiv.firstChild instanceof TestCustomizedBuiltIn, 'main document'); }, 'Upgrade into customized built-in element when definition is added'); + +test(t => { + const registry = new CustomElementRegistry; + + const shadow = attachShadowForTest(t, registry); + shadow.innerHTML = '<globally-scoped></globally-scoped>'; + assert_false(shadow.firstChild instanceof GloballyScopedElement, 'is not GloballyScoped'); + +}, 'Upgrade into autonomous custom element should not inherit from global registry for missing values'); </script> diff --git a/tests/wpt/tests/direct-sockets/META.yml b/tests/wpt/tests/direct-sockets/META.yml index 85c05e8c834..ace03410a23 100644 --- a/tests/wpt/tests/direct-sockets/META.yml +++ b/tests/wpt/tests/direct-sockets/META.yml @@ -1,5 +1,3 @@ spec: https://github.com/WICG/direct-sockets/blob/main/docs/explainer.md suggested_reviewers: - - ewilligers - - mgiuca - - phoglenix + - greengrape diff --git a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html b/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html index f2f6e50be0f..cc2f58b76a6 100644 --- a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html +++ b/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html @@ -1,14 +1,26 @@ <!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" /> - <title>Sockets test: Can be disabled by permissions policy</title> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - <script src="/resources/testdriver.js"></script> - <script src="/resources/testdriver-vendor.js"></script> - </head> - <body> - <script src="disabled-by-permissions-policy.js"></script> - </body> -</html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + +'use strict'; + +test(() => { + assert_throws_dom("NotAllowedError", () => { + new TCPSocket("127.0.0.1", 53); + }, "constructor should throw"); +}, "TCPSocket disabled by permissions-policy"); + +test(() => { + assert_throws_dom("NotAllowedError", () => { + new UDPSocket({ remoteAddress: "127.0.0.1", remotePort: 53 }); + }, "constructor should throw"); +}, "UDPSocket disabled by permissions-policy"); + +test(() => { + assert_throws_dom("NotAllowedError", () => { + new TCPServerSocket("127.0.0.1"); + }, "constructor should throw"); +}, "TCPServerSocket disabled by permissions-policy"); + +</script> diff --git a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html.headers b/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html.headers index ba6f09f55b3..661a357effc 100644 --- a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html.headers +++ b/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.https.sub.html.headers @@ -1,3 +1,3 @@ Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp -Permissions-Policy: direct-sockets=()
\ No newline at end of file +Permissions-Policy: direct-sockets=() diff --git a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.js b/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.js deleted file mode 100644 index a27d1ddf497..00000000000 --- a/tests/wpt/tests/direct-sockets/disabled-by-permissions-policy.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -test(() => { - assert_throws_dom("NotAllowedError", () => new TCPSocket("address.com", 53), "constructor should throw"); -}, "tcp disabled by permissions-policy"); -test(() => { - assert_throws_dom("NotAllowedError", () => new UDPSocket({ remoteAddress: "address.com", remotePort: 53 }), "constructor should throw"); -}, "udp disabled by permissions-policy"); diff --git a/tests/wpt/tests/direct-sockets/open-securecontext.http.html b/tests/wpt/tests/direct-sockets/open-securecontext.http.html deleted file mode 100644 index c3a2a42a25b..00000000000 --- a/tests/wpt/tests/direct-sockets/open-securecontext.http.html +++ /dev/null @@ -1,21 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Sockets test: Open from non-secure context</title> - <link rel="help" href="https://github.com/WICG/direct-sockets/blob/main/docs/explainer.md#security-considerations"> - <script src="/resources/testharness.js"></script> - <script src="/resources/testharnessreport.js"></script> - </head> - <body> - <script> - test(() => { - assert_false(typeof TCPSocket !== 'undefined', 'TCPSocket is present'); - }, 'TCPSocket must be undefined in non-secure context'); - - test(() => { - assert_false(typeof UDPSocket !== 'undefined', 'UDPSocket is present'); - }, 'UDPSocket must be undefined in non-secure context'); - </script> - </body> -</html> diff --git a/tests/wpt/tests/direct-sockets/tcp_socket.https.html b/tests/wpt/tests/direct-sockets/tcp_socket.https.html new file mode 100644 index 00000000000..10d21ce42b9 --- /dev/null +++ b/tests/wpt/tests/direct-sockets/tcp_socket.https.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/test-only-api.js"></script> +<script> +'use strict'; + +promise_test(async () => { + const kPacket = "I'm a netcat. Meow-meow!" + + const serverSocket = new TCPServerSocket("127.0.0.1"); + const { localPort } = await serverSocket.opened; + + const clientSocket = new TCPSocket("127.0.0.1", localPort); + const acceptedSocket = await (async () => { + const { readable } = await serverSocket.opened; + const reader = readable.getReader(); + const { value: acceptedSocket, done } = await reader.read(); + assert_false(done); + reader.releaseLock(); + return acceptedSocket; + })(); + + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + + const readPacket = async socket => { + const { readable } = await socket.opened; + const reader = readable.getReader(); + let result = ""; + while (result.length < kPacket.length) { + const { value, done } = await reader.read(); + assert_false(done); + result += decoder.decode(value); + } + assert_equals(result, kPacket); + reader.releaseLock(); + }; + + const sendPacket = async socket => { + const { writable } = await socket.opened; + const writer = writable.getWriter(); + await writer.ready; + await writer.write(encoder.encode(kPacket)); + writer.releaseLock(); + }; + + const acceptedSocketEcho = (async () => { + await readPacket(acceptedSocket); + await sendPacket(acceptedSocket); + })(); + + const clientSocketSend = (async () => { + await sendPacket(clientSocket); + })(); + + const clientSocketReceive = (async () => { + await readPacket(clientSocket); + })(); + + await clientSocketReceive; + + await clientSocket.close(); + await acceptedSocket.close(); + await serverSocket.close(); + +}, 'TCPSocket exchanges packets with TCPServerSocket'); +</script> diff --git a/tests/wpt/tests/direct-sockets/tcp_socket.https.html.headers b/tests/wpt/tests/direct-sockets/tcp_socket.https.html.headers new file mode 100644 index 00000000000..177feb102db --- /dev/null +++ b/tests/wpt/tests/direct-sockets/tcp_socket.https.html.headers @@ -0,0 +1,3 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp +Permissions-Policy: direct-sockets=(self) diff --git a/tests/wpt/tests/direct-sockets/udp_socket.https.html b/tests/wpt/tests/direct-sockets/udp_socket.https.html new file mode 100644 index 00000000000..c95d41e2bde --- /dev/null +++ b/tests/wpt/tests/direct-sockets/udp_socket.https.html @@ -0,0 +1,95 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/test-only-api.js"></script> +<script> +'use strict'; + +promise_test(async () => { + const kRequiredDatagrams = 150; + const kRequiredBytes = + kRequiredDatagrams * (kRequiredDatagrams + 1) / 2; + + const boundSocket = new UDPSocket({ localAddress: "127.0.0.1" }); + const { localPort: boundLocalPort } = await boundSocket.opened; + + const connectedSocket = new UDPSocket({ + remoteAddress: "127.0.0.1", + remotePort: boundLocalPort, + }); + + const { + localAddress: clientAddress, + localPort: clientPort + } = await connectedSocket.opened; + + const boundEchoLoop = (async() => { + let bytesEchoed = 0; + + const { readable, writable } = await boundSocket.opened; + const reader = readable.getReader(); + const writer = writable.getWriter(); + + while (bytesEchoed < kRequiredBytes) { + const { value: { data, remoteAddress, remotePort }, done } = await reader.read(); + assert_false(done); + assert_equals(remoteAddress, clientAddress); + assert_equals(remotePort, clientPort); + for (let index = 0; index < data.length; index++) { + assert_equals(data[index], bytesEchoed % 256); + bytesEchoed++; + } + await writer.write({ data, remoteAddress, remotePort }); + } + + assert_equals(bytesEchoed, kRequiredBytes); + reader.releaseLock(); + writer.releaseLock(); + })(); + + const connectedSendLoop = (async () => { + let bytesWritten = 0; + let chunkLength = 0; + + const { writable } = await connectedSocket.opened; + const writer = writable.getWriter(); + + while (bytesWritten < kRequiredBytes) { + chunkLength = Math.min(chunkLength + 1, kRequiredBytes - bytesWritten); + let chunk = new Uint8Array(chunkLength); + for (let index = 0; index < chunkLength; index++) { + chunk[index] = bytesWritten % 256; + bytesWritten++; + } + await writer.ready; + await writer.write({ data: chunk }); + } + assert_equals(bytesWritten, kRequiredBytes); + writer.releaseLock(); + })(); + + const connectedReadLoop = (async () => { + let bytesRead = 0; + + const { readable } = await connectedSocket.opened; + const reader = readable.getReader(); + + while (bytesRead < kRequiredBytes) { + const { value: { data }, done } = await reader.read(); + assert_false(done); + for (let index = 0; index < data.length; index++) { + assert_equals(data[index], bytesRead % 256); + bytesRead++; + } + } + assert_equals(bytesRead, kRequiredBytes); + + reader.releaseLock(); + })(); + + await connectedReadLoop; + + await boundSocket.close(); + await connectedSocket.close(); +}, "UDPSocket (connected) exchanges datagrams with UDPSocket (bound)"); +</script> diff --git a/tests/wpt/tests/direct-sockets/udp_socket.https.html.headers b/tests/wpt/tests/direct-sockets/udp_socket.https.html.headers new file mode 100644 index 00000000000..177feb102db --- /dev/null +++ b/tests/wpt/tests/direct-sockets/udp_socket.https.html.headers @@ -0,0 +1,3 @@ +Cross-Origin-Opener-Policy: same-origin +Cross-Origin-Embedder-Policy: require-corp +Permissions-Policy: direct-sockets=(self) diff --git a/tests/wpt/tests/eventsource/eventsource-request-cancellation.any.window.js b/tests/wpt/tests/eventsource/eventsource-request-cancellation.window.js index 1cee9b742ea..1cee9b742ea 100644 --- a/tests/wpt/tests/eventsource/eventsource-request-cancellation.any.window.js +++ b/tests/wpt/tests/eventsource/eventsource-request-cancellation.window.js diff --git a/tests/wpt/tests/fetch/api/response/response-arraybuffer-realm.window.js b/tests/wpt/tests/fetch/api/response/response-arraybuffer-realm.window.js new file mode 100644 index 00000000000..19a5dfa5ff6 --- /dev/null +++ b/tests/wpt/tests/fetch/api/response/response-arraybuffer-realm.window.js @@ -0,0 +1,23 @@ +// META: title=realm of Response arrayBuffer() + +'use strict'; + +promise_test(async () => { + await new Promise(resolve => { + onload = resolve; + }); + + let iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + iframe.srcdoc = '<!doctype html>'; + await new Promise(resolve => { + iframe.onload = resolve; + }); + + let otherRealm = iframe.contentWindow; + + let ab = await window.Response.prototype.arrayBuffer.call(new otherRealm.Response('')); + + assert_true(ab instanceof otherRealm.ArrayBuffer, "ArrayBuffer should be created in receiver's realm"); + assert_false(ab instanceof ArrayBuffer, "ArrayBuffer should not be created in the arrayBuffer() methods's realm"); +}, 'realm of the ArrayBuffer from Response arrayBuffer()'); diff --git a/tests/wpt/tests/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js b/tests/wpt/tests/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js new file mode 100644 index 00000000000..881bdd23f93 --- /dev/null +++ b/tests/wpt/tests/fetch/fetch-later/send-on-deactivate-with-background-sync.tentative.https.window.js @@ -0,0 +1,128 @@ +// META: script=/resources/testdriver.js +// META: script=/resources/testdriver-vendor.js +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/fetch/fetch-later/resources/fetch-later-helper.js +// META: timeout=long + +'use strict'; + +async function setBackgroundSyncEnabled(enabled) { + const status = enabled ? 'granted' : 'denied'; + await test_driver.set_permission({name: 'background-sync'}, status); +} + +parallelPromiseTest(async t => { + // Enables BackgroundSync permission such that deferred request won't be + // immediately sent out on entering BFCache. + await setBackgroundSyncEnabled(true); + + const uuid = token(); + const url = generateSetBeaconURL(uuid); + // Sets no option to test the default behavior when a document enters BFCache. + const helper = new RemoteContextHelper(); + // Opens a window with noopener so that BFCache will work. + const rc1 = await helper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + + // Creates a fetchLater request with default config in remote, which should + // only be sent on page discarded (not on entering BFCache). + await rc1.executeScript(url => { + fetchLater(url); + // Add a pageshow listener to stash the BFCache event. + window.addEventListener('pageshow', e => { + window.pageshowEvent = e; + }); + }, [url]); + // Navigates away to let page enter BFCache. + const rc2 = await rc1.navigateToNew(); + // Navigates back. + await rc2.historyBack(); + // Verifies the page was BFCached. + assert_true(await rc1.executeScript(() => { + return window.pageshowEvent.persisted; + })); + + // By default, pending requests are all flushed on BFCache no matter + // BackgroundSync is on or not. See http://b/310541607#comment28. + await expectBeacon(uuid, {count: 1}); +}, `fetchLater() does send on page entering BFCache even if BackgroundSync is on.`); + +parallelPromiseTest(async t => { + // Enables BackgroundSync permission such that deferred request won't be + // immediately sent out on entering BFCache. + await setBackgroundSyncEnabled(true); + + const uuid = token(); + const url = generateSetBeaconURL(uuid); + // activateAfter = 0s means the request should be sent out right on + // document becoming deactivated (BFCached or frozen) after navigating away. + const options = {activateAfter: 0}; + const helper = new RemoteContextHelper(); + // Opens a window with noopener so that BFCache will work. + const rc1 = await helper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + + // Creates a fetchLater request in remote which should only be sent on + // navigating away. + await rc1.executeScript((url, options) => { + fetchLater(url, options); + + // Add a pageshow listener to stash the BFCache event. + window.addEventListener('pageshow', e => { + window.pageshowEvent = e; + }); + }, [url, options]); + // Navigates away to trigger request sending. + const rc2 = await rc1.navigateToNew(); + // Navigates back. + await rc2.historyBack(); + // Verifies the page was BFCached. + assert_true(await rc1.executeScript(() => { + return window.pageshowEvent.persisted; + })); + + await expectBeacon(uuid, {count: 1}); +}, `fetchLater() with activateAfter=0 sends on page entering BFCache if BackgroundSync is on.`); + +parallelPromiseTest(async t => { + // Enables BackgroundSync permission such that deferred request won't be + // immediately sent out on entering BFCache. + await setBackgroundSyncEnabled(true); + + const uuid = token(); + const url = generateSetBeaconURL(uuid); + // activateAfter = 1m means the request should NOT be sent out on + // document becoming deactivated (BFCached or frozen) until after 1 minute. + const options = {activateAfter: 60000}; + const helper = new RemoteContextHelper(); + // Opens a window with noopener so that BFCache will work. + const rc1 = await helper.addWindow( + /*config=*/ null, /*options=*/ {features: 'noopener'}); + + // Creates a fetchLater request in remote which should only be sent on + // navigating away. + await rc1.executeScript((url, options) => { + fetchLater(url, options); + + // Adds a pageshow listener to stash the BFCache event. + window.addEventListener('pageshow', e => { + window.pageshowEvent = e; + }); + }, [url, options]); + // Navigates away to trigger request sending. + const rc2 = await rc1.navigateToNew(); + // Navigates back. + await rc2.historyBack(); + // Verifies the page was BFCached. + assert_true(await rc1.executeScript(() => { + return window.pageshowEvent.persisted; + })); + + // By default, pending requests are all flushed on BFCache no matter + // BackgroundSync is on or not. See http://b/310541607#comment28. + await expectBeacon(uuid, {count: 1}); +}, `fetchLater() with activateAfter=1m does send on page entering BFCache even if BackgroundSync is on.`); diff --git a/tests/wpt/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js b/tests/wpt/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js index 37a61c12b56..b617911105a 100644 --- a/tests/wpt/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js +++ b/tests/wpt/tests/fetch/h1-parsing/resources-with-0x00-in-header.window.js @@ -1,3 +1,5 @@ +// META: script=/common/get-host-info.sub.js + async_test(t => { const script = document.createElement("script"); t.add_cleanup(() => script.remove()); @@ -29,3 +31,7 @@ async_test(t => { img.onload = t.unreached_func(); document.body.append(img); }, "Expect network error for image with 0x00 in a header"); + +promise_test(async t => { + return promise_rejects_js(t, TypeError, fetch(get_host_info().HTTP_REMOTE_ORIGIN + "/fetch/h1-parsing/resources/blue-with-0x00-in-a-header.asis", {mode:"no-cors"})); +}, "Expect network error for fetch with 0x00 in a header"); diff --git a/tests/wpt/tests/fetch/metadata/WEB_FEATURES.yml b/tests/wpt/tests/fetch/metadata/WEB_FEATURES.yml new file mode 100644 index 00000000000..fb48eaa3112 --- /dev/null +++ b/tests/wpt/tests/fetch/metadata/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: fetch-metadata + files: "**" diff --git a/tests/wpt/tests/fledge/tentative/auction-config.https.window.js b/tests/wpt/tests/fledge/tentative/auction-config.https.window.js index 057b4d7f785..b5f55149164 100644 --- a/tests/wpt/tests/fledge/tentative/auction-config.https.window.js +++ b/tests/wpt/tests/fledge/tentative/auction-config.https.window.js @@ -242,9 +242,12 @@ makeTest({ } }); +// Cross-origin trustedScoringSignalsURL is fine, but it needs extra +// headers to actually make it work. The auction here doesn't actually +// care if the signals don't load. makeTest({ name: 'trustedScoringSignalsURL is cross-origin with seller', - expect: EXPECT_EXCEPTION(TypeError), + expect: EXPECT_WINNER, auctionConfigOverrides: { trustedScoringSignalsURL: "https://example.com" }, }); diff --git a/tests/wpt/tests/fledge/tentative/network.https.window.js b/tests/wpt/tests/fledge/tentative/network.https.window.js index fe287767c8d..0b41662155a 100644 --- a/tests/wpt/tests/fledge/tentative/network.https.window.js +++ b/tests/wpt/tests/fledge/tentative/network.https.window.js @@ -6,7 +6,8 @@ // META: timeout=long // META: variant=?1-5 // META: variant=?6-10 -// META: variant=?11-last +// META: variant=?11-15 +// META: variant=?16-last "use strict"; @@ -37,22 +38,6 @@ function createRedirectURL(location) { return url.toString(); } -// Delete all cookies. Separate function so that can be replaced with -// something else for testing outside of a WPT environment. -async function deleteAllCookies() { - await test_driver.delete_all_cookies(); -} - -// Deletes all cookies (to avoid pre-existing cookies causing inconsistent -// output on failure) and sets a cookie with name "cookie" and a value of -// "cookie". Adds a cleanup task to delete all cookies again when the test -// is done. -async function setCookie(test) { - await deleteAllCookies(); - document.cookie = 'cookie=cookie; path=/' - test.add_cleanup(deleteAllCookies); -} - // Assert that "headers" has a single header with "name", whose value is "value". function assertHasHeader(headers, name, value) { assert_equals(JSON.stringify(headers[name]), JSON.stringify([value]), @@ -213,7 +198,7 @@ subsetTest(promise_test, async test => { } checkHeader("accept", "application/json"); checkHeader("sec-fetch-dest", "empty"); - checkHeader("sec-fetch-mode", "no-cors"); + checkHeader("sec-fetch-mode", "cors"); checkHeader("sec-fetch-site", "same-origin"); if (headers.cookie !== undefined) throw "Unexpected cookie: " + JSON.stringify(headers.cookie); @@ -226,6 +211,40 @@ subsetTest(promise_test, async test => { subsetTest(promise_test, async test => { const uuid = generateUuid(test); + let cookieFrame = await createFrame(test, OTHER_ORIGIN1); + await runInFrame(test, cookieFrame, `await setCookie(test_instance)`); + + await joinGroupAndRunBasicFledgeTestExpectingWinner( + test, + { uuid: uuid, + interestGroupOverrides: { + trustedBiddingSignalsURL: CROSS_ORIGIN_TRUSTED_BIDDING_SIGNALS_URL, + trustedBiddingSignalsKeys: ['headers', 'cors'], + biddingLogicURL: createBiddingScriptURL({ + generateBid: + `let headers = crossOriginTrustedBiddingSignals[ + '${OTHER_ORIGIN1}'].headers; + function checkHeader(name, value) { + jsonActualValue = JSON.stringify(headers[name]); + if (jsonActualValue !== JSON.stringify([value])) + throw "Unexpected " + name + ": " + jsonActualValue; + } + checkHeader("accept", "application/json"); + checkHeader("sec-fetch-dest", "empty"); + checkHeader("sec-fetch-mode", "cors"); + checkHeader("sec-fetch-site", "cross-site"); + checkHeader("origin", "${window.location.origin}"); + if (headers.cookie !== undefined) + throw "Unexpected cookie: " + JSON.stringify(headers.cookie); + if (headers.referer !== undefined) + throw "Unexpected referer: " + JSON.stringify(headers.referer);`, + }) + } + }); +}, 'cross-origin trustedBiddingSignalsURL request headers.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); await deleteAllCookies(); await joinGroupAndRunBasicFledgeTestExpectingWinner( @@ -282,7 +301,7 @@ subsetTest(promise_test, async test => { } checkHeader("accept", "application/json"); checkHeader("sec-fetch-dest", "empty"); - checkHeader("sec-fetch-mode", "no-cors"); + checkHeader("sec-fetch-mode", "cors"); checkHeader("sec-fetch-site", "same-origin"); if (headers.cookie !== undefined) throw "Unexpected cookie: " + JSON.stringify(headers.cookie); @@ -295,6 +314,46 @@ subsetTest(promise_test, async test => { subsetTest(promise_test, async test => { const uuid = generateUuid(test); + let cookieFrame = await createFrame(test, OTHER_ORIGIN1); + await runInFrame(test, cookieFrame, `await setCookie(test_instance)`); + + let renderURL = createRenderURL(uuid, /*script=*/null, /*signalsParam=*/'headers,cors'); + + await joinGroupAndRunBasicFledgeTestExpectingWinner( + test, + { uuid: uuid, + interestGroupOverrides: { + ads: [{ renderURL: renderURL }] + }, + auctionConfigOverrides: { + trustedScoringSignalsURL: CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL, + decisionLogicURL: createDecisionScriptURL(uuid, + { + permitCrossOriginTrustedSignals: `"${OTHER_ORIGIN1}"`, + scoreAd: + `let headers = crossOriginTrustedScoringSignals[ + '${OTHER_ORIGIN1}'].renderURL["${renderURL}"]; + function checkHeader(name, value) { + jsonActualValue = JSON.stringify(headers[name]); + if (jsonActualValue !== JSON.stringify([value])) + throw "Unexpected " + name + ": " + jsonActualValue; + } + checkHeader("accept", "application/json"); + checkHeader("sec-fetch-dest", "empty"); + checkHeader("sec-fetch-mode", "cors"); + checkHeader("sec-fetch-site", "cross-site"); + checkHeader("origin", "${window.location.origin}"); + if (headers.cookie !== undefined) + throw "Unexpected cookie: " + JSON.stringify(headers.cookie); + if (headers.referer !== undefined) + throw "Unexpected referer: " + JSON.stringify(headers.referer);`, + }) + } + }); +}, 'cross-origin trustedScoringSignalsURL request headers.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); await deleteAllCookies(); await joinGroupAndRunBasicFledgeTestExpectingWinner( diff --git a/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py b/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py index e17f2c2c75d..8c0539d43c8 100644 --- a/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py +++ b/tests/wpt/tests/fledge/tentative/resources/bidding-logic.sub.py @@ -58,7 +58,8 @@ def main(request, response): body += f""" function generateBid(interestGroup, auctionSignals, perBuyerSignals, trustedBiddingSignals, browserSignals, - directFromSellerSignals) {{ + directFromSellerSignals, + crossOriginTrustedBiddingSignals) {{ {{{{GET[generateBid]}}}}; return {{ bid: {bid}, diff --git a/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py b/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py index 3a23f981620..545c7e5e4f8 100644 --- a/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py +++ b/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py @@ -35,11 +35,18 @@ def main(request, response): if error == b"no-body": return b'' + permitCrossOriginTrustedSignals = request.GET.get( + b"permit-cross-origin-trusted-signals", None) + if permitCrossOriginTrustedSignals != None: + response.headers.set(b"Ad-Auction-Allow-Trusted-Scoring-Signals-From", + permitCrossOriginTrustedSignals) + body = (Path(__file__).parent.resolve() / 'worklet-helpers.js').read_text().encode("ASCII") if error != b"no-scoreAd": body += b""" function scoreAd(adMetadata, bid, auctionConfig, trustedScoringSignals, - browserSignals, directFromSellerSignals) { + browserSignals, directFromSellerSignals, + crossOriginTrustedScoringSignals) { // Don't bid on interest group with the wrong uuid. This is to prevent // left over interest groups from other tests from affecting auction // results. diff --git a/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js b/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js index a7d0f63830d..148613eef8d 100644 --- a/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js +++ b/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js @@ -26,6 +26,12 @@ const OTHER_ORIGIN5 = 'https://{{hosts[][www]}}:{{ports[https][1]}}'; const OTHER_ORIGIN6 = 'https://{{hosts[alt][www]}}:{{ports[https][0]}}'; const OTHER_ORIGIN7 = 'https://{{hosts[alt][www]}}:{{ports[https][1]}}'; +// Trusted signals hosted on OTHER_ORIGIN1 +const CROSS_ORIGIN_TRUSTED_BIDDING_SIGNALS_URL = OTHER_ORIGIN1 + BASE_PATH + + 'resources/trusted-bidding-signals.py'; +const CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL = OTHER_ORIGIN1 + BASE_PATH + + 'resources/trusted-scoring-signals.py'; + // Creates a URL that will be sent to the URL request tracker script. // `uuid` is used to identify the stash shard to use. // `dispatch` affects what the tracker script does. @@ -232,6 +238,10 @@ function createDecisionScriptURL(uuid, params = {}) { url.searchParams.append('reportResult', params.reportResult); if (params.error != null) url.searchParams.append('error', params.error); + if (params.permitCrossOriginTrustedSignals != null) { + url.searchParams.append('permit-cross-origin-trusted-signals', + params.permitCrossOriginTrustedSignals); + } return url.toString(); } @@ -859,3 +869,19 @@ function createStringBeforeAndAfterReplacements(deprecatedRenderURLReplacements) } return { beforeReplacements, afterReplacements }; } + +// Delete all cookies. Separate function so that can be replaced with +// something else for testing outside of a WPT environment. +async function deleteAllCookies() { + await test_driver.delete_all_cookies(); +} + +// Deletes all cookies (to avoid pre-existing cookies causing inconsistent +// output on failure) and sets a cookie with name "cookie" and a value of +// "cookie". Adds a cleanup task to delete all cookies again when the test +// is done. +async function setCookie(test) { + await deleteAllCookies(); + document.cookie = 'cookie=cookie; path=/' + test.add_cleanup(deleteAllCookies); +} diff --git a/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py b/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py index 162c93e8b06..92733eedf43 100644 --- a/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py +++ b/tests/wpt/tests/fledge/tentative/resources/fledge_http_server_util.py @@ -1,5 +1,6 @@ """Utility functions shared across multiple endpoints.""" - +from collections import namedtuple +from urllib.parse import unquote_plus, urlparse def headers_to_ascii(headers): """Converts a header map with binary values to one with ASCII values. @@ -65,3 +66,81 @@ def handle_cors_headers_and_preflight(request, response): response.status = (204, b"No Content") return True + +def decode_trusted_scoring_signals_params(request): + """Decodes query parameters to trusted query params handler. + + Args: + request: the wptserve Request that was passed to main + + If successful, returns a named tuple TrustedScoringSignalsParams decoding the + various expected query fields, as a hostname, plus a field urlLists which is a list of + {type: <render URL type>, urls: <render URL list>} pairs, where <render URL type> is + one of the two render URL dictionary keys used in the response ("renderURLs" or + "adComponentRenderURLs"). May be of length 1 or 2, depending on whether there + are any component URLs. + + On failure, throws a ValueError with a message. + """ + TrustedScoringSignalsParams = namedtuple( + 'TrustedScoringSignalsParams', ['hostname', 'urlLists']) + + hostname = None + renderUrls = None + adComponentRenderURLs = None + urlLists = [] + + # Manually parse query params. Can't use request.GET because it unescapes as well as splitting, + # and commas mean very different things from escaped commas. + for param in request.url_parts.query.split("&"): + pair = param.split("=", 1) + if len(pair) != 2: + raise ValueError("Bad query parameter: " + param) + # Browsers should escape query params consistently. + if "%20" in pair[1]: + raise ValueError("Query parameter should escape using '+': " + param) + + # Hostname can't be empty. The empty string can be a key or interest group name, though. + if pair[0] == "hostname" and hostname == None and len(pair[1]) > 0: + hostname = pair[1] + continue + if pair[0] == "renderUrls" and renderUrls == None: + renderUrls = list(map(unquote_plus, pair[1].split(","))) + urlLists.append({"type":"renderURLs", "urls":renderUrls}) + continue + if pair[0] == "adComponentRenderUrls" and adComponentRenderURLs == None: + adComponentRenderURLs = list(map(unquote_plus, pair[1].split(","))) + urlLists.append({"type":"adComponentRenderURLs", "urls":adComponentRenderURLs}) + continue + raise ValueError("Unexpected query parameter: " + param) + + # "hostname" and "renderUrls" are mandatory. + if not hostname: + raise ValueError("hostname missing") + if not renderUrls: + raise ValueError("renderUrls missing") + + return TrustedScoringSignalsParams(hostname, urlLists) + +def decode_render_url_signals_params(renderUrl): + """Decodes signalsParams field encoded inside a renderURL. + + Args: renderUrl to extract signalsParams from. + + Returns an array of fields in signal params string. + """ + signalsParams = None + for param in urlparse(renderUrl).query.split("&"): + pair = param.split("=", 1) + if len(pair) != 2: + continue + if pair[0] == "signalsParams": + if signalsParams != None: + raise ValueError("renderUrl has multiple signalsParams: " + renderUrl) + signalsParams = pair[1] + + if signalsParams is None: + return [] + + signalsParams = unquote_plus(signalsParams) + return signalsParams.split(",") diff --git a/tests/wpt/tests/fledge/tentative/resources/request-tracker.py b/tests/wpt/tests/fledge/tentative/resources/request-tracker.py index 3514741f634..dea8427266f 100644 --- a/tests/wpt/tests/fledge/tentative/resources/request-tracker.py +++ b/tests/wpt/tests/fledge/tentative/resources/request-tracker.py @@ -36,6 +36,29 @@ def main(request, response): dispatch = request.GET.first(b"dispatch", None) uuid = request.GET.first(b"uuid", None) + # If we're used as a trusted scoring signals handler, our params are + # smuggled in via renderURLs. We won't have dispatch and uuid provided + # directly then. + if dispatch is None and uuid is None: + try: + signals_params = fledge_http_server_util.decode_trusted_scoring_signals_params(request) + for urlList in signals_params.urlLists: + for renderUrl in urlList["urls"]: + try: + signalsParams = fledge_http_server_util.decode_render_url_signals_params(renderUrl) + except ValueError as ve: + return simple_response(request, response, 500, + b"InternalError", str(ve)) + for signalsParam in signalsParams: + if signalsParam.startswith("dispatch:"): + dispatch = signalsParam.split(':', 1)[1].encode("utf-8") + elif signalsParam.startswith("uuid:"): + uuid = signalsParam.split(':', 1)[1].encode("utf-8") + except ValueError: + # It doesn't look like a trusted scoring signals request, so + # never mind. + pass + if not uuid or not dispatch: return simple_response(request, response, 404, b"Not found", b"Invalid query parameters") diff --git a/tests/wpt/tests/fledge/tentative/resources/subordinate-frame.sub.html b/tests/wpt/tests/fledge/tentative/resources/subordinate-frame.sub.html index f5b1ef99595..ea1f0c44d62 100644 --- a/tests/wpt/tests/fledge/tentative/resources/subordinate-frame.sub.html +++ b/tests/wpt/tests/fledge/tentative/resources/subordinate-frame.sub.html @@ -5,6 +5,8 @@ <!--- Allow injected scripts to use functions in fledge-util.sub.js ---> <base href=".."> <script src="/resources/testharness.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> <script src="/common/utils.js"></script> <script src="resources/fledge-util.sub.js"></script> </head> diff --git a/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py b/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py index 955a7c0bdfa..5a89e3b6025 100644 --- a/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py +++ b/tests/wpt/tests/fledge/tentative/resources/trusted-bidding-signals.py @@ -39,6 +39,13 @@ def main(request, response): continue return fail(response, "Unexpected query parameter: " + param) + # If trusted signal keys are passed in, and one of them is "cors", + # add appropriate Access-Control-* headers to normal requests, and handle + # CORS preflights. + if keys and "cors" in keys and fledge_http_server_util.handle_cors_headers_and_preflight( + request, response): + return + # "interestGroupNames" and "hostname" are mandatory. if not hostname: return fail(response, "hostname missing") diff --git a/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py b/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py index ce53e762958..934d2e9129d 100644 --- a/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py +++ b/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py @@ -1,5 +1,4 @@ import json -from urllib.parse import unquote_plus, urlparse from fledge.tentative.resources import fledge_http_server_util @@ -11,44 +10,10 @@ from fledge.tentative.resources import fledge_http_server_util # each affect either the value associated with the renderUrl, or the # response as a whole. def main(request, response): - hostname = None - renderUrls = None - adComponentRenderURLs = None - # List of {type: <render URL type>, urls: <render URL list>} pairs, where <render URL type> is - # one of the two render URL dictionary keys used in the response ("renderURLs" or - # "adComponentRenderURLs"). May be of length 1 or 2, depending on whether there - # are any component URLs. - urlLists = [] - - # Manually parse query params. Can't use request.GET because it unescapes as well as splitting, - # and commas mean very different things from escaped commas. - for param in request.url_parts.query.split("&"): - pair = param.split("=", 1) - if len(pair) != 2: - return fail(response, "Bad query parameter: " + param) - # Browsers should escape query params consistently. - if "%20" in pair[1]: - return fail(response, "Query parameter should escape using '+': " + param) - - # Hostname can't be empty. The empty string can be a key or interest group name, though. - if pair[0] == "hostname" and hostname == None and len(pair[1]) > 0: - hostname = pair[1] - continue - if pair[0] == "renderUrls" and renderUrls == None: - renderUrls = list(map(unquote_plus, pair[1].split(","))) - urlLists.append({"type":"renderURLs", "urls":renderUrls}) - continue - if pair[0] == "adComponentRenderUrls" and adComponentRenderURLs == None: - adComponentRenderURLs = list(map(unquote_plus, pair[1].split(","))) - urlLists.append({"type":"adComponentRenderURLs", "urls":adComponentRenderURLs}) - continue - return fail(response, "Unexpected query parameter: " + param) - - # "hostname" and "renderUrls" are mandatory. - if not hostname: - return fail(response, "hostname missing") - if not renderUrls: - return fail(response, "renderUrls missing") + try: + params = fledge_http_server_util.decode_trusted_scoring_signals_params(request) + except ValueError as ve: + return fail(response, str(ve)) response.status = (200, b"OK") @@ -62,73 +27,76 @@ def main(request, response): contentType = "application/json" adAuctionAllowed = "true" dataVersion = None - for urlList in urlLists: + cors = False + for urlList in params.urlLists: for renderUrl in urlList["urls"]: value = "default value" addValue = True - signalsParams = None - for param in urlparse(renderUrl).query.split("&"): - pair = param.split("=", 1) - if len(pair) != 2: - continue - if pair[0] == "signalsParams": - if signalsParams != None: - return fail(response, "renderUrl has multiple signalsParams: " + renderUrl) - signalsParams = pair[1] - if signalsParams != None: - signalsParams = unquote_plus(signalsParams) - for signalsParam in signalsParams.split(","): - if signalsParam == "close-connection": - # Close connection without writing anything, to simulate a - # network error. The write call is needed to avoid writing the - # default headers. - response.writer.write("") - response.close_connection = True - return - elif signalsParam.startswith("replace-body:"): - # Replace entire response body. Continue to run through other - # renderUrls, to allow them to modify request headers. - body = signalsParam.split(':', 1)[1] - elif signalsParam.startswith("data-version:"): - dataVersion = signalsParam.split(':', 1)[1] - elif signalsParam == "http-error": - response.status = (404, b"Not found") - elif signalsParam == "no-content-type": - contentType = None - elif signalsParam == "wrong-content-type": - contentType = 'text/plain' - elif signalsParam == "bad-ad-auction-allowed": - adAuctionAllowed = "sometimes" - elif signalsParam == "ad-auction-not-allowed": - adAuctionAllowed = "false" - elif signalsParam == "no-ad-auction-allow": - adAuctionAllowed = None - elif signalsParam == "wrong-url": - renderUrl = "https://wrong-url.test/" - elif signalsParam == "no-value": - addValue = False - elif signalsParam == "null-value": - value = None - elif signalsParam == "num-value": - value = 1 - elif signalsParam == "string-value": - value = "1" - elif signalsParam == "array-value": - value = [1, "foo", None] - elif signalsParam == "object-value": - value = {"a":"b", "c":["d"]} - elif signalsParam == "hostname": - value = request.GET.first(b"hostname", b"not-found").decode("ASCII") - elif signalsParam == "headers": - value = fledge_http_server_util.headers_to_ascii(request.headers) - elif signalsParam == "url": - value = request.url + try: + signalsParams = fledge_http_server_util.decode_render_url_signals_params(renderUrl) + except ValueError as ve: + return fail(response, str(ve)) + + for signalsParam in signalsParams: + if signalsParam == "close-connection": + # Close connection without writing anything, to simulate a + # network error. The write call is needed to avoid writing the + # default headers. + response.writer.write("") + response.close_connection = True + return + elif signalsParam.startswith("replace-body:"): + # Replace entire response body. Continue to run through other + # renderUrls, to allow them to modify request headers. + body = signalsParam.split(':', 1)[1] + elif signalsParam.startswith("data-version:"): + dataVersion = signalsParam.split(':', 1)[1] + elif signalsParam == "http-error": + response.status = (404, b"Not found") + elif signalsParam == "no-content-type": + contentType = None + elif signalsParam == "wrong-content-type": + contentType = 'text/plain' + elif signalsParam == "bad-ad-auction-allowed": + adAuctionAllowed = "sometimes" + elif signalsParam == "ad-auction-not-allowed": + adAuctionAllowed = "false" + elif signalsParam == "no-ad-auction-allow": + adAuctionAllowed = None + elif signalsParam == "wrong-url": + renderUrl = "https://wrong-url.test/" + elif signalsParam == "no-value": + addValue = False + elif signalsParam == "null-value": + value = None + elif signalsParam == "num-value": + value = 1 + elif signalsParam == "string-value": + value = "1" + elif signalsParam == "array-value": + value = [1, "foo", None] + elif signalsParam == "object-value": + value = {"a":"b", "c":["d"]} + elif signalsParam == "hostname": + value = params.hostname + elif signalsParam == "headers": + value = fledge_http_server_util.headers_to_ascii(request.headers) + elif signalsParam == "url": + value = request.url + elif signalsParam == "cors": + cors = True if addValue: if urlList["type"] not in responseBody: responseBody[urlList["type"]] = {} responseBody[urlList["type"]][renderUrl] = value + # If the signalsParam embedded inside a render URL calls for CORS, add + # appropriate response headers, and fully handle preflights. + if cors and fledge_http_server_util.handle_cors_headers_and_preflight( + request, response): + return + if contentType: response.headers.set("Content-Type", contentType) if adAuctionAllowed: diff --git a/tests/wpt/tests/fledge/tentative/trusted-bidding-signals.https.window.js b/tests/wpt/tests/fledge/tentative/trusted-bidding-signals.https.window.js index 905abf8381e..205c6895a06 100644 --- a/tests/wpt/tests/fledge/tentative/trusted-bidding-signals.https.window.js +++ b/tests/wpt/tests/fledge/tentative/trusted-bidding-signals.https.window.js @@ -329,6 +329,34 @@ subsetTest(promise_test, async test => { }, 'Trusted bidding signals receives hostname field.'); ///////////////////////////////////////////////////////////////////////////// +// Cross-origin trusted bidding signals tests +///////////////////////////////////////////////////////////////////////////// + +subsetTest(promise_test, async test => { + await runTrustedBiddingSignalsTest( + test, + `trustedBiddingSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedBiddingSignals['${OTHER_ORIGIN1}']['num-value'] === 1 && + browserSignals.crossOriginDataVersion === 4`, + { name: 'data-version', + trustedBiddingSignalsKeys: ['num-value', 'cors'], + trustedBiddingSignalsURL: CROSS_ORIGIN_TRUSTED_BIDDING_SIGNALS_URL }); +}, 'Basic cross-origin trusted bidding signals'); + +subsetTest(promise_test, async test => { + await runTrustedBiddingSignalsTest( + test, + `trustedBiddingSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedBiddingSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + { name: 'data-version', + trustedBiddingSignalsKeys: ['num-value'], + trustedBiddingSignalsURL: CROSS_ORIGIN_TRUSTED_BIDDING_SIGNALS_URL }); +}, 'Cross-origin trusted bidding signals w/o CORS authorization'); + +///////////////////////////////////////////////////////////////////////////// // Data-Version tests ///////////////////////////////////////////////////////////////////////////// diff --git a/tests/wpt/tests/fledge/tentative/trusted-scoring-signals.https.window.js b/tests/wpt/tests/fledge/tentative/trusted-scoring-signals.https.window.js index 105b09fb3be..46570da3e41 100644 --- a/tests/wpt/tests/fledge/tentative/trusted-scoring-signals.https.window.js +++ b/tests/wpt/tests/fledge/tentative/trusted-scoring-signals.https.window.js @@ -12,7 +12,8 @@ // META: variant=?31-35 // META: variant=?36-40 // META: variant=?41-45 -// META: variant=?45-last +// META: variant=?45-50 +// META: variant=?50-last "use strict"; @@ -21,25 +22,25 @@ // to worklet scripts, and handling the Data-Version header. // Helper for trusted scoring signals tests. Runs an auction with -// TRUSTED_SCORING_SIGNALS_URL and a single interest group, failing the test -// if there's no winner. "scoreAdCheck" is an expression that should be true +// trustedSignalsURL and a single interest group, failing the test if there's no +// winner. "scoreAdCheck" is an expression that should be true // when evaluated in scoreAd(). "renderURL" can be used to control the response -// given for TRUSTED_SCORING_SIGNALS_URL. +// given for trustedSignalsURL. async function runTrustedScoringSignalsTest(test, uuid, renderURL, scoreAdCheck, - additionalInterestGroupOverrides) { + additionalInterestGroupOverrides, + trustedSignalsURL = TRUSTED_SCORING_SIGNALS_URL, + decisionScriptParamOverrides = {}) { const auctionConfigOverrides = { - trustedScoringSignalsURL: TRUSTED_SCORING_SIGNALS_URL, + trustedScoringSignalsURL: trustedSignalsURL, decisionLogicURL: createDecisionScriptURL(uuid, { - scoreAd: `if (!(${scoreAdCheck})) throw "error";` })}; - await joinGroupAndRunBasicFledgeTestExpectingWinner( - test, - { - uuid: uuid, - interestGroupOverrides: {ads: [{ renderURL: renderURL }], - ...additionalInterestGroupOverrides}, - auctionConfigOverrides: auctionConfigOverrides - }); + scoreAd: `if (!(${scoreAdCheck})) throw "error";`, + ...decisionScriptParamOverrides})}; + await joinInterestGroup(test, uuid, + {ads: [{ renderURL: renderURL }], + ...additionalInterestGroupOverrides}); + return await runBasicFledgeTestExpectingWinner( + test, uuid, auctionConfigOverrides); } // Much like runTrustedScoringSignalsTest, but runs auctions through reporting @@ -306,6 +307,124 @@ subsetTest(promise_test, async test => { }, 'Trusted scoring signals multiple renderURLs.'); ///////////////////////////////////////////////////////////////////////////// +// Cross-origin trusted scoring signals tests +///////////////////////////////////////////////////////////////////////////// +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/'string-value,data-version:3,cors'); + await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals['${OTHER_ORIGIN1}'].renderURL[ + "${renderURL}"] === "1" && + browserSignals.crossOriginDataVersion === 3`, + /*additionalInterestGroupOverrides=*/ {}, + CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL, + {permitCrossOriginTrustedSignals: `"${OTHER_ORIGIN1}"`}); +}, 'Basic cross-origin trusted scoring signals.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/'string-value,data-version:3'); + await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + /*additionalInterestGroupOverrides=*/ {}, + CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL, + {permitCrossOriginTrustedSignals: `"${OTHER_ORIGIN1}"`}); +}, 'Cross-origin trusted scoring signals w/o CORS authorization.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const sellerReportURL = createSellerReportURL(uuid); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/`string-value,data-version:3,uuid:${uuid},dispatch:track_get`); + // Use the request tracker for trusted scoring signals, to have it + // record whether they got fetched or not. + const crossOriginRequestTrackerURL = OTHER_ORIGIN1 + BASE_PATH + + 'resources/request-tracker.py'; + + let combinedTrustedSignalsURL = new URL(crossOriginRequestTrackerURL); + combinedTrustedSignalsURL.search = + `hostname=${window.location.hostname}&renderUrls=${encodeURIComponent(renderURL)}` + + let result = await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + /*additionalInterestGroupOverrides=*/ {}, + crossOriginRequestTrackerURL, + {permitCrossOriginTrustedSignals: `"${OTHER_ORIGIN1}"`, + reportResult: `sendReportTo("${sellerReportURL}")`}); + createAndNavigateFencedFrame(test, result); + await waitForObservedRequests( + uuid, [combinedTrustedSignalsURL.href, createBidderReportURL(uuid), sellerReportURL]); +}, 'Cross-origin trusted scoring signals w/o CORS authorization sends request.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/'string-value,data-version:3, cors'); + await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + /*additionalInterestGroupOverrides=*/ {}, + CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL); +}, 'Cross-origin trusted scoring signals w/o script allow header.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/'string-value,data-version:3'); + await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + /*additionalInterestGroupOverrides=*/ {}, + CROSS_ORIGIN_TRUSTED_SCORING_SIGNALS_URL, + {permitCrossOriginTrustedSignals: + `"${OTHER_ORIGIN2}", "${window.location.origin}"`}); +}, 'Cross-origin trusted scoring signals with wrong script allow header.'); + +subsetTest(promise_test, async test => { + const uuid = generateUuid(test); + const sellerReportURL = createSellerReportURL(uuid); + const renderURL = createRenderURL(uuid, /*script=*/null, + /*signalsParam=*/`string-value,data-version:3,uuid:${uuid},dispatch:track_get`); + // Use the request tracker for trusted scoring signals, to have it + // record whether they got fetched or not. + const crossOriginRequestTrackerURL = OTHER_ORIGIN1 + BASE_PATH + + 'resources/request-tracker.py'; + let result = await runTrustedScoringSignalsTest( + test, uuid, renderURL, + `trustedScoringSignals === null && + !('dataVersion' in browserSignals) && + crossOriginTrustedScoringSignals === null && + !('crossOriginDataVersion' in browserSignals)`, + /*additionalInterestGroupOverrides=*/ {}, + crossOriginRequestTrackerURL, + {permitCrossOriginTrustedSignals: + `"${OTHER_ORIGIN2}", "${window.location.origin}"`, + reportResult: `sendReportTo("${sellerReportURL}")`}); + createAndNavigateFencedFrame(test, result); + await waitForObservedRequests(uuid, + [createBidderReportURL(uuid), sellerReportURL]); +}, 'Cross-origin trusted scoring signals with wrong script allow header not fetched.'); + +///////////////////////////////////////////////////////////////////////////// // Data-Version tests ///////////////////////////////////////////////////////////////////////////// @@ -658,4 +777,4 @@ subsetTest(promise_test, async test => { ); runBasicFledgeTestExpectingWinner(test, uuid, auctionConfigOverrides); -}, 'Trusted scoring signals splits the request if the combined URL length exceeds the limit of small value.');
\ No newline at end of file +}, 'Trusted scoring signals splits the request if the combined URL length exceeds the limit of small value.'); diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html new file mode 100644 index 00000000000..f98cb61ad32 --- /dev/null +++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-bfcache-restore-iframe.html @@ -0,0 +1,52 @@ +<!DOCTYPE html> +<title>pagereveal event in iframe fires and in correct order on restoration from BFCache</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#updating-the-document"> +<link rel="author" href="mailto:bokan@chromium.org"> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/common/dispatcher/dispatcher.js"></script> +<script src="/html/browsers/browsing-the-web/back-forward-cache/resources/helper.sub.js"></script> +<script> + +// runBfcacheTest opens a popup to pageA which navigates to pageB and then +// back, ensuring pageA is stored in the BFCache. +runBfcacheTest({ + scripts: ['/common/get-host-info.sub.js'], + funcBeforeNavigation: async () => { + // This function executes in pageA + window.message = (data) => { + return new Promise(resolve => { + addEventListener('message', e => { + if (data == undefined || data === e.data) + resolve(e.data); + }); + }); + } + + const frameLoaded = message('loaded'); + const iframe = document.createElement('iframe'); + iframe.src = `${get_host_info().OTHER_ORIGIN}/html/browsers/browsing-the-web/history-traversal/pagereveal/resources/iframe.html?restore`; + document.body.appendChild(iframe); + await frameLoaded; + }, + funcAfterAssertion: async (pageA, pageB, t) => { + let event_log = await pageA.execute_script(async () => { + const event_log = message(); + document.querySelector('iframe').contentWindow.postMessage('getEventLog', '*'); + return await event_log; + }); + + // Expect that the events seen are: + // pageshow.persisted, pagereveal, rAF, rAF, rAF, ... + assert_equals(event_log.slice(0, 3).toString(), + 'pageshow.persisted,pagereveal,rAF'); + for (let i = 3; i < event_log.length; ++i) { + assert_equals(event_log[i], 'rAF', + 'All events following pagereveal should be animation frames'); + } + }, + targetOrigin: originSameOrigin, +}); +</script> diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html new file mode 100644 index 00000000000..b982025bc78 --- /dev/null +++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/order-in-new-document-navigation-iframe.html @@ -0,0 +1,35 @@ +<!DOCTYPE html> +<title>pagereveal event fires and in correct order on new-document navigation in an iframe</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering"> +<link rel="author" href="mailto:bokan@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<script> +function message(data) { + return new Promise(resolve => { + addEventListener('message', e => { + if (data == undefined || data === e.data) + resolve(e.data); + }); + }); +} + +promise_test(async () => { + const frameLoaded = message('loaded'); + const iframe = document.createElement('iframe'); + iframe.src = `${get_host_info().OTHER_ORIGIN}/html/browsers/browsing-the-web/history-traversal/pagereveal/resources/iframe.html`; + document.body.appendChild(iframe); + await frameLoaded; + + const event_log_promise = message(); + iframe.contentWindow.postMessage('getEventLog', '*'); + const event_log = await event_log_promise; + + // Expect that the events seen are: + // pageshow.persisted, pagereveal, rAF, rAF, rAF, ... + assert_equals(event_log.slice(0, 3).toString(),'pageshow,pagereveal,rAF'); +}); +</script> +</body> diff --git a/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/resources/iframe.html b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/resources/iframe.html new file mode 100644 index 00000000000..a1c1c623328 --- /dev/null +++ b/tests/wpt/tests/html/browsers/browsing-the-web/history-traversal/pagereveal/resources/iframe.html @@ -0,0 +1,48 @@ +<!DOCTYPE html> +<!-- Logs rAF, pageshow, and pagereveal events. Load with '?restore' to ignore + events prior to pageshow.persisted --> +<script> +// If the test is checking behavior after a BFCache restore, only record once +// pageshow.persisted has been seen. +const params = new URLSearchParams(window.location.search); +let should_record = !params.has('restore'); + +let event_log = []; + +addEventListener('message', async e => { + if (e.data === 'getEventLog') { + // Ensure at least one animation frame is produced to ensure + // pagereveal must have fired. + await new Promise(requestAnimationFrame); + e.source.postMessage(event_log, '*'); + } +}); + +addEventListener('load', () => { + window.parent.postMessage('loaded', '*'); +}) + +function recordRafs() { + requestAnimationFrame( () => { + if (should_record) + event_log.push('rAF'); + + recordRafs(); + }); +} + +recordRafs(); + +addEventListener('pageshow', (e) => { + if (e.persisted) + should_record = true; + + if (should_record) + event_log.push('pageshow' + (e.persisted ? '.persisted' : '')); +}); + +addEventListener('pagereveal', () => { + if (should_record) + event_log.push('pagereveal'); +}); +</script> diff --git a/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh-expected.html b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh-expected.html new file mode 100644 index 00000000000..d183f6940de --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh-expected.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class="test-wait"> +<title>HTML Canvas reference: SVG filter using CSS font-relative line-height units</title> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +:root { + font: 20px Ahem; +} + +div { + display: inline-block; + width: 100px; + height: 100px; + background: green; +} + +.r { + background: red; +} +</style> +<div><div class="r" style="width: 48px;"></div></div><br> +<div><div class="r" style="width: 24px;"></div></div> diff --git a/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh.html b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh.html new file mode 100644 index 00000000000..b61193fb9fd --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter-lh-rlh.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html class="test-wait"> +<title>HTML Canvas test: SVG filter using CSS font-relative line-height units</title> +<link rel="match" href="svg-filter-lh-rlh-expected.html"/> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +:root { + font: 20px Ahem; +} +</style> +<svg width="0" height="0"> + <!-- https://html.spec.whatwg.org/multipage/canvas.html#working-with-externally-defined-svg-filters --> + <use href="./svg-filter.svg#filter-lh" /> + <use href="./svg-filter.svg#filter-rlh" /> +</svg +><canvas id="canvas-lh" width="100" height="100"></canvas><br +><canvas id="canvas-rlh" width="100" height="100"></canvas> +<script> +function use_filter(canvas, filter_id) { + const ctx = canvas.getContext("2d"); + ctx.font = "40px Ahem"; + ctx.filter = `url(./svg-filter.svg#${filter_id})`; + ctx.fillStyle = "red"; + ctx.fillRect(0, 0, 100, 100); +} +window.addEventListener("load", async () => { + use_filter(document.getElementById("canvas-lh"), "filter-lh"); + use_filter(document.getElementById("canvas-rlh"), "filter-rlh"); + document.documentElement.classList.remove('test-wait'); +}); +</script> +</html> diff --git a/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter.svg b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter.svg new file mode 100644 index 00000000000..a783a3eb15d --- /dev/null +++ b/tests/wpt/tests/html/canvas/element/manual/filters/svg-filter.svg @@ -0,0 +1,10 @@ +<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"> + <filter id="filter-lh"> + <feFlood result="floodFill" x="1lh" y="0" width="100" height="100" flood-color="green" /> + <feBlend in="SourceGraphic" in2="floodFill" mode="color-dodge" /> + </filter> + <filter id="filter-rlh"> + <feFlood result="floodFill" x="1rlh" y="0" width="100" height="100" flood-color="green" /> + <feBlend in="SourceGraphic" in2="floodFill" mode="color-dodge" /> + </filter> +</svg> diff --git a/tests/wpt/tests/html/rendering/widgets/WEB_FEATURES.yml b/tests/wpt/tests/html/rendering/widgets/WEB_FEATURES.yml new file mode 100644 index 00000000000..b4ae339c2f3 --- /dev/null +++ b/tests/wpt/tests/html/rendering/widgets/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: field-sizing + files: + - field-sizing-* diff --git a/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance-ref.html b/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance-ref.html new file mode 100644 index 00000000000..33e0e6ac161 --- /dev/null +++ b/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance-ref.html @@ -0,0 +1,3 @@ +<!doctype html> +<meta charset="utf-8"> +<input type="password" style="appearance: none; background-color: blue"> diff --git a/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance.html b/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance.html new file mode 100644 index 00000000000..3c85b100a1d --- /dev/null +++ b/tests/wpt/tests/html/rendering/widgets/input-password-background-suppresses-appearance.html @@ -0,0 +1,7 @@ +<!doctype html> +<meta charset="utf-8"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1895561"> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="match" href="input-password-background-suppresses-appearance-ref.html"> +<title>backgrounds disable native password input appearance</title> +<input type="password" style="background-color: blue"> diff --git a/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/WEB_FEATURES.yml b/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/WEB_FEATURES.yml new file mode 100644 index 00000000000..457c9040053 --- /dev/null +++ b/tests/wpt/tests/html/semantics/forms/attributes-common-to-form-controls/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: dirname + files: + - dirname-* diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/stylable-select/select-option-hover-styles.tentative.html b/tests/wpt/tests/html/semantics/forms/the-select-element/stylable-select/select-option-hover-styles.tentative.html new file mode 100644 index 00000000000..4361229b8f1 --- /dev/null +++ b/tests/wpt/tests/html/semantics/forms/the-select-element/stylable-select/select-option-hover-styles.tentative.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> + +<style> +#selecteditem { + color: SelectedItemText; + background-color: SelectedItem; +} +</style> +<div id=selecteditem>SelectedItem test colors</div> + +<select style="appearance:base-select"> + <option class=one>one</option> + <option class=two>two</option> + <option class=three disabled>disabled</option> +</select> + +<script> +const select = document.querySelector('select'); +const optionOne = document.querySelector('.one'); +const optionTwo = document.querySelector('.two'); +const disabledOption = document.querySelector('.three'); + +promise_test(async () => { + await new Promise(requestAnimationFrame); + const selectedItemTestElement = document.getElementById('selecteditem'); + const selectedItemTextColor = getComputedStyle(selectedItemTestElement).color; + const selectedItemColor = getComputedStyle(selectedItemTestElement).backgroundColor; + + await test_driver.bless(); + select.showPicker(); + assert_true(select.matches(':open'), + 'dropdown should open after calling showPicker().'); + + await (new test_driver.Actions() + .pointerMove(1, 1, {origin: optionOne})) + .send(); + await new Promise(requestAnimationFrame); + + assert_equals(getComputedStyle(optionOne).color, selectedItemTextColor, + 'The hovered option should have color:SelectedItemText.'); + assert_equals(getComputedStyle(optionOne).backgroundColor, selectedItemColor, + 'The hovered option should have background-color:SelectedItem.'); + // SelectedItemTextColor might be the same as the default text color, so + // don't test that optionTwo's color isn't selectedItemTextColor. + assert_not_equals(getComputedStyle(optionTwo).backgroundColor, selectedItemColor, + 'The not hovered option should not have background-color:SelectedItem.'); + + const disabledColor = getComputedStyle(disabledOption).color; + const disabledBackgroundColor = getComputedStyle(disabledOption).backgroundColor; + + await (new test_driver.Actions() + .pointerMove(1, 1, disabledOption)) + .send(); + await new Promise(requestAnimationFrame); + + assert_equals(getComputedStyle(disabledOption).color, disabledColor, + 'Disabled options should not change color when hovered.'); + assert_equals(getComputedStyle(disabledOption).backgroundColor, disabledBackgroundColor, + 'Disabled options should not change background-color when hovered.'); +}, 'Hover styles should be present for appearance:base-select options.'); +</script> diff --git a/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html new file mode 100644 index 00000000000..6e81a20962c --- /dev/null +++ b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html @@ -0,0 +1,53 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<body> +<!-- The permission element should not be focusable by script. +--> +<permission tabindex="0" id="valid_permission_element" type="geolocation"> + +<span tabindex="0" id="focusable_span">This is some text</span> + +<!-- style needed to allow the invalid element to have a width --> +<permission style="width: auto; padding-left: 10px" tabindex="0" id="invalid_permission_element" type="invalid"> + +<script> + promise_test(async() => { + valid_permission_element.focus(); + assert_equals(document.activeElement, document.body, + "Permission element should not be focused. Instead the parent element gets focus."); + + actions = new test_driver.Actions() + .pointerMove(1, 1, {origin: valid_permission_element}) + .pointerDown() + .addTick(); + await actions.send(); + + assert_equals(document.activeElement, valid_permission_element, + "Users can still focus the element"); + + focusable_span.focus(); + assert_equals(document.activeElement, focusable_span, + "Other element should be focused"); + + invalid_permission_element.focus(); + assert_equals(document.activeElement, focusable_span, + "Invalid permission element should not be focused"); + + actions = new test_driver.Actions() + .pointerMove(1, 1, {origin: invalid_permission_element}) + .pointerDown() + .addTick(); + await actions.send(); + + assert_equals(document.activeElement, document.body, + "Invalid permission element should not be focusable even by user.\ + Instead the parent elements gets focus."); +}, "Permission element is not focusable by script"); +</script> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/html/semantics/popovers/popover-focus-2.html b/tests/wpt/tests/html/semantics/popovers/popover-focus-2.html index 8f24ace9195..552c8d8206b 100644 --- a/tests/wpt/tests/html/semantics/popovers/popover-focus-2.html +++ b/tests/wpt/tests/html/semantics/popovers/popover-focus-2.html @@ -1,6 +1,7 @@ <!DOCTYPE html> <meta charset="utf-8" /> <title>Popover focus behaviors</title> +<meta name="timeout" content="long"> <link rel="author" href="mailto:masonf@chromium.org"> <link rel=help href="https://open-ui.org/components/popover.research.explainer"> <script src="/resources/testharness.js"></script> diff --git a/tests/wpt/tests/html/semantics/selectors/pseudo-classes/WEB_FEATURES.yml b/tests/wpt/tests/html/semantics/selectors/pseudo-classes/WEB_FEATURES.yml index 055a5fb4a30..2877344b649 100644 --- a/tests/wpt/tests/html/semantics/selectors/pseudo-classes/WEB_FEATURES.yml +++ b/tests/wpt/tests/html/semantics/selectors/pseudo-classes/WEB_FEATURES.yml @@ -5,6 +5,10 @@ features: - name: default files: - default.html +- name: indeterminate + files: + - checked-indeterminate.window.js + - indeterminate* - name: read-write-pseudos files: - readwrite-readonly-type-change.html diff --git a/tests/wpt/tests/import-maps/dynamic-integrity.html b/tests/wpt/tests/import-maps/dynamic-integrity.html new file mode 100644 index 00000000000..7a6fed71086 --- /dev/null +++ b/tests/wpt/tests/import-maps/dynamic-integrity.html @@ -0,0 +1,87 @@ +<!DOCTYPE html> +<html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +let log; +</script> +<script type="importmap"> +{ + "imports": { + "./resources/log.js?pipe=sub&name=ResolvesToBadHash": "./resources/log.js?pipe=sub&name=BadHash", + "./resources/log.js?pipe=sub&name=ResolvesToNoHash": "./resources/log.js?pipe=sub&name=NoHash", + "./resources/log.js?pipe=sub&name=GoodHash": "./resources/log.js?pipe=sub&name=GoodHash", + "bare": "./resources/log.js?pipe=sub&name=BareURL", + "bare2": "./resources/log.js?pipe=sub&name=F" + }, + "integrity": { + "./resources/log.js?pipe=sub&name=BadHash": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ResolvesToNoHash": "sha384-foobar", + "./resources/log.js?pipe=sub&name=GoodHash": "sha384-SwfgBqInhSlLziU454cYhGgwPpae+d3VHZcY+vjZIO/gxRGt2u3Jsfyvure/Ww0u", + "./resources/log.js?pipe=sub&name=InvalidExtra": "sha384-WsKk8nzJFPhk/4pWR4LYoPhEu3xaAc6PdIm4vmqoZVWqEgMYmZgOg9XJKxgD1+8v foobar-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", + "./resources/log.js?pipe=sub&name=Suffix": "sha384-lbOWldbmji7sCHI/L8iVJ+elmFIMp41p+aYOLxqQfZMqtoFeHFVe/ASRA0IyZ1/9?foobar", + "./resources/log.js?pipe=sub&name=Multiple": "sha384-foobar sha512-rOJN8igD0+jW6lwNN3+InhXTgQztVHlq/HJ0riswXp8kMoiIDx5JpmCwuVem6Ll9q2LFNSu1xq23bsBMMQk1rg==", + "./resources/log.js?pipe=sub&name=BadHashWithNoImport": "sha384-foobar", + "./resources/log.js?pipe=sub&name=BareURL": "sha384-foobar", + "bare2": "sha384-foobar", + "resources/log.js?pipe=sub&name=Bare": "sha384-foobar" + } +} +</script> +<script type="module"> +const test_not_loaded = (url, description) => { + promise_test(async t => { + log = []; + const promise = import(url); + await promise_rejects_js(t, TypeError, promise); + assert_array_equals(log, []); + }, description); +}; + +const test_loaded = (url, log_expectation, description) => { + promise_test(async t => { + log = []; + await import(url); + assert_array_equals(log, log_expectation); + }, description); +}; + +test_not_loaded("./resources/log.js?pipe=sub&name=ResolvesToBadHash", + 'script was not loaded, as its resolved URL failed its integrity check'); + +test_loaded("./resources/log.js?pipe=sub&name=ResolvesToNoHash", ["log:NoHash"], + 'script was loaded, as its resolved URL had no integrity check, despite' + + ' its specifier having one'); + +test_loaded("./resources/log.js?pipe=sub&name=GoodHash", ["log:GoodHash"], + 'script was loaded, as its integrity check passed'); + +test_not_loaded("./resources/log.js?pipe=sub&name=BadHashWithNoImport", + 'Script with no import definition was not loaded, as it failed its' + + ' integrity check'); + +test_not_loaded("bare", + 'Bare specifier script was not loaded, as it failed its integrity check'); + +test_loaded("bare2", ["log:F"], + 'Bare specifier used for integrity loaded, as its definition should have' + + ' used the URL'); + +test_loaded("./resources/log.js?pipe=sub&name=InvalidExtra", + ["log:InvalidExtra"], + 'script was loaded, as its integrity check passed, despite having an extra' + + ' invalid hash'); + +test_loaded("./resources/log.js?pipe=sub&name=Suffix", ["log:Suffix"], + 'script was loaded, as its integrity check passed, despite having an' + + ' invalid suffix'); + +test_loaded("./resources/log.js?pipe=sub&name=Multiple", ["log:Multiple"], + 'script was loaded, as its integrity check passed given multiple hashes.' + + ' This also makes sure that the larger hash is picked.'); + +test_loaded("./resources/log.js?pipe=sub&name=Bare",["log:Bare"], + 'script was loaded, as its integrity check was ignored, as it was defined' + + ' using a URL that looks like a bare specifier'); +</script> + diff --git a/tests/wpt/tests/import-maps/no-referencing-script-integrity-valid.html b/tests/wpt/tests/import-maps/no-referencing-script-integrity-valid.html new file mode 100644 index 00000000000..2594459fcbf --- /dev/null +++ b/tests/wpt/tests/import-maps/no-referencing-script-integrity-valid.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +let log = []; +</script> +<script type="importmap"> +{ + "integrity": { + "./resources/log.js?pipe=sub&name=NoReferencingScriptValidCheck": "sha384-5eRmXQSBE6H5ENdymdZxcyiIfJL1dxtH8p+hOelZY7Jzk+gt0gYyemrGY0cEaThF" + } +} +</script> +<script> +let promiseResolve; +let promiseReject; +let promise = new Promise((resolve, reject) => { + promiseResolve = resolve; + promiseReject = reject; +}); +</script> +</head> +<body> +<img src="/images/green.png?2" + onload="import('./resources/log.js?pipe=sub&name=NoReferencingScriptValidCheck').then(promiseResolve).catch(promiseReject)"> +<script> +promise_test(async () => { + await promise; + assert_equals(log.length, 1); + assert_equals(log[0], "log:NoReferencingScriptValidCheck"); +}, "Script was loaded as its valid integrity check passed"); +</script> +</body> +</html> + diff --git a/tests/wpt/tests/import-maps/no-referencing-script-integrity.html b/tests/wpt/tests/import-maps/no-referencing-script-integrity.html new file mode 100644 index 00000000000..8025ba3b899 --- /dev/null +++ b/tests/wpt/tests/import-maps/no-referencing-script-integrity.html @@ -0,0 +1,34 @@ +<!DOCTYPE html> +<html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +let log = []; +</script> +<script type="importmap"> +{ + "integrity": { + "./resources/log.js?pipe=sub&name=NoReferencingScriptInvalidCheck": "sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7" + } +} +</script> +<script> +let promiseResolve; +let promiseReject; +let promise = new Promise((resolve, reject) => { + promiseResolve = resolve; + promiseReject = reject; +}); +</script> +</head> +<body> +<img src="/images/green.png" + onload="import('./resources/log.js?pipe=sub&name=NoReferencingScriptInvalidCheck').then(promiseResolve).catch(promiseReject)"> +<script type="module"> +promise_test(async t => { + await promise_rejects_js(t, TypeError, promise); +}, "Script was not loaded as its integrity check failed"); +</script> +</body> +</html> diff --git a/tests/wpt/tests/import-maps/nonimport-integrity.html b/tests/wpt/tests/import-maps/nonimport-integrity.html new file mode 100644 index 00000000000..1157ee64ee7 --- /dev/null +++ b/tests/wpt/tests/import-maps/nonimport-integrity.html @@ -0,0 +1,161 @@ +<!DOCTYPE html> +<html> +<head> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +let log = []; +</script> +<script type="importmap"> +{ + "integrity": { + "./resources/log.js?pipe=sub&name=ModuleNoIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModuleIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModuleEmptyIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModuleBadIntegrityAttribute": "sha384-COhDkp+ybIZ9wz9hUaSJ5NzKcn8wOMZMpsACZfTeEdBRtNcX5yWJnFn+lIK77Tay", + "./resources/log.js?pipe=sub&name=ModulePreloadNoIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModulePreloadIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModulePreloadEmptyIntegrity": "sha384-foobar", + "./resources/log.js?pipe=sub&name=ModulePreloadBadIntegrityAttribute": "sha384-026dlUs9+KSmPb0Uc7oUPOlWBO67o7vSFdfLJZWEVTvKCly5NXO8+CsOXl54ZBqJ", + "./resources/log.js?pipe=sub&name=NonModule": "sha384-foobar", + "/images/green.png": "sha384-foobar" + } +} +</script> +<script type="module"> +promise_test(async t => { + log = []; + const script = document.createElement("script"); + script.type = "module"; + script.src = "./resources/log.js?pipe=sub&name=ModuleNoIntegrity"; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = () => { reject(Error()); }; + }); + document.head.appendChild(script); + await promise_rejects_js(t, Error, promise); +}, "Script was not loaded as its integrity check was not ignored"); + +promise_test(async () => { + log = []; + const script = document.createElement("script"); + script.type = "module"; + script.integrity = "sha384-QtZrhNFOSmHASHnBdmGg+zrVz5hjukCBakaqwT2pcG7w+QTa/niK16csP6kXAeXI"; + script.src = "./resources/log.js?pipe=sub&name=ModuleIntegrity"; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = reject; + }); + document.head.appendChild(script); + await promise; + assert_equals(log.length, 1); + assert_equals(log[0], "log:ModuleIntegrity"); +}, "Script was loaded as its correct integrity attribute was not ignored"); + +promise_test(async () => { + log = []; + const script = document.createElement("script"); + script.type = "module"; + script.integrity = ""; + script.src = "./resources/log.js?pipe=sub&name=ModuleEmptyIntegrity"; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = reject; + }); + document.head.appendChild(script); + await promise; + assert_equals(log.length, 1); + assert_equals(log[0], "log:ModuleEmptyIntegrity"); +}, "Script was loaded as its empty integrity attribute was not ignored"); + +promise_test(async t => { + log = []; + const script = document.createElement("script"); + script.type = "module"; + script.integrity = "sha384-foobar"; + script.src = "./resources/log.js?pipe=sub&name=ModuleBadIntegrityAttribute"; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = () => { reject(Error()); }; + }); + document.head.appendChild(script); + await promise_rejects_js(t, Error, promise); +}, "Script was not loaded as its bad integrity attribute was not overridden"); + +promise_test(async t => { + const link = document.createElement("link"); + link.rel = "modulepreload"; + link.href = "./resources/log.js?pipe=sub&name=ModulePreloadNoIntegrity"; + const promise = new Promise((resolve, reject) => { + link.onload = resolve; + link.onerror = () => { reject(Error()); }; + }); + document.head.appendChild(link); + await promise_rejects_js(t, Error, promise); +}, "Modulepreload was not loaded as its integrity check was not ignored"); + +promise_test(async () => { + const link = document.createElement("link"); + link.rel = "modulepreload"; + link.integrity = "sha384-iDG3WysExtjWvD9QwQrC7nGXRvO0jM+r7Z2cOLMDO2geMlEtmN9j9xfqHfzT45+9"; + link.href = "./resources/log.js?pipe=sub&name=ModulePreloadIntegrity"; + const promise = new Promise((resolve, reject) => { + link.onload = resolve; + link.onerror = reject; + }); + document.head.appendChild(link); + await promise; +}, "Modulepreload was loaded as its correct integrity attribute was not ignored"); + +promise_test(async () => { + const link = document.createElement("link"); + link.rel = "modulepreload"; + link.integrity = ""; + link.href = "./resources/log.js?pipe=sub&name=ModulePreloadEmptyIntegrity"; + const promise = new Promise((resolve, reject) => { + link.onload = resolve; + link.onerror = reject; + }); + document.head.appendChild(link); + await promise; +}, "Modulepreload was loaded as its empty integrity attribute was not ignored"); + +promise_test(async t => { + const link = document.createElement("link"); + link.rel = "modulepreload"; + link.integrity = "sha384-foobar"; + link.href = "./resources/log.js?pipe=sub&name=ModulePreloadBadIntegrityAttribute"; + const promise = new Promise((resolve, reject) => { + link.onload = resolve; + link.onerror = () => { reject(Error()); }; + }); + document.head.appendChild(link); + await promise_rejects_js(t, Error, promise); +}, "Modulepreload was not loaded as its bad integrity attribute was not ignored"); + +promise_test(async () => { + log = []; + const script = document.createElement("script"); + script.src = "./resources/log.js?pipe=sub&name=NonModule"; + const promise = new Promise((resolve, reject) => { + script.onload = resolve; + script.onerror = reject; + }); + document.head.appendChild(script); + await promise; + assert_equals(log.length, 1); + assert_equals(log[0], "log:NonModule"); +}, "Classic script was loaded as its integrity check was ignored"); + +promise_test(async () => { + const img = document.createElement("img"); + const promise = new Promise((resolve, reject) => { + img.onload = resolve; + img.onerror = reject; + }); + img.src = "/images/green.png"; + document.head.appendChild(img); + await promise; +}, "Image was loaded as its integrity check was ignored"); +</script> +</head> diff --git a/tests/wpt/tests/import-maps/static-integrity.html b/tests/wpt/tests/import-maps/static-integrity.html new file mode 100644 index 00000000000..d1d3649339e --- /dev/null +++ b/tests/wpt/tests/import-maps/static-integrity.html @@ -0,0 +1,68 @@ +<!DOCTYPE html> +<html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +let log = []; +</script> +<script type="importmap"> +{ + "imports": { + "./resources/log.js?pipe=sub&name=A": "./resources/log.js?pipe=sub&name=B", + "./resources/log.js?pipe=sub&name=C": "./resources/log.js?pipe=sub&name=D" + }, + "integrity": { + "./resources/log.js?pipe=sub&name=B": "sha384-Li9vy3DqF8tnTXuiaAJuML3ky+er10rcgNR/VqsVpcw+ThHmYcwiB1pbOxEbzJr7", + "./resources/log.js?pipe=sub&name=D": "sha384-rxZqznFuOnvObm6JJKVmwzBXrsRG25IepqKDFHGhtitRu9YPjxPpRPMIu2hzvtxF", + "./resources/log.js?pipe=sub&name=X": "sha384-mCon9M46vUfNK2Wb3yjvBmpBw/3hwB+wMYS8IzDBng+7//R5Qao35E1azo4gFVzx", + "./resources/log.js?pipe=sub&name=Y": "sha384-u0yaFlBF39Au++qcn+MGL/Ml7UmuVfLymNJAz6Yyi4RqyUfWelcuAzVyE8Shs9xn", + "./resources/log.js?pipe=sub&name=Z": "sha384-u0yaFlBF39Au++qcn+MGL/Ml7UmuVfLymNJAz6Yyi4RqyUfWelcuAzVyE8Shs9xn" + } +} +</script> +<script type="module"> +import './resources/log.js?pipe=sub&name=A'; +</script> +<script type="module"> +test(t => { + assert_array_equals(log, []); + }, 'Static script did not load as it failed its integrity check'); +log = []; +</script> +<script type="module"> +import './resources/log.js?pipe=sub&name=C'; +</script> +<script type="module"> +test(t => { + assert_array_equals(log, ["log:D"]); + }, 'Static script loaded as its integrity check passed'); +log = []; +</script> +<script type="module"> +import './resources/log.js?pipe=sub&name=X'; +</script> +<script type="module"> +test(t => { + assert_array_equals(log, []); + }, 'Static script did not load as it failed its integrity check, even' + + ' without an import defined'); +log = []; +</script> +<script type="module"> +import './resources/log.js?pipe=sub&name=Y'; +</script> +<script type="module"> +test(t => { + assert_array_equals(log, ["log:Y"]); + }, 'Static script loaded as its integrity check passed without an import' + + ' defined'); +log = []; +</script> +<script type="module" src="./resources/log.js?pipe=sub&name=Z">; +</script> +<script type="module"> +test(t => { + assert_array_equals(log, []); + }, 'HTML-based module script did not load as its integrity check failed.'); +log = []; +</script> diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/fuzzy-ref-2.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/fuzzy-ref-2.html.ini index cdfd9736c54..e78d0b4315d 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/fuzzy-ref-2.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/fuzzy-ref-2.html.ini @@ -1,4 +1,3 @@ [fuzzy-ref-2.html] fuzzy: - if os == "mac" and product == "chrome": maxDifference=254-255;100-100 maxDifference=255;100-100 diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/reftest_fuzzy_chain_ini.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/reftest_fuzzy_chain_ini.html.ini index d3776e243e4..6c8e46ceafd 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/reftest_fuzzy_chain_ini.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/legacy/reftest_fuzzy_chain_ini.html.ini @@ -1,4 +1,3 @@ [reftest_fuzzy_chain_ini.html] fuzzy: - if os == "mac" and product == "chrome": maxDifference=254-255;100-100 maxDifference=255;100-100 diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_1.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_1.html.ini deleted file mode 100644 index 44f185357bc..00000000000 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_1.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[reftest_fuzzy_1.html] - fuzzy: - if os == "mac" and product == "chrome": fuzzy-ref-1.html:254-255;100 diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_full.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_full.html.ini index d682550d53e..0ea76527da4 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_full.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_full.html.ini @@ -1,6 +1,4 @@ [reftest_fuzzy_ini_full.html] fuzzy: - if os == "mac" and product == "chrome": [maxDifference=1;100-100, - reftest_fuzzy_ini_full.html==fuzzy-ref-1.html:254-255;100] if 1 == 1: [maxDifference=1;100-100, # 'if 1 == 1:' is a workaround for a parser bug reftest_fuzzy_ini_full.html==fuzzy-ref-1.html:255;100] diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_ref_only.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_ref_only.html.ini index 4437fceff89..8e321bdb902 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_ref_only.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_ref_only.html.ini @@ -1,8 +1,5 @@ [reftest_fuzzy_ini_ref_only.html] fuzzy: - if os == "mac" and product == "chrome": [maxDifference=1;100-100, - fuzzy-ref-1.html:maxDifference=254-255;100-100, - reftest_fuzzy==fuzzy-ref-2.html:maxDifference=1;100-100] if 1 == 1: [maxDifference=1;100-100, # 1 == 1 is a workaround for a parser bug. fuzzy-ref-1.html:maxDifference=255;100-100, reftest_fuzzy==fuzzy-ref-2.html:maxDifference=1;100-100] diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_short.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_short.html.ini index 27e3290e6fb..4a3cb610fac 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_short.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/reftest/reftest_fuzzy_ini_short.html.ini @@ -1,4 +1,3 @@ [reftest_fuzzy_ini_short.html] fuzzy: - if os == "mac" and product == "chrome": maxDifference=254-255;100-100 maxDifference=255;100-100 diff --git a/tests/wpt/tests/infrastructure/metadata/infrastructure/testdriver/click_iframe_crossorigin.sub.html.ini b/tests/wpt/tests/infrastructure/metadata/infrastructure/testdriver/click_iframe_crossorigin.sub.html.ini index c0ca25ab657..aa94652ad76 100644 --- a/tests/wpt/tests/infrastructure/metadata/infrastructure/testdriver/click_iframe_crossorigin.sub.html.ini +++ b/tests/wpt/tests/infrastructure/metadata/infrastructure/testdriver/click_iframe_crossorigin.sub.html.ini @@ -2,4 +2,3 @@ [TestDriver click on a document in an iframe] expected: if product == "chrome": [PASS, FAIL] # https://github.com/web-platform-tests/wpt/issues/26295 - if os == "mac" and product == "firefox": [PASS, FAIL] # https://github.com/web-platform-tests/wpt/issues/45987 diff --git a/tests/wpt/tests/largest-contentful-paint/transparent-text-with-shadow.html b/tests/wpt/tests/largest-contentful-paint/transparent-text-with-shadow.html new file mode 100644 index 00000000000..8231ed9ff11 --- /dev/null +++ b/tests/wpt/tests/largest-contentful-paint/transparent-text-with-shadow.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<!-- + Transparent text with shadow decoration should be eligible for LCP. +--> +<style> + .large-transparent { + font-size: 200px; + position: fixed; + top: 0; + left: 0; + padding: 0; + margin: 0; + pointer-events: none; + color: transparent; + z-index: -999; + text-shadow: green 5px 5px; + } +</style> + +<body> + <img src='/images/lcp-133x106.png' id='image' /> + <p id='larger_text' class='large-transparent'>fake LCP</p> + + <script> + const LcpEntryPromise = (entry_id) => { + return new Promise(resolve => { + new PerformanceObserver((entryList, observer) => { + if (entryList.getEntries().filter(e => e.id == entry_id).length > 0) { + resolve(entryList.getEntries()); + observer.disconnect(); + } + }).observe({ type: 'largest-contentful-paint', buffered: true }); + }); + } + + promise_test(async t => { + assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented"); + + lcpEntries = await LcpEntryPromise('larger_text'); + + assert_equals(lcpEntries.length, 1, + "Transparent texts with shadow decoration are should not be excluded from LCP."); + }, "Transparent text with shadow decoration should not be excluded from LCP.") + </script> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/largest-contentful-paint/transparent-text-with-text-stroke.html b/tests/wpt/tests/largest-contentful-paint/transparent-text-with-text-stroke.html new file mode 100644 index 00000000000..2c81ff8aad7 --- /dev/null +++ b/tests/wpt/tests/largest-contentful-paint/transparent-text-with-text-stroke.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<!-- + Transparent text with text stroke decoration should be eligible for LCP. +--> +<style> + .large-transparent { + font-size: 200px; + position: fixed; + top: 0; + left: 0; + padding: 0; + margin: 0; + pointer-events: none; + color: transparent; + z-index: -999; + -webkit-text-stroke: 1px blue; + } +</style> + +<body> + <img src='/images/lcp-133x106.png' id='image' /> + <p id='larger_text' class='large-transparent'>fake LCP</p> + + <script> + const LcpEntryPromise = (entry_id) => { + return new Promise(resolve => { + new PerformanceObserver((entryList, observer) => { + if (entryList.getEntries().filter(e => e.id == entry_id).length > 0) { + resolve(entryList.getEntries()); + observer.disconnect(); + } + }).observe({ type: 'largest-contentful-paint', buffered: true }); + }); + } + + promise_test(async t => { + assert_implements(window.LargestContentfulPaint, "LargestContentfulPaint is not implemented"); + + lcpEntries = await LcpEntryPromise('larger_text'); + + assert_equals(lcpEntries.length, 1, + "Transparent texts with text stroke decoration are should not be excluded from LCP."); + }, "Transparent text with text stroke decoration should not be excluded from LCP.") + </script> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/lint.ignore b/tests/wpt/tests/lint.ignore index 61bca89ddc9..14e02983f75 100644 --- a/tests/wpt/tests/lint.ignore +++ b/tests/wpt/tests/lint.ignore @@ -616,7 +616,6 @@ MISSING DEPENDENCY: resources/chromium/fake-serial.js MISSING DEPENDENCY: resources/chromium/fake-hid.js MISSING DEPENDENCY: resources/chromium/mock-battery-monitor.js MISSING DEPENDENCY: resources/chromium/mock-barcodedetection.js -MISSING DEPENDENCY: resources/chromium/mock-direct-sockets.js MISSING DEPENDENCY: resources/chromium/mock-facedetection.js MISSING DEPENDENCY: resources/chromium/mock-idle-detection.js MISSING DEPENDENCY: resources/chromium/mock-imagecapture.js @@ -700,6 +699,17 @@ TESTHARNESS-IN-OTHER-TYPE: svg/svg-in-svg/svg-in-svg-circular-filter-reference-c # Adding the testharnessreport.js script causes the test to never complete. MISSING-TESTHARNESSREPORT: accessibility/crashtests/computed-node-checked.html +# Existing manual tests with references +REFERENCE-IN-OTHER-TYPE: css/CSS2/backgrounds/background-root-012a.xht +REFERENCE-IN-OTHER-TYPE: css/CSS2/backgrounds/background-root-013a.xht +REFERENCE-IN-OTHER-TYPE: css/CSS2/backgrounds/background-root-014a.xht +REFERENCE-IN-OTHER-TYPE: css/CSS2/cascade/html-precedence-004.xht +REFERENCE-IN-OTHER-TYPE: css/css-flexbox/css-flexbox-height-animation-stretch.html +REFERENCE-IN-OTHER-TYPE: css/css-transforms/css-transform-scale-001-manual.html + +# Needs control of page size +REFERENCE-IN-OTHER-TYPE: css/css-multicol/moz-multicol3-column-balancing-break-inside-avoid-1.html + PRINT STATEMENT: webdriver/tests/bidi/browsing_context/print/* PRINT STATEMENT: webdriver/tests/classic/print/* PRINT STATEMENT: webdriver/tests/support/fixtures_bidi.py @@ -750,6 +760,72 @@ HTML INVALID SYNTAX: mathml/crashtests/mozilla/411603-1.html HTML INVALID SYNTAX: quirks/percentage-height-calculation.html HTML INVALID SYNTAX: trusted-types/TrustedTypePolicyFactory-getAttributeType-namespace.html +# Tests which include testdriver.js but aren't testharness.js tests +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-grid/grid-model/grid-layout-stale-001.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-grid/grid-model/grid-layout-stale-002.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-scroll-anchoring/fullscreen-crash.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-shadow-parts/interaction-with-nested-pseudo-class.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-text-decor/invalidation/text-decoration-thickness.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-view-transitions/hit-test-unpainted-element.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/css-view-transitions/hit-test-unrelated-element.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: css/selectors/remove-hovered-element.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-IndexedDB-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-getUniqueId-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-isSameEntry-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-BroadcastChannel-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-Error-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-MessagePort-frames-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-MessagePort-windows-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-MessagePort-workers-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-frames-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-windows-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-postMessage-workers-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemBaseHandle-remove-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-getDirectoryHandle-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-getFileHandle-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-iteration-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-move-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-partitioned-manual.https.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-removeEntry-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemDirectoryHandle-resolve-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemFileHandle-create-sync-access-handle-manual.https.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemFileHandle-getFile-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemFileHandle-move-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemFileHandle-partitioned-manual.https.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemWritableFileStream-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemWritableFileStream-piped-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/local_FileSystemWritableFileStream-write-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/showDirectoryPicker-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/showOpenFilePicker-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: file-system-access/showSaveFilePicker-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/crashtests/chrome-1312699.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/crashtests/content-visibility-crash.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/rendering/backdrop-iframe.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/rendering/backdrop-inherit.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/rendering/backdrop-object.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: fullscreen/rendering/fullscreen-root-fills-page.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/crashtests/fieldset-middleclick.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/native-popup-with-datalist-ref.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/native-popup-with-datalist.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/select-appearance-custom-button-no-datalist.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-no-datalist.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/select-appearance-writing-mode-vertical-lr.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-select-element/stylable-select/select-appearance-writing-mode-vertical-rl.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/forms/the-selectlist-element/selectlist-option-arbitrary-content-displayed.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/popovers/popover-dialog-crash.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/popovers/popover-hint-crash.tentative.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: html/semantics/popovers/popover-manual-crash.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: infrastructure/testdriver/click_child_crossorigin.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: infrastructure/testdriver/click_child_testdriver.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: mediacapture-streams/MediaStreamTrack-end-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: payment-handler/change-payment-method-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: payment-handler/change-shipping-address-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: payment-handler/change-shipping-option-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: payment-handler/payment-request-event-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: payment-handler/supports-shipping-contact-delegation-manual.https.html +TESTDRIVER-IN-UNSUPPORTED-TYPE: shadow-dom/crashtests/move-to-new-tree-1343016.html + # Pre compressed data using Shared Brotli and Shared Zstandard. TRAILING WHITESPACE, INDENT TABS, CR AT EOL: fetch/compression-dictionary/resources/compressed.br-d.data TRAILING WHITESPACE, INDENT TABS, CR AT EOL: fetch/compression-dictionary/resources/compressed.zstd-d.data diff --git a/tests/wpt/tests/mathml/relations/css-styling/width-height-004.html b/tests/wpt/tests/mathml/relations/css-styling/width-height-004.html index 7133573b04d..10ece249ca0 100644 --- a/tests/wpt/tests/mathml/relations/css-styling/width-height-004.html +++ b/tests/wpt/tests/mathml/relations/css-styling/width-height-004.html @@ -3,7 +3,6 @@ <head> <meta charset="utf-8"> <title>content position with width/height</title> -<link rel="match" href="width-height-003-ref.html"> <link rel="help" href="https://w3c.github.io/mathml-core/#layout-algorithms"> <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> <meta name="assert" content="Verify the inline-start of the children of the munder, mover, munderover and mfrac layout algorithms."/> diff --git a/tests/wpt/tests/mediasession/mediametadata.html b/tests/wpt/tests/mediasession/mediametadata.html index f87e71d9690..d73a4312516 100644 --- a/tests/wpt/tests/mediasession/mediametadata.html +++ b/tests/wpt/tests/mediasession/mediametadata.html @@ -50,8 +50,27 @@ test(function() { test(function() { var image1 = { src: 'http://example.com/1', sizes: 'sizes1', type: 'type1' }; var image2 = { src: 'http://example.com/2', sizes: 'sizes2', type: 'type2' }; + var chapter1_image1 = { src: 'http://chapterexample.com/1', sizes: '128x128', type: 'image/png' }; + var chapter1_image2 = { src: 'http://chapterexample.com/2', sizes: '512x512', type: 'image/png' }; + var chapter2_image1 = { src: 'http://chapterexample.com/3', sizes: '128x128', type: 'image/png' }; + var chapter2_image2 = { src: 'http://chapterexample.com/4', sizes: '512x512', type: 'image/png' }; var metadata = new MediaMetadata({ - title: 'foo', album: 'bar', artist: 'plop', artwork: [ image1, image2 ] + title: 'foo', album: 'bar', artist: 'plop', artwork: [image1, image2], + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [ + chapter1_image1, + chapter1_image2 + ] + }, { + title: 'Chapter 2', + startTime: 16, + artwork: [ + chapter2_image1, + chapter2_image2, + ] + }] }); assert_equals(metadata.title, 'foo'); @@ -64,6 +83,22 @@ test(function() { assert_equals(metadata.artwork[1].src, image2.src); assert_equals(metadata.artwork[1].sizes, image2.sizes); assert_equals(metadata.artwork[1].type, image2.type); + assert_equals(metadata.chapterInfo[0].title, 'Chapter 1'); + assert_equals(metadata.chapterInfo[0].startTime, 0); + assert_equals(metadata.chapterInfo[0].artwork[0].src, chapter1_image1.src); + assert_equals(metadata.chapterInfo[0].artwork[1].src, chapter1_image2.src); + assert_equals(metadata.chapterInfo[0].artwork[0].sizes, chapter1_image1.sizes); + assert_equals(metadata.chapterInfo[0].artwork[1].sizes, chapter1_image2.sizes); + assert_equals(metadata.chapterInfo[0].artwork[0].type, chapter1_image1.type); + assert_equals(metadata.chapterInfo[0].artwork[1].type, chapter1_image2.type); + assert_equals(metadata.chapterInfo[1].title, 'Chapter 2'); + assert_equals(metadata.chapterInfo[1].startTime, 16); + assert_equals(metadata.chapterInfo[1].artwork[0].src, chapter2_image1.src); + assert_equals(metadata.chapterInfo[1].artwork[1].src, chapter2_image2.src); + assert_equals(metadata.chapterInfo[1].artwork[0].sizes, chapter2_image1.sizes); + assert_equals(metadata.chapterInfo[1].artwork[1].sizes, chapter2_image2.sizes); + assert_equals(metadata.chapterInfo[1].artwork[0].type, chapter2_image1.type); + assert_equals(metadata.chapterInfo[1].artwork[1].type, chapter2_image2.type); }, 'Test the different values allowed in MediaMetadata init dictionary'); test(function() { @@ -72,6 +107,7 @@ test(function() { assert_equals(metadata.artist, ''); assert_equals(metadata.album, ''); assert_equals(0, metadata.artwork.length); + assert_equals(0, metadata.chapterInfo.length); }, 'Test the default values for MediaMetadata with empty init dictionary'); test(function() { @@ -80,6 +116,7 @@ test(function() { assert_equals(metadata.artist, ''); assert_equals(metadata.album, ''); assert_equals(0, metadata.artwork.length); + assert_equals(0, metadata.chapterInfo.length); }, 'Test the default values for MediaMetadata with no init dictionary'); test(function() { @@ -90,8 +127,28 @@ test(function() { test(function() { var image1 = { src: 'http://example.com/1', sizes: 'sizes1', type: 'type1' }; var image2 = { src: 'http://example.com/2', sizes: 'sizes2', type: 'type2' }; + var chapter1_image1 = { src: 'http://chapterexample.com/1', sizes: '128x128', type: 'image/png' }; + var chapter1_image2 = { src: 'http://chapterexample.com/2', sizes: '512x512', type: 'image/png' }; + var chapter2_image1 = { src: 'http://chapterexample.com/3', sizes: '128x128', type: 'image/png' }; + var chapter2_image2 = { src: 'http://chapterexample.com/4', sizes: '512x512', type: 'image/png' }; + var metadata = new MediaMetadata({ - title: 'foo', album: 'bar', artist: 'plop', artwork: [ image1, image2 ] + title: 'foo', album: 'bar', artist: 'plop', artwork: [image1, image2], + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [ + chapter1_image1, + chapter1_image2 + ] + }, { + title: 'Chapter 2', + startTime: 16, + artwork: [ + chapter2_image1, + chapter2_image2, + ] + }] }); metadata.title = 'something else'; @@ -109,6 +166,18 @@ test(function() { assert_equals(metadata.artwork[0].src, 'http://example.com/'); assert_equals(metadata.artwork[0].sizes, '40x40'); assert_equals(metadata.artwork[0].type, 'image/png'); + + // The chapterInfo cannot be modified. + var chapter_image = { src: 'http://example.com/', sizes: '40x40', type: 'image/png' }; + var chapter = { + title: 'Chapter 3', + startTime: 22, + artwork: [chapter_image] + }; + metadata.chapterInfo = [chapter]; + assert_equals(metadata.chapterInfo[0].title, 'Chapter 1'); + assert_equals(metadata.chapterInfo[0].startTime, 0); + assert_equals(metadata.chapterInfo.length, 2); }, "Test that MediaMetadata is read/write"); test(function() { @@ -121,7 +190,7 @@ test(function() { metadata.artwork[0].src = 'bar'; assert_equals(metadata.artwork[0].src, 'http://foo.com/'); -}, "Test that MediaMetadat.artwork can't be modified"); +}, "Test that MediaMetadata.artwork can't be modified"); test(function() { var metadata = new MediaMetadata({ artwork: [{ @@ -149,6 +218,34 @@ test(function() { }, "Test that MediaMetadata.artwork is Frozen"); test(function() { + var chapter1_image1 = { src: 'http://chapterexample.com/1', sizes: '128x128', type: 'image/png' }; + var chapter1_image2 = { src: 'http://chapterexample.com/2', sizes: '512x512', type: 'image/png' }; + var chapter2_image1 = { src: 'http://chapterexample.com/3', sizes: '128x128', type: 'image/png' }; + var chapter2_image2 = { src: 'http://chapterexample.com/4', sizes: '512x512', type: 'image/png' }; + var metadata = new MediaMetadata({ + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [ + chapter1_image1, + chapter1_image2 + ] + }, { + title: 'Chapter 2', + startTime: 16, + artwork: [ + chapter2_image1, + chapter2_image2, + ] + }] + }); + + assert_true(Object.isFrozen(metadata.chapterInfo)); + for (var i = 0; i < metadata.chapterInfo.length; ++i) + assert_true(Object.isFrozen(metadata.chapterInfo[i])); +}, "Test that MediaMetadata.chapterInfo is Frozen"); + +test(function() { var metadata = new MediaMetadata({ artwork: [ { src: 'http://example.com', sizes: '40x40', type: 'image/png' }, { src: '../foo', sizes: '40x40', type: 'image/png' }, @@ -161,6 +258,39 @@ test(function() { }, "Test that MediaMetadata.artwork returns parsed urls"); test(function() { + var chapter1_image1 = { src: 'http://chapterexample.com/1', sizes: '128x128', type: 'image/png' }; + var chapter1_image2 = { src: 'http://chapterexample.com/2', sizes: '512x512', type: 'image/png' }; + var chapter2_image1 = { src: 'http://chapterexample.com/3', sizes: '128x128', type: 'image/png' }; + var chapter2_image2 = { src: 'http://chapterexample.com/4', sizes: '512x512', type: 'image/png' }; + var metadata = new MediaMetadata({ + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [ + chapter1_image1, + chapter1_image2 + ] + }, { + title: 'Chapter 2', + startTime: 16, + artwork: [ + chapter2_image1, + chapter2_image2, + ] + }] + }); + + assert_equals(metadata.chapterInfo[0].artwork[0].src, + new URL('http://chapterexample.com/1', document.URL).href) + assert_equals(metadata.chapterInfo[0].artwork[1].src, + new URL('http://chapterexample.com/2', document.URL).href) + assert_equals(metadata.chapterInfo[1].artwork[0].src, + new URL('http://chapterexample.com/3', document.URL).href) + assert_equals(metadata.chapterInfo[1].artwork[1].src, + new URL('http://chapterexample.com/4', document.URL).href) +}, "Test that MediaMetadata.chapterInfo's artwork returns parsed urls"); + +test(function() { var metadata = 42; assert_throws_js(TypeError, _ => { @@ -180,6 +310,22 @@ test(function() { }); assert_equals(metadata.artwork.length, 0); + assert_throws_js(TypeError, _ => { + metadata + new MediaMetadata({ + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [ + // Valid url. + { src: 'http://example.com' }, + // Invalid url. + { src: 'http://example.com:demo' }, + ] + }] + }); + }); + assert_equals(metadata.chapterInfo.length, 0); }, "Test that MediaMetadata throws when setting an invalid url"); test(function() { @@ -190,13 +336,24 @@ test(function() { test(function() { assert_throws_js(TypeError, _ => { - new MediaMetadata({ artwork: [ {} ] }); + new MediaMetadata({ artwork: [ {} ] }) }); var metadata = new MediaMetadata(); assert_throws_js(TypeError, _ => { metadata.artwork = [ { type: 'image/png', sizes: '40x40' } ]; }); + + assert_throws_js(TypeError, _ => { + metadata + new MediaMetadata({ + chapterInfo: [{ + title: 'Chapter 1', + startTime: 0, + artwork: [{ type: 'image/png', sizes: '40x40' }] + }] + }); + }); }, "Test that MediaImage.src is required") promise_test(async t => { diff --git a/tests/wpt/tests/navigation-api/navigate-event/event-constructor.html b/tests/wpt/tests/navigation-api/navigate-event/event-constructor.html index 863681ced73..89ac934020e 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/event-constructor.html +++ b/tests/wpt/tests/navigation-api/navigate-event/event-constructor.html @@ -78,7 +78,8 @@ async_test(t => { assert_equals(event.downloadRequest, downloadRequest); assert_equals(event.info, info); assert_equals(event.hasUAVisualTransition, hasUAVisualTransition); - assert_equals(event.sourceElement, sourceElement); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(event.sourceElement, sourceElement); }); history.pushState(2, null, "#2"); }, "all properties are reflected back"); @@ -98,7 +99,8 @@ async_test(t => { assert_equals(event.formData, null); assert_equals(event.downloadRequest, null); assert_equals(event.info, undefined); - assert_equals(event.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(event.sourceElement, null); }); history.pushState(3, null, "#3"); }, "defaults are as expected"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-cross-origin.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-cross-origin.html index 62e5adb20ae..a69b78196ff 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-cross-origin.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-cross-origin.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); }); a.click(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download-userInitiated.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download-userInitiated.html index 69181425292..17109a2ae82 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download-userInitiated.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download-userInitiated.html @@ -21,7 +21,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download.html index d04245ec253..fbeeb69b956 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-download.html @@ -25,7 +25,8 @@ for (const [tag, download_attr] of tests) { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, a); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, a); e.preventDefault(); }); a.click(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-fragment.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-fragment.html index 6443ccecd1d..69400c3d2f3 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-fragment.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-fragment.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-same-origin-cross-document.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-same-origin-cross-document.html index 5a6dce7ec8b..084993540a1 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-same-origin-cross-document.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-same-origin-cross-document.html @@ -18,7 +18,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); }); a.click(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-userInitiated.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-userInitiated.html index bb76e7a3fbe..686d7ad6ee3 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-userInitiated.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-userInitiated.html @@ -20,7 +20,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-with-target.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-with-target.html index e4b897d82f3..de74239b3be 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-with-target.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-anchor-with-target.html @@ -20,10 +20,11 @@ async_test(t => { assert_equals(new URL(e.destination.url).pathname, "/navigation-api/navigate-event/foo.html"); assert_false(e.destination.sameDocument); - assert_equals(e.destination.key, ""); - assert_equals(e.destination.id, ""); + assert_equals(e.destination.key, ""); + assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); }); a.click(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-back-forward.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-back-forward.html index 869fc164815..b206981821b 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-back-forward.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-back-forward.html @@ -19,7 +19,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); navigation.back(); }), 0); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-navigate.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-navigate.html index d19a1685145..1e622f99117 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-navigate.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-navigate.html @@ -16,7 +16,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); navigation.navigate("#foo", { state: navState }); }, 0); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-reload.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-reload.html index ac6528ce7ef..be33b8120da 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-reload.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-destination-getState-reload.html @@ -16,7 +16,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.intercept(); }); navigation.updateCurrentEntry({ state: navState }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-get.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-get.html index 7a71a1c3050..59661a1caf7 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-get.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-get.html @@ -21,7 +21,8 @@ async_test(t => { // Because it's a GET, not a POST assert_equals(e.formData, null); - assert_equals(e.sourceElement, form); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, form); }); window.onload = t.step_func(() => form.submit()); }, "<form> submission with GET method fires navigate event but with formData null"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-reload.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-reload.html index 21716905372..cdd3ade4ff2 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-reload.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-reload.html @@ -12,7 +12,8 @@ async_test(t => { iframe.contentWindow.navigation.onnavigate = t.step_func(e => { assert_equals(e.navigationType, "push"); assert_not_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); iframe.onload = t.step_func(() => { iframe.contentWindow.navigation.onnavigate = t.step_func_done(e => { diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-traverse.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-traverse.html index b9665c80566..72b8dc36acb 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-traverse.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-traverse.html @@ -12,7 +12,8 @@ async_test(t => { iframe.contentWindow.navigation.onnavigate = t.step_func(e => { assert_equals(e.navigationType, "push"); assert_not_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); iframe.onload = t.step_func(() => { // Avoid the replace behavior that occurs if you navigate during the load handler diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-userInitiated.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-userInitiated.html index 246e028a0db..079f546771f 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-userInitiated.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-userInitiated.html @@ -24,7 +24,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_not_equals(e.formData, null); - assert_equals(e.sourceElement, submit); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, submit); }); window.onload = t.step_func(() => test_driver.click(submit)); }, "<form> submission fires navigate event"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-with-target.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-with-target.html index 4b1a8ce9d3a..07418366a76 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form-with-target.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form-with-target.html @@ -22,7 +22,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_not_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); form.submit(); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-form.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-form.html index 653ef3b8eba..8cea889bec1 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-form.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-form.html @@ -19,7 +19,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_not_equals(e.formData, null); - assert_equals(e.sourceElement, form); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, form); }); window.onload = t.step_func(() => form.submit()); }, "<form> submission fires navigate event"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-fragment.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-fragment.html index 9da4ddcd507..4529fe25ac3 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-fragment.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-fragment.html @@ -24,7 +24,8 @@ async_test(t => { assert_equals(e.destination.id, target_id); assert_equals(e.destination.index, start_index); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); history.back(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-pushState.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-pushState.html index fdee41a3121..06c3b89bbcf 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-pushState.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-after-pushState.html @@ -24,7 +24,8 @@ async_test(t => { assert_equals(e.destination.id, target_id); assert_equals(e.destination.index, start_index); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); history.back(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-cross-document.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-cross-document.html index 29c626a5221..a34b20a5e53 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-cross-document.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-back-cross-document.html @@ -23,7 +23,8 @@ async_test(t => { assert_equals(e.destination.index, 0); assert_equals(e.formData, null); assert_equals(e.info, undefined); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); assert_true(i.contentWindow.navigation.canGoBack); i.contentWindow.history.back(); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-go-0.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-go-0.html index 5508928e198..cd716bfafb1 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-go-0.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-go-0.html @@ -18,7 +18,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-pushState.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-pushState.html index 5079b210781..f89288b6edf 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-pushState.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-pushState.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); t.step_timeout(t.step_func_done(() => { assert_equals(location.hash, ""); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-replaceState.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-replaceState.html index 444116a6324..d18feb2bc1d 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-history-replaceState.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-history-replaceState.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); t.step_timeout(t.step_func_done(() => { assert_equals(location.hash, ""); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-iframe-location.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-iframe-location.html index 1bd79188231..c00a6e010db 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-iframe-location.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-iframe-location.html @@ -21,7 +21,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-location.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-location.html index a0ed4dc0aac..b1ce204a626 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-location.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-location.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); location.href = "#1"; }, "location API fires navigate event"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-meta-refresh.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-meta-refresh.html index d4d5b1c8e13..f64484c3055 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-meta-refresh.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-meta-refresh.html @@ -20,7 +20,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); }); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-cross-document.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-cross-document.html index 084051539b8..de87fbbb800 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-cross-document.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-cross-document.html @@ -25,7 +25,8 @@ async_test(t => { assert_equals(e.destination.index, 0); assert_equals(e.formData, null); assert_equals(e.info, "hi"); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); i.contentWindow.onbeforeunload = () => beforeunload_called = true; assert_true(i.contentWindow.navigation.canGoBack); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document-in-iframe.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document-in-iframe.html index 42c694e2905..3d810d2f1de 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document-in-iframe.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document-in-iframe.html @@ -27,7 +27,8 @@ promise_test(async t => { assert_equals(e.destination.index, 0); assert_equals(e.formData, null); assert_equals(e.info, "hi"); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); } await i.contentWindow.navigation.back({ info: "hi" }).finished; }, "navigate event for navigation.back() - same-document in an iframe"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document.html index b08bbfcbf11..0f2faff7d7b 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-back-same-document.html @@ -25,7 +25,8 @@ async_test(t => { assert_equals(e.formData, null); assert_equals(e.info, "hi"); assert_not_equals(e.hasUAVisualTransition, undefined); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); assert_true(navigation.canGoBack); navigation.back({ info: "hi" }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-navigate.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-navigate.html index c56af1b40df..5dd1892cc00 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-navigate.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-navigation-navigate.html @@ -16,7 +16,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); }); navigation.navigate("#foo"); }, "navigate event for navigation.navigate()"); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-svg-anchor-fragment.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-svg-anchor-fragment.html index c6d210cccb1..647496fd5c6 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-svg-anchor-fragment.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-svg-anchor-fragment.html @@ -17,7 +17,8 @@ async_test(t => { assert_equals(e.destination.key, ""); assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); - assert_equals(e.sourceElement, document.getElementById("a")); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, document.getElementById("a")); e.preventDefault(); t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0); }); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-to-srcdoc.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-to-srcdoc.html index ea5c3f92168..bb598d8b902 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-to-srcdoc.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-to-srcdoc.html @@ -21,7 +21,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); // Make sure it doesn't navigate anyway. diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open-self.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open-self.html index 4e569b6d548..1ef65ed82ba 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open-self.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open-self.html @@ -16,7 +16,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); }); window.onload = t.step_func(() => window.open("#1", "_self")); diff --git a/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open.html b/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open.html index 42828308d77..13cdefb5d3b 100644 --- a/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open.html +++ b/tests/wpt/tests/navigation-api/navigate-event/navigate-window-open.html @@ -21,7 +21,8 @@ async_test(t => { assert_equals(e.destination.id, ""); assert_equals(e.destination.index, -1); assert_equals(e.formData, null); - assert_equals(e.sourceElement, null); + // NavigateEvent sourceElement is still in development, so test whether it is available. + if ("sourceElement" in e) assert_equals(e.sourceElement, null); e.preventDefault(); }); diff --git a/tests/wpt/tests/pointerevents/deviceproperties/pointer-event-has-device-properties-uniqueid-from-pointer-event-init.tentative.html b/tests/wpt/tests/pointerevents/deviceproperties/pointer-event-has-device-properties-uniqueid-from-pointer-event-init.tentative.html index a37df4b4214..33b2354ec63 100644 --- a/tests/wpt/tests/pointerevents/deviceproperties/pointer-event-has-device-properties-uniqueid-from-pointer-event-init.tentative.html +++ b/tests/wpt/tests/pointerevents/deviceproperties/pointer-event-has-device-properties-uniqueid-from-pointer-event-init.tentative.html @@ -87,6 +87,6 @@ height: 100, isPrimary: true, }); - CheckDeviceId(downEventEmptyProps, INVALID_UNIQUE_ID); + assert_equals(downEventEmptyProps.deviceProperties, null); }, 'No deviceProperties in PointerEventInit'); </script>
\ No newline at end of file diff --git a/tests/wpt/tests/preload/WEB_FEATURES.yml b/tests/wpt/tests/preload/WEB_FEATURES.yml new file mode 100644 index 00000000000..384fd1a3e54 --- /dev/null +++ b/tests/wpt/tests/preload/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: modulepreload + files: + - "*modulepreload*" diff --git a/tests/wpt/tests/private-aggregation/shared-storage-surface-filtering-id.https.html b/tests/wpt/tests/private-aggregation/shared-storage-surface-filtering-id.https.html new file mode 100644 index 00000000000..53ed3a109bc --- /dev/null +++ b/tests/wpt/tests/private-aggregation/shared-storage-surface-filtering-id.https.html @@ -0,0 +1,97 @@ +<!doctype html> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<script src="/shared-storage/resources/util.js"></script> +<script src="/private-aggregation/resources/util.js"></script> +<script src="/fenced-frame/resources/utils.js"></script> + +<body> +<script> +'use strict'; + +promise_test(async () => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = {}; + + await sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true}); +}, 'no filtering ID max bytes'); + +promise_test(async () => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: 1, + }; + + await sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true}); +}, 'explicit default filtering ID max bytes'); + +promise_test(async () => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: 8, + }; + + await sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true}); +}, 'max filtering ID max bytes'); + +promise_test(async (test) => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: 9, + }; + + return promise_rejects_dom( + test, "DataError", + sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true})); +}, 'too big filtering ID max bytes'); + +promise_test(async (test) => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: 0, + }; + + return promise_rejects_dom( + test, "DataError", + sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true})); +}, 'zero filtering ID max bytes'); + +promise_test(async (test) => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: -1, + }; + + return promise_rejects_js( + test, TypeError, + sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true})); +}, 'negative filtering ID max bytes'); + +promise_test(async (test) => { + await addModuleOnce("/private-aggregation/resources/private-aggregation-helper-module.js"); + + const privateAggregationConfig = { + filteringIdMaxBytes: 3n, + }; + + return promise_rejects_js( + test, TypeError, + sharedStorage.run("contribute-to-histogram", + {privateAggregationConfig, keepAlive: true})); +}, 'wrong type filtering ID byte size'); + +</script> +</body> diff --git a/tests/wpt/tests/resources/chromium/mock-direct-sockets.js b/tests/wpt/tests/resources/chromium/mock-direct-sockets.js deleted file mode 100644 index 6d557f7a015..00000000000 --- a/tests/wpt/tests/resources/chromium/mock-direct-sockets.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -import {DirectSocketsService, DirectSocketsServiceReceiver} from '/gen/third_party/blink/public/mojom/direct_sockets/direct_sockets.mojom.m.js'; - -self.DirectSocketsServiceTest = (() => { - // Class that mocks DirectSocketsService interface defined in - // https://source.chromium.org/chromium/chromium/src/third_party/blink/public/mojom/direct_sockets/direct_sockets.mojom - class MockDirectSocketsService { - constructor() { - this.interceptor_ = new MojoInterfaceInterceptor(DirectSocketsService.$interfaceName); - this.receiver_ = new DirectSocketsServiceReceiver(this); - this.interceptor_.oninterfacerequest = e => - this.receiver_.$.bindHandle(e.handle); - this.interceptor_.start(); - } - - reset() { - this.receiver_.$.close(); - this.interceptor_.stop(); - } - - openTCPSocket( - options, - receiver, - observer) { - return Promise.resolve({ - // return result = net:Error::NOT_IMPLEMENTED (code -11) - result: -11 - }); - } - - openConnectedUDPSocket( - options, - receiver, - listener) { - return Promise.resolve({ - // return result = net:Error::NOT_IMPLEMENTED (code -11) - result: -11 - }); - } - - openBoundUDPSocket( - options, - receiver, - listener) { - return Promise.resolve({ - // return result = net:Error::NOT_IMPLEMENTED (code -11) - result: -11 - }); - } - - openTCPServerSocket( - options, - receiver) { - return Promise.resolve({ - // return result = net:Error::NOT_IMPLEMENTED (code -11) - result: -11 - }); - } - } - - let testInternal = { - initialized: false, - mockDirectSocketsService: null - } - - class DirectSocketsServiceTestChromium { - constructor() { - Object.freeze(this); // Make it immutable. - } - - initialize() { - if (!testInternal.initialized) { - testInternal = { - mockDirectSocketsService: new MockDirectSocketsService(), - initialized: true - }; - } - } - - async reset() { - if (testInternal.initialized) { - testInternal.mockDirectSocketsService.reset(); - testInternal = { - mockDirectSocketsService: null, - initialized: false - }; - await new Promise(resolve => setTimeout(resolve, 0)); - } - } - } - - return DirectSocketsServiceTestChromium; -})(); diff --git a/tests/wpt/tests/scroll-to-text-fragment/percent-encoding.html b/tests/wpt/tests/scroll-to-text-fragment/percent-encoding.html index 1f1794bdae0..be688eabfc6 100644 --- a/tests/wpt/tests/scroll-to-text-fragment/percent-encoding.html +++ b/tests/wpt/tests/scroll-to-text-fragment/percent-encoding.html @@ -35,17 +35,17 @@ let test_cases = [ }, { fragment: '#:~:text=%', - expect: 'noscroll', + expect: 'singlepercent', description: 'Percent char without hex digits is invalid.' }, { fragment: '#:~:text=%%', - expect: 'noscroll', + expect: 'doublepercent', description: 'Percent char followed by percent char is invalid.' }, { fragment: '#:~:text=%F', - expect: 'noscroll', + expect: 'percentf', description: 'Single digit percent-encoding is invalid.' }, { @@ -65,21 +65,23 @@ let test_cases = [ }, ]; -for (const test_case of test_cases) { - promise_test(t => new Promise(resolve => { - // Clear the fragment and reset the scroll offset to prepare for the next - // test case. - location = `${location.pathname}#`; - scrollTo(0, 0); +function runTests() { + for (const test_case of test_cases) { + promise_test(t => new Promise(resolve => { + // Clear the fragment and reset the scroll offset to prepare for the next + // test case. + location = `${location.pathname}#`; + scrollTo(0, 0); - location = `${location.pathname}${test_case.fragment}`; - requestAnimationFrame( () => requestAnimationFrame(resolve) ); - }).then(() => { - assert_equals(determineResult(), test_case.expect); - }), `Test navigation with fragment: ${test_case.description}.`); + location = `${location.pathname}${test_case.fragment}`; + requestAnimationFrame( () => requestAnimationFrame(resolve) ); + }).then(() => { + assert_equals(determineResult(), test_case.expect); + }), `Test navigation with fragment: ${test_case.description}.`); + } } </script> - +<body onload="runTests()"> <p class="target" id="singlepercent"> % </p> @@ -100,3 +102,4 @@ for (const test_case of test_cases) { Hello world </p> +</body>
\ No newline at end of file diff --git a/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js b/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js new file mode 100644 index 00000000000..525bc96e763 --- /dev/null +++ b/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event-worker.js @@ -0,0 +1,2 @@ +self.onmessageerror = e => { e.source.postMessage("received error event"); }; +self.onmessage = e => { e.source.postMessage("received message event"); }; diff --git a/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html b/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html new file mode 100644 index 00000000000..fc8edb4b896 --- /dev/null +++ b/tests/wpt/tests/service-workers/service-worker/ServiceWorkerGlobalScope/error-message-event.https.html @@ -0,0 +1,47 @@ +<!DOCTYPE html> +<html> +<head> +<title>Service Worker GlobalScope onerror event</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + <script src="/common/get-host-info.sub.js"></script> +</head> +<body> +<canvas id=canvas></canvas> +<script> +var scope = "resources"; +var registration; +var frame; + +var url1 = "/WebKit/service-workers/resources/response-full-of-headers.py"; +var url2 = get_host_info().HTTPS_REMOTE_ORIGIN + url1; + +async function registerServiceWorker(scope) +{ + const registration = await navigator.serviceWorker.register("error-message-event-worker.js", { scope : scope }); + let activeWorker = registration.active; + if (activeWorker) + return registration; + activeWorker = registration.installing; + return new Promise(resolve => { + activeWorker.addEventListener('statechange', () => { + if (activeWorker.state === "activated") + resolve(registration); + }); + }); +} + +promise_test(async (test) => { + registration = await registerServiceWorker(scope); + + const stream = canvas.captureStream(); + const track = stream.getVideoTracks()[0]; + // MediaStreamTrack is not defined in service worker contexts. + registration.active.postMessage({ track }, [track]); + + const result = await new Promise(resolve => navigator.serviceWorker.onmessage = e => resolve(e.data)); + assert_equals(result, "received error event"); +}, "Verify error event is received"); +</script> +</body> +</html> diff --git a/tests/wpt/tests/service-workers/service-worker/WEB_FEATURES.yml b/tests/wpt/tests/service-workers/service-worker/WEB_FEATURES.yml new file mode 100644 index 00000000000..9ddc5b400dc --- /dev/null +++ b/tests/wpt/tests/service-workers/service-worker/WEB_FEATURES.yml @@ -0,0 +1,5 @@ +features: +- name: js-modules-service-workers + files: + - registration-script-module.https.html + - update-registration-with-type.https.html diff --git a/tests/wpt/tests/service-workers/service-worker/fetch-request-resources.https.html b/tests/wpt/tests/service-workers/service-worker/fetch-request-resources.https.html index b4680c3ccd5..9524e6d4749 100644 --- a/tests/wpt/tests/service-workers/service-worker/fetch-request-resources.https.html +++ b/tests/wpt/tests/service-workers/service-worker/fetch-request-resources.https.html @@ -90,7 +90,67 @@ function script_integrity_test(frame, url, integrity, expected_integrity) { destination: 'script', message: `Script load (url:${actual_url})` }; - frame.contentWindow.load_script_with_integrity(actual_url, integrity); + frame.contentWindow.load_script_with_integrity(actual_url, integrity, /*type=*/null); + return add_promise_to_test(actual_url); +} + +function module_script_integrity_test(frame, url, integrity, expected_integrity) { + const actual_url = url + "_module"; + expected_results[actual_url] = { + url: actual_url, + mode: 'cors', + credentials: 'same-origin', + redirect: 'follow', + integrity: expected_integrity, + destination: 'script', + message: `Module Script load (url:${actual_url})` + }; + frame.contentWindow.load_script_with_integrity(actual_url, integrity, "module"); + return add_promise_to_test(actual_url); +} + +function modulepreload_integrity_test(frame, url, integrity, expected_integrity) { + const actual_url = url + "_modulepreload"; + expected_results[actual_url] = { + url: actual_url, + mode: 'cors', + credentials: 'same-origin', + redirect: 'follow', + integrity: expected_integrity, + destination: 'script', + message: `Module Script load (url:${actual_url})` + }; + frame.contentWindow.load_modulepreload_with_integrity(actual_url, integrity); + return add_promise_to_test(actual_url); +} + +function import_module_integrity_test(frame, url, expected_integrity) { + const actual_url = url + "_moduleimport"; + expected_results[actual_url] = { + url: actual_url, + mode: 'cors', + credentials: 'same-origin', + redirect: 'follow', + integrity: expected_integrity, + destination: 'script', + message: `Module Script load (url:${actual_url})` + }; + frame.contentWindow.import_modulescript(actual_url); + return add_promise_to_test(actual_url); +} + +function import_dynamic_module_integrity_test(frame, url, expected_integrity) { + const actual_url = url + "_moduleimportdynamic"; + expected_results[actual_url] = { + url: actual_url, + mode: 'cors', + credentials: 'same-origin', + redirect: 'follow', + integrity: expected_integrity, + destination: 'script', + message: `Module Script load (url:${actual_url})` + }; + frame.contentWindow.import_dynamic_modulescript(actual_url); return add_promise_to_test(actual_url); } @@ -253,6 +313,19 @@ promise_test(async t => { 'sha256-foo sha384-abc '); await script_integrity_test(f, LOCAL_URL, 'sha256-foo sha256-abc', 'sha256-foo sha256-abc'); + await module_script_integrity_test(f, LOCAL_URL, + null, + 'sha384-foobar'); + + await modulepreload_integrity_test(f, LOCAL_URL, + null, + 'sha384-foobar'); + + await import_module_integrity_test(f, LOCAL_URL, + 'sha384-foobar'); + + await import_dynamic_module_integrity_test(f, LOCAL_URL, + 'sha384-foobar'); await css_integrity_test(f, LOCAL_URL, ' ', ' '); await css_integrity_test( diff --git a/tests/wpt/tests/service-workers/service-worker/navigation-timing-sizes.https.html b/tests/wpt/tests/service-workers/service-worker/navigation-timing-sizes.https.html index a960cd57f3c..e726a31f170 100644 --- a/tests/wpt/tests/service-workers/service-worker/navigation-timing-sizes.https.html +++ b/tests/wpt/tests/service-workers/service-worker/navigation-timing-sizes.https.html @@ -43,6 +43,39 @@ promise_test(async t => { var script = 'resources/pass-through-worker.js'; + var scope = 'resources/simple.txt'; + + const registration = await service_worker_unregister_and_register(t, script, scope); + t.add_cleanup(() => registration.unregister()); + await wait_for_state(t, registration.installing, 'activated'); + + const iframe = await with_iframe(scope); + + // Sanity, to check that we actually loaded the text file. + assert_equals(iframe.contentWindow.document.body.textContent, "a simple text file\n"); + t.add_cleanup(() => iframe.remove()); + const navigationEntry = iframe.contentWindow.performance.getEntriesByType("navigation")[0]; + + const main_page_resource_timing = performance.getEntriesByType("resource").filter( + e => e.name.includes('blank'))[0]; + + assert_greater_than(navigationEntry.encodedBodySize, 0, + 'Navigation timing should have encodedBodySize larger than 0.'); + + assert_equals(navigationEntry.decodedBodySize, navigationEntry.encodedBodySize, + 'Navigation timing\'s decodedBodySize and encodedBodySize should be equal.'); + + assert_greater_than(main_page_resource_timing.encodedBodySize, 0, + 'Corresponding resource timing emitted on parent page should have decodedBodySize larger than 0.'); + + assert_equals(main_page_resource_timing.encodedBodySize, main_page_resource_timing.decodedBodySize, + 'Corresponding resource timing emitted on parent page should have equal\ + decodedBodySize and encodedBodySize.'); + + }, 'Body sizes in a pass-through with non html content'); + + promise_test(async t => { + var script = 'resources/pass-through-worker.js'; var scope = 'resources/blank.html'; const registration = await service_worker_unregister_and_register(t, script, scope); diff --git a/tests/wpt/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html b/tests/wpt/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html index 86e9f4bb359..37fc491134d 100644 --- a/tests/wpt/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html +++ b/tests/wpt/tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html @@ -1,5 +1,15 @@ <script src="test-helpers.sub.js?pipe=sub"></script> <body> +<script type="importmap"> +{ + "integrity": { + "./sample?test_module": "sha384-foobar", + "./sample?test_modulepreload": "sha384-foobar", + "./sample?test_moduleimport": "sha384-foobar", + "./sample?test_moduleimportdynamic": "sha384-foobar" + } +} +</script> <script> function load_image(url, cross_origin) { @@ -50,13 +60,42 @@ function load_css_image_set(url, type) { } } -function load_script_with_integrity(url, integrity) { +function load_script_with_integrity(url, integrity, type) { const script = document.createElement('script'); + if (type) { + script.type = type; + } script.src = url; - script.integrity = integrity; + if (integrity) { + script.integrity = integrity; + } document.body.appendChild(script); } +function import_modulescript(url) { + const script = document.createElement('script'); + script.type = "module"; + script.innerHTML = `import "${url}";`; + document.body.appendChild(script); +} + +function import_dynamic_modulescript(url) { + const script = document.createElement('script'); + script.type = "module"; + script.innerHTML = `import("${url}");`; + document.body.appendChild(script); +} + +function load_modulepreload_with_integrity(url, integrity) { + const link = document.createElement('link'); + link.href = url; + if (integrity) { + link.integrity = integrity; + } + link.rel = "modulepreload"; + document.body.appendChild(link); +} + function load_css_with_integrity(url, integrity) { const link = document.createElement('link'); link.rel = 'stylesheet' diff --git a/tests/wpt/tests/shadow-dom/Document-caretPositionFromPoint.tentative.html b/tests/wpt/tests/shadow-dom/Document-caretPositionFromPoint.tentative.html new file mode 100644 index 00000000000..2b97546d2e2 --- /dev/null +++ b/tests/wpt/tests/shadow-dom/Document-caretPositionFromPoint.tentative.html @@ -0,0 +1,216 @@ +<!DOCTYPE html> +<html> +<body> +<meta name="author" title="Siye Liu" href="mailto:siliu@microsoft.com"> +<meta name="assert" content="Document's caretPositionFromPoint should return a CaretPosition inside Shadow Root which is provided as argument."> +<link rel="help" href="https://www.w3.org/TR/cssom-view-1/#dom-document-caretpositionfrompoint"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="container"></div> +<script> + +test(() => { + assert_throws_js(TypeError, () => { document.caretPositionFromPoint(5, 5, "foo"); }); + assert_throws_js(TypeError, () => { document.caretPositionFromPoint(5, 5, 6); }); + }, "document.caretPositionFromPoint() throws when called without the correct parameters"); + +test(() => { + container.setHTMLUnsafe(`<span>hello, world</span>`); + const rect = container.firstChild.getBoundingClientRect(); + const characterWidth = rect.width / container.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `he|llo, world`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Text); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, container.firstChild.firstChild); + assert_equals(caretPosition.offset, characterIndex); +}, "document.caretPositionFromPoint() should return a CaretPosition at the specified location"); + +test(() => { + container.setHTMLUnsafe(`a<div id="host"></div>b`); + const shadowRoot = host.attachShadow({mode: 'closed'}); + shadowRoot.setHTMLUnsafe(`<span>hello, world</span>`); + const rect = shadowRoot.firstChild.getBoundingClientRect(); + const characterWidth = rect.width / shadowRoot.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `he|llo, world`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y, shadowRoot); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Text); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, shadowRoot.firstChild.firstChild); + assert_equals(caretPosition.offset, characterIndex); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to a closed shadaw tree when the shadow tree is specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + <span>abcd</span> + <div id="host"> + <template shadowrootmode=open> + <span>hello, world</span> + </template> + </div>efg`); + const shadowRoot = host.shadowRoot; + const spanElement = document.querySelector("span"); + const rect = spanElement.getBoundingClientRect(); + const characterWidth = rect.width / spanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `ab|cd`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y, shadowRoot); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Text); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, spanElement.firstChild); + assert_equals(caretPosition.offset, characterIndex); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location when the non-intersecting shadow tree is specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + a<div id="host"> + <template shadowrootmode=open> + <span>hello, world</span> + </template> + </div>b`); + const shadowRoot = host.shadowRoot; + const shadowRootSpanElement = shadowRoot.querySelector("span"); + const rect = shadowRootSpanElement.getBoundingClientRect(); + const characterWidth = rect.width / shadowRootSpanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `he|llo, world`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Node); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, container); + assert_equals(caretPosition.offset, 1); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the shadow host\'s parent when the shadow tree is not specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + a<div id="outerHost"> + <template shadowrootmode=open> + <div id="innerHost"> + <template shadowrootmode=open> + <span>some text</span> + </template> + </div> + <div>world</div> + </template> + </div>b`); + const outerShadowRoot = outerHost.shadowRoot; + const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot; + const innerShadowRootSpanElement = innerShadowRoot.querySelector("span"); + const rect = innerShadowRootSpanElement.getBoundingClientRect(); + const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `so|me text`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Node); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, container); + assert_equals(caretPosition.offset, 1); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the outer shadow host\'s parent when the point is in an inner shadow tree and no shadow tree is specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + a<div id="outerHost"> + <template shadowrootmode=open> + <div id="innerHost"> + <template shadowrootmode=open> + <span>some text</span> + </template> + </div> + <div>world</div> + </template> + </div>b`); + const outerShadowRoot = outerHost.shadowRoot; + const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot; + const innerShadowRootSpanElement = innerShadowRoot.querySelector("span"); + const rect = innerShadowRootSpanElement.getBoundingClientRect(); + const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `so|me text`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y, innerShadowRoot); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Text); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, innerShadowRootSpanElement.firstChild); + assert_equals(caretPosition.offset, characterIndex); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the inner shadow tree when the point is in an inner shadow tree and the inner shadow tree is specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + a<div id="outerHost"> + <template shadowrootmode=open> + <div id="innerHost"> + <template shadowrootmode=open> + <span>some text</span> + </template> + </div> + <div>world</div> + </template> + </div>b`); + const outerShadowRoot = outerHost.shadowRoot; + const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot; + const innerShadowRootSpanElement = innerShadowRoot.querySelector("span"); + const rect = innerShadowRootSpanElement.getBoundingClientRect(); + const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `so|me text`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y, outerShadowRoot); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Node); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, outerShadowRoot); + assert_equals(caretPosition.offset, 1); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the outer shadow tree when the point is in an inner shadow tree and the outer shadow tree is specified as an argument'); + +test(() => { + container.setHTMLUnsafe(` + a<div id="outerHost"> + <template shadowrootmode=open> + <div id="innerHost"> + <template shadowrootmode=open> + <span>some text</span> + </template> + </div> + <div>world</div> + </template> + </div>b`); + + const outerShadowRoot = outerHost.shadowRoot; + const innerShadowRoot = outerShadowRoot.getElementById('innerHost').shadowRoot; + const innerShadowRootSpanElement = innerShadowRoot.querySelector("span"); + const rect = innerShadowRootSpanElement.getBoundingClientRect(); + const characterWidth = rect.width / innerShadowRootSpanElement.textContent.length; + const characterIndex = 2 + // Get x and y coordinate at `so|me text`. + const x = rect.left + characterWidth * characterIndex; + const y = rect.top + rect.height / 2; + const caretPosition = document.caretPositionFromPoint(x, y, outerShadowRoot, innerShadowRoot); + assert_true(caretPosition instanceof CaretPosition); + assert_true(caretPosition.offsetNode instanceof Text); + assert_equals(typeof(caretPosition.offset), "number"); + assert_equals(caretPosition.offsetNode, innerShadowRootSpanElement.firstChild); + assert_equals(caretPosition.offset, characterIndex); +}, 'document.caretPositionFromPoint() should return a CaretPosition at the specified location pointing to the inner shadow tree when the point is in an inner shadow tree and the inner shadow tree and the outer shadow tree are specified as an argument'); +</script> +</body> +</html> diff --git a/tests/wpt/tests/shadow-dom/WEB_FEATURES.yml b/tests/wpt/tests/shadow-dom/WEB_FEATURES.yml index 171923c0672..dcb21f38716 100644 --- a/tests/wpt/tests/shadow-dom/WEB_FEATURES.yml +++ b/tests/wpt/tests/shadow-dom/WEB_FEATURES.yml @@ -1,3 +1,6 @@ features: - name: shadow-dom files: "**" +- name: slot-assign + files: + - imperative-slot-* diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-across-scopes.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-across-scopes.html new file mode 100644 index 00000000000..d505383e338 --- /dev/null +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-across-scopes.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Display: reading-order-items with value grid-order on shadow host</title> +<link rel="help" href="https://drafts.csswg.org/css-display-4/#reading-order-items"> +<link rel="author" title="Di Zhang" href="mailto:dizhangg@chromium.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src='../../resources/shadow-dom.js'></script> +<script src="../../resources/focus-utils.js"></script> + +<style> +.wrapper { + display: grid; + reading-order-items: grid-order; +} +</style> + +<div class="test-case" data-expect="C,B,A" + data-description="Grid items in shadow root that is a display contents grid item"> + <div class=wrapper id="root"> + <div style="display: contents"> + <template shadowrootmode=open> + <slot></slot> + </template> + <button id="A2" style="order: 2">A</button> + <button id="B2" style="order: 1">B</button> + </div> + <button id="C" style="order: 3">C</button> + </div> +<div> + +<script> +runFocusTestCases(); +</script> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-nested-grids.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-nested-grids.html index d3da6682a34..15bdcf996fd 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-nested-grids.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-nested-grids.html @@ -1,5 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> +<meta name="timeout" content="long"> <title>CSS Display: reading-order-items with value grid-order in nested grids</title> <link rel="help" href="https://drafts.csswg.org/css-display-4/#reading-order-items"> <link rel="author" title="Di Zhang" href="mailto:dizhangg@chromium.org"> @@ -39,6 +40,32 @@ </div> </div> +<div class="test-case" data-expect="C,D,B,A" + data-description="Grid items are in display contents containers."> + <div class=box> + <div style="display:contents" tabindex="0"> + <div style="display:contents" tabindex="0"> + <button style="order: 4" id="A">A</button> + </div> + </div> + <div style="display:contents" tabindex="0"> + <div style="display:contents" tabindex="0"> + <button style="order: 3" id="B">B</button> + </div> + </div> + <div style="display:contents" tabindex="0"> + <div style="display:contents" tabindex="0"> + <button style="order: 1" id="C">C</button> + </div> + </div> + <div style="display:contents" tabindex="0"> + <div style="display:contents" tabindex="0"> + <button style="order: 2" id="D">D</button> + </div> + </div> + </div> +</div> + <div class="test-case" data-expect="wrapper,div3,button3b,button3a,div2,button2,div1,button1b,button1a" data-description="Grid items are grid containers."> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-popover.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-popover.html index 2e98c041570..c96a0c4fcf7 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-popover.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-popover.html @@ -1,5 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> +<meta name="timeout" content="long"> <title>CSS Display: reading-order-items with value grid-order</title> <link rel="help" href="https://drafts.csswg.org/css-display-4/#reading-order-items"> <link rel="author" title="Di Zhang" href="mailto:dizhangg@chromium.org"> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-slots.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-slots.html index 3045001e1d8..ed658b3510a 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-slots.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order-with-slots.html @@ -1,5 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> +<meta name="timeout" content="long"> <title>CSS Display: reading-order-items with value grid-order in Shadow DOM</title> <link rel="help" href="https://drafts.csswg.org/css-display-4/#reading-order-items"> <link rel="author" title="Di Zhang" href="mailto:dizhangg@chromium.org"> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order.html b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order.html index 1b86ab0b25a..3ee91358fd6 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order.html +++ b/tests/wpt/tests/shadow-dom/focus-navigation/reading-order/tentative/grid-order.html @@ -1,5 +1,6 @@ <!DOCTYPE html> <meta charset="utf-8"> +<meta name="timeout" content="long"> <title>CSS Display: reading-order-items with value grid-order</title> <link rel="help" href="https://drafts.csswg.org/css-display-4/#reading-order-items"> <link rel="author" title="Di Zhang" href="mailto:dizhangg@chromium.org"> diff --git a/tests/wpt/tests/shadow-dom/focus-navigation/resources/focus-utils.js b/tests/wpt/tests/shadow-dom/focus-navigation/resources/focus-utils.js index f4056dc1688..4aadfe24cbc 100644 --- a/tests/wpt/tests/shadow-dom/focus-navigation/resources/focus-utils.js +++ b/tests/wpt/tests/shadow-dom/focus-navigation/resources/focus-utils.js @@ -7,7 +7,7 @@ function waitForRender() { async function navigateFocusForward() { await waitForRender(); const kTab = '\uE004'; - await new test_driver.send_keys(document.documentElement,kTab); + await new test_driver.send_keys(document.body, kTab); await waitForRender(); } @@ -183,7 +183,7 @@ async function runFocusTestCases() { for (let testCase of testCases) { promise_test(async () => { const expected = testCase.dataset.expect.split(','); - await assert_focus_navigation_forward(expected); + await assert_focus_navigation_bidirectional(expected); }, testCase.dataset.description); } } diff --git a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html index f1f37b0affd..db361776f63 100644 --- a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html +++ b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-false-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html @@ -19,11 +19,10 @@ promise_test(async t => { `&shared_storage_cross_origin_worklet_allowed_header=?0` + `&token=${ancestor_key}`; - // The network error for `createWorklet()` won't be revealed to the - // cross-origin caller. - await sharedStorage.createWorklet( + return promise_rejects_dom(t, "OperationError", + sharedStorage.createWorklet( helper_url + `&action=store-cookie`, - { credentials: "include" }); + { credentials: "include" })); }, 'createWorklet() with cross-origin module script and credentials ' + '"include", and with the Shared-Storage-Cross-Origin-Worklet-Allowed ' + 'response header value set to false (?0)'); diff --git a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-credentials.tentative.https.sub.html b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-access-control-allow-credentials.tentative.https.sub.html index dd6347e4631..8887aad64dc 100644 --- a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-credentials.tentative.https.sub.html +++ b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-access-control-allow-credentials.tentative.https.sub.html @@ -18,11 +18,10 @@ promise_test(async t => { `&shared_storage_cross_origin_worklet_allowed_header=?1` + `&token=${ancestor_key}`; - // The network error for `createWorklet()` won't be revealed to the - // cross-origin caller. - await sharedStorage.createWorklet( + return promise_rejects_dom(t, "OperationError", + sharedStorage.createWorklet( helper_url + `&action=store-cookie`, - { credentials: "include" }); + { credentials: "include" })); }, 'createWorklet() with cross-origin module script and credentials ' + '"include", and without the Access-Control-Allow-Credentials response ' + 'header'); diff --git a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-origin.tentative.https.sub.html b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-access-control-allow-origin.tentative.https.sub.html index 1f3223a5644..58a2f3a77bb 100644 --- a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-access-control-allow-origin.tentative.https.sub.html +++ b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-access-control-allow-origin.tentative.https.sub.html @@ -18,11 +18,10 @@ promise_test(async t => { `&shared_storage_cross_origin_worklet_allowed_header=?1` + `&token=${ancestor_key}`; - // The network error for `createWorklet()` won't be revealed to the - // cross-origin caller. - await sharedStorage.createWorklet( + return promise_rejects_dom(t, "OperationError", + sharedStorage.createWorklet( helper_url + `&action=store-cookie`, - { credentials: "include" }); + { credentials: "include" })); }, 'createWorklet() with cross-origin module script and credentials ' + '"include", and without the Access-Control-Allow-Origin response header'); diff --git a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html index f96e4d596e8..5b140a8141c 100644 --- a/tests/wpt/tests/shared-storage/cross-origin-create-worklet-unrevealed-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html +++ b/tests/wpt/tests/shared-storage/cross-origin-create-worklet-failure-missing-shared-storage-cross-origin-worklet-allowed.tentative.https.sub.html @@ -18,11 +18,10 @@ promise_test(async t => { `&access_control_allow_credentials_header=true` + `&token=${ancestor_key}`; - // The network error for `createWorklet()`` won't be revealed to the - // cross-origin caller. - await sharedStorage.createWorklet( + return promise_rejects_dom(t, "OperationError", + sharedStorage.createWorklet( helper_url + `&action=store-cookie`, - { credentials: "include" }); + { credentials: "include" })); }, 'createWorklet() with cross-origin module script and credentials ' + '"include", and without the Shared-Storage-Cross-Origin-Worklet-Allowed ' + 'response header'); diff --git a/tests/wpt/tests/shared-storage/resources/shared-storage-writable-fetch-request-in-sandboxed-iframe-inner.https.sub.html b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-fetch-request-in-sandboxed-iframe-inner.https.sub.html new file mode 100644 index 00000000000..ef8b2459f3c --- /dev/null +++ b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-fetch-request-in-sandboxed-iframe-inner.https.sub.html @@ -0,0 +1,54 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + +async function init() { + // Make fetch request that sets (expectedKey, expectedValue) to shared storage + // via response header. + let {expectedKey, expectedValue} = parseExpectedKeyAndValueData(); + const rawWriteHeader = `set;key=${expectedKey};value=${expectedValue}`; + const writeHeader = encodeURIComponent(rawWriteHeader); + const fetchUrl = + `/shared-storage/resources/shared-storage-write-notify-parent.py` + + `?write=${writeHeader}`; + let frame = document.createElement('iframe'); + let parentOrOpener = window.opener || window.parent; + fetch(fetchUrl, {sharedStorageWritable: true}) + .then(response => response.text()) + .then(htmlContent => { + frame.srcdoc = htmlContent; + + const promise = new Promise((resolve, reject) => { + window.addEventListener('message', async function handler(evt) { + if (evt.source === frame.contentWindow && + evt.data.sharedStorageWritableHeader) { + assert_equals(evt.data.sharedStorageWritableHeader, '?1'); + parentOrOpener.postMessage({ + sharedStorageFetchStatus: "success", + sharedStorageWritableHeader: + evt.data.sharedStorageWritableHeader}, + "*"); + document.body.removeChild(frame); + window.removeEventListener('message', handler); + resolve(); + } + }); + window.addEventListener('error', () => { + reject(new Error('Fetch or navigation error')); + }); + }); + + // Navigate and wait for notification. + document.body.appendChild(frame); + return promise; + }) + .catch(error => { + parentOrOpener.postMessage({sharedStorageFetchStatus: error}, "*"); + }); +} + +init(); + </script> +</body> diff --git a/tests/wpt/tests/shared-storage/resources/shared-storage-writable-iframe-request-in-sandboxed-iframe-inner.https.sub.html b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-iframe-request-in-sandboxed-iframe-inner.https.sub.html new file mode 100644 index 00000000000..4d1b7ab198d --- /dev/null +++ b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-iframe-request-in-sandboxed-iframe-inner.https.sub.html @@ -0,0 +1,47 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + +async function init() { + // Create iframe that sets (expectedKey, expectedValue) to shared storage + // via response header. + let {expectedKey, expectedValue} = parseExpectedKeyAndValueData(); + const rawWriteHeader = `set;key=${expectedKey};value=${expectedValue}`; + const writeHeader = encodeURIComponent(rawWriteHeader); + const iframeSrc = + `/shared-storage/resources/shared-storage-write-notify-parent.py` + + `?write=${writeHeader}`; + let frame = document.createElement('iframe'); + frame.src = iframeSrc; + frame.sharedStorageWritable = true; + + // We pass the message on to the parent/opener. + const promise = new Promise((resolve, reject) => { + window.addEventListener('message', async function handler(evt) { + if (evt.source === frame.contentWindow && + evt.data.sharedStorageWritableHeader) { + assert_equals(evt.data.sharedStorageWritableHeader, '?1'); + let parentOrOpener = window.opener || window.parent; + parentOrOpener.postMessage({sharedStorageWritableHeader: + evt.data.sharedStorageWritableHeader}, + "*"); + document.body.removeChild(frame); + window.removeEventListener('message', handler); + resolve(); + } + }); + window.addEventListener('error', () => { + reject(new Error('Navigation error')); + }); + }); + + // Navigate and wait for notification. + document.body.appendChild(frame); + await promise; +} + +init(); + </script> +</body> diff --git a/tests/wpt/tests/shared-storage/resources/shared-storage-writable-img-request-in-sandboxed-iframe-inner.https.sub.html b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-img-request-in-sandboxed-iframe-inner.https.sub.html new file mode 100644 index 00000000000..8842a4689d8 --- /dev/null +++ b/tests/wpt/tests/shared-storage/resources/shared-storage-writable-img-request-in-sandboxed-iframe-inner.https.sub.html @@ -0,0 +1,37 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + +async function init() { + // Create image that sets (expectedKey, expectedValue) to shared storage + // via response header. + let {expectedKey, expectedValue} = parseExpectedKeyAndValueData(); + const imgSrc = + `/shared-storage/resources/shared-storage-writable-pixel.png` + + `?key=${expectedKey}&value=${expectedValue}`; + let image = document.createElement('img'); + image.src = imgSrc; + image.sharedStorageWritable = true; + + let parentOrOpener = window.opener || window.parent; + const promise = new Promise((resolve, reject) => { + image.addEventListener('load', () => { + parentOrOpener.postMessage({sharedStorageImageLoadStatus: "success"}, "*"); + resolve(); + }); + image.addEventListener('error', () => { + parentOrOpener.postMessage({sharedStorageImageLoadStatus: error}, "*"); + reject(error); + }); + }); + + // Navigate and wait for image load. + document.body.appendChild(image); + await promise; +} + +init(); + </script> +</body> diff --git a/tests/wpt/tests/shared-storage/shared-storage-writable-fetch-request-in-sandboxed-frame.tentative.https.html b/tests/wpt/tests/shared-storage/shared-storage-writable-fetch-request-in-sandboxed-frame.tentative.https.html new file mode 100644 index 00000000000..de935b22fe0 --- /dev/null +++ b/tests/wpt/tests/shared-storage/shared-storage-writable-fetch-request-in-sandboxed-frame.tentative.https.html @@ -0,0 +1,86 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/common/utils.js></script> + <script src=/fenced-frame/resources/utils.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + async function + test_shared_storage_writable_fetch_request_in_sandboxed_iframe( + test, key, value, sandbox_flags, expect_success) { + // Create sandboxed iframe. + let frame = document.createElement('iframe'); + frame.sandbox = sandbox_flags; + let url = new URL( + '/shared-storage/resources/' + + 'shared-storage-writable-fetch-request-in-sandboxed-iframe-' + + 'inner.https.sub.html', + location.href); + url = appendExpectedKeyAndValue(url, key, value); + frame.src = url; + + // We expect a message to bubble up via the sandboxed iframe. + const promise = new Promise((resolve, reject) => { + window.addEventListener('message', async function handler(evt) { + if (evt.source === frame.contentWindow && + evt.data.sharedStorageFetchStatus) { + if (expect_success) { + assert_true(!!evt.data.sharedStorageWritableHeader, + "sharedStorageWritableHeader expected in event data"); + assert_equals(evt.data.sharedStorageWritableHeader, '?1'); + assert_equals(evt.data.sharedStorageFetchStatus, "success"); + } else { + assert_equals(evt.data.sharedStorageFetchStatus.toString(), + "TypeError: Failed to execute 'fetch' on 'Window':" + + " sharedStorageWritable: sharedStorage operations" + + " are not available for opaque origins."); + } + document.body.removeChild(frame); + window.removeEventListener('message', handler); + resolve(); + } + }); + window.addEventListener('error', () => { + reject(new Error('Navigation error')); + }); + }); + + // Navigate and wait for notification. + document.body.appendChild(frame); + await promise; + + if (expect_success) { + // Verify that the value has been set. + await verifyKeyValueForOrigin(key, value, location.origin); + } else { + // Verify that the value has not been set. + await verifyKeyNotFoundForOrigin(key, location.origin); + } + + // Clean up and finish. + await sharedStorage.delete(key); + test.done(); + } + + async_test(t => { + test_shared_storage_writable_fetch_request_in_sandboxed_iframe( + t, + /*key=*/'a', + /*value=*/'b', + /*sandbox_flags=*/'allow-scripts allow-same-origin', + /*expect_success=*/true); + }, 'test sharedStorageWritable fetch request in sandboxed iframe with ' + + '"allow-same-origin"'); + + async_test(t => { + test_shared_storage_writable_fetch_request_in_sandboxed_iframe( + t, + /*key=*/'c', + /*value=*/'d', + /*sandbox_flags=*/'allow-scripts', + /*expect_success=*/false); + }, 'test sharedStorageWritable fetch request in sandboxed iframe without ' + + '"allow-same-origin"'); + </script> +</body> diff --git a/tests/wpt/tests/shared-storage/shared-storage-writable-iframe-request-in-sandboxed-frame.tentative.https.html b/tests/wpt/tests/shared-storage/shared-storage-writable-iframe-request-in-sandboxed-frame.tentative.https.html new file mode 100644 index 00000000000..d2d07fcc330 --- /dev/null +++ b/tests/wpt/tests/shared-storage/shared-storage-writable-iframe-request-in-sandboxed-frame.tentative.https.html @@ -0,0 +1,69 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/common/utils.js></script> + <script src=/fenced-frame/resources/utils.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + async function + test_shared_storage_writable_iframe_request_in_sandboxed_iframe( + test, key, value, sandbox_flags) { + // Create sandboxed iframe. + let frame = document.createElement('iframe'); + frame.sandbox = sandbox_flags; + let url = new URL( + '/shared-storage/resources/' + + 'shared-storage-writable-iframe-request-' + + 'in-sandboxed-iframe-inner.https.sub.html', + location.href); + url = appendExpectedKeyAndValue(url, key, value); + frame.src = url; + + // We expect a message to bubble up via the sandboxed iframe. + const promise = new Promise((resolve, reject) => { + window.addEventListener('message', async function handler(evt) { + if (evt.source === frame.contentWindow && + evt.data.sharedStorageWritableHeader) { + assert_equals(evt.data.sharedStorageWritableHeader, '?1'); + document.body.removeChild(frame); + window.removeEventListener('message', handler); + resolve(); + } + }); + window.addEventListener('error', () => { + reject(new Error('Navigation error')); + }); + }); + + // Navigate and wait for notification. + document.body.appendChild(frame); + await promise; + + // Verify that the value has been set. + await verifyKeyValueForOrigin(key, value, location.origin); + + // Clean up and finish. + await sharedStorage.delete(key); + test.done(); + } + + async_test(t => { + test_shared_storage_writable_iframe_request_in_sandboxed_iframe( + t, + /*key=*/'a', + /*value=*/'b', + /*sandbox_flags=*/'allow-scripts allow-same-origin'); + }, 'test sharedStorageWritable iframe request in sandboxed iframe with ' + + '"allow-same-origin"'); + + async_test(t => { + test_shared_storage_writable_iframe_request_in_sandboxed_iframe( + t, + /*key=*/'c', + /*value=*/'d', + /*sandbox_flags=*/'allow-scripts'); + }, 'test sharedStorageWritable iframe request in sandboxed iframe without ' + + '"allow-same-origin"'); + </script> +</body> diff --git a/tests/wpt/tests/shared-storage/shared-storage-writable-img-request-in-sandboxed-frame.tentative.https.html b/tests/wpt/tests/shared-storage/shared-storage-writable-img-request-in-sandboxed-frame.tentative.https.html new file mode 100644 index 00000000000..a901500d66a --- /dev/null +++ b/tests/wpt/tests/shared-storage/shared-storage-writable-img-request-in-sandboxed-frame.tentative.https.html @@ -0,0 +1,79 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/common/utils.js></script> + <script src=/fenced-frame/resources/utils.js></script> + <script src=/shared-storage/resources/util.js></script> + <script> + async function + test_shared_storage_writable_img_request_in_sandboxed_iframe( + test, key, value, sandbox_flags, expect_success) { + // Create sandboxed iframe. + let frame = document.createElement('iframe'); + frame.sandbox = sandbox_flags; + let url = new URL( + '/shared-storage/resources/' + + 'shared-storage-writable-img-request-' + + 'in-sandboxed-iframe-inner.https.sub.html', + location.href); + url = appendExpectedKeyAndValue(url, key, value); + frame.src = url; + + // We expect a message from the sandboxed iframe. + const promise = new Promise((resolve, reject) => { + window.addEventListener('message', async function handler(evt) { + if (evt.source === frame.contentWindow && + evt.data.sharedStorageImageLoadStatus) { + document.body.removeChild(frame); + window.removeEventListener('message', handler); + if (evt.data.sharedStorageImageLoadStatus === "success") { + resolve(); + } else { + reject(evt.data.sharedStorageImageLoadStatus); + } + } + }); + window.addEventListener('error', () => { + reject(new Error('Load error')); + }); + }); + + // Navigate and wait for notification. + document.body.appendChild(frame); + await promise; + + if (expect_success) { + // Verify that the value has been set. + await verifyKeyValueForOrigin(key, value, location.origin); + } else { + // Verify that the value has not been set. + await verifyKeyNotFoundForOrigin(key, location.origin); + } + + // Clean up and finish. + await sharedStorage.delete(key); + test.done(); + } + + async_test(t => { + test_shared_storage_writable_img_request_in_sandboxed_iframe( + t, + /*key=*/'a', + /*value=*/'b', + /*sandbox_flags=*/'allow-scripts allow-same-origin', + /*expect_success=*/true); + }, 'test sharedStorageWritable img request in sandboxed iframe with ' + + '"allow-same-origin"'); + + async_test(t => { + test_shared_storage_writable_img_request_in_sandboxed_iframe( + t, + /*key=*/'c', + /*value=*/'d', + /*sandbox_flags=*/'allow-scripts', + /*expect_success=*/false); + }, 'test sharedStorageWritable img request in sandboxed iframe without ' + + '"allow-same-origin"'); + </script> +</body> diff --git a/tests/wpt/tests/speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html b/tests/wpt/tests/speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html index 9c9371c4c31..2687b5bf2c2 100644 --- a/tests/wpt/tests/speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html +++ b/tests/wpt/tests/speculation-rules/prefetch/navigation-timing-requestStart-responseStart.https.html @@ -5,48 +5,92 @@ <script src="/common/utils.js"></script> <script src="../resources/utils.js"></script> <script src="resources/utils.sub.js"></script> +<script src="/common/subset-tests-by-key.js"></script> -<meta name="variant" content="?default"> -<meta name="variant" content="?prefetch=true"> +<meta name="variant" content="?include=noPrefetch"> +<meta name="variant" content="?include=afterResponse"> +<meta name="variant" content="?include=waitingForResponse"> +<meta name="variant" content="?include=waitingForRedirect"> <script> -setup(() => assertSpeculationRulesIsSupported()); +const setupProperties = {}; +if (shouldRunSubTest('waitingForResponse') || shouldRunSubTest('waitingForRedirect')) { + // These tests rely on the relationship between these timeouts, the delays + // on the server, and any vendor specific timeouts. Force a multiplier of 1, + // since using setTimeout directly incurs the wrath of `wpt lint`. + setupProperties.timeout_multiplier = 1; +} +setup(() => assertSpeculationRulesIsSupported(), setupProperties); -const searchParams = new URLSearchParams(location.search); -const prefetchEnabled = searchParams.has('prefetch'); +subsetTestByKey('noPrefetch', promise_test, async t => { + const agent = await spawnWindow(t); + const landingUrl = agent.getExecutorURL({page: 2}); -promise_test(async t => { - const agent = await spawnWindow(t); - // Some meaningless query param to avoid cached response. - const prefetchUrl = agent.getExecutorURL({ a: "b" }); + await agent.navigate(landingUrl); + assert_not_prefetched(await agent.getRequestHeaders(), `${landingUrl} should not be prefetched.`); - if (prefetchEnabled) - await agent.forceSinglePrefetch(prefetchUrl); + // It's generally expected that events occur in this order: + // ... -> connectEnd --> requestStart --> responseStart --> ... + const [entry] = await agent.execute_script( + () => performance.getEntriesByType('navigation')); + assert_less_than_equal(entry.connectEnd, entry.requestStart); + assert_less_than_equal(entry.requestStart, entry.responseStart); +}, "PerformanceNavigationTiming data should be in the correct order (no prefetch)"); + +subsetTestByKey('afterResponse', promise_test, async t => { + const agent = await spawnWindow(t); + const landingUrl = agent.getExecutorURL({page: 2}); + await agent.forceSinglePrefetch(landingUrl); + + await agent.navigate(landingUrl); + assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`); + + // Since the response should have started before the navigation, these should + // all have the same value (i.e., the start of the fetch). + const [entry] = await agent.execute_script( + () => performance.getEntriesByType('navigation')); + assert_equals(entry.connectEnd, entry.requestStart); + assert_equals(entry.requestStart, entry.responseStart); +}, "PerformanceNavigationTiming data should show 'instantaneous' events completed beforehand"); + +subsetTestByKey('waitingForResponse', promise_test, async t => { + const agent = await spawnWindow(t); + const landingUrl = agent.getExecutorURL({executor: 'slow-executor.py', delay: '4', page: 2}); + await agent.forceSinglePrefetch(landingUrl, {}, /*wait_for_completion=*/false); + await new Promise(resolve => t.step_timeout(resolve, 1000)); + + await agent.navigate(landingUrl); + assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`); + + // We should have to wait for this response. While timing is going to be + // somewhat variable here, it's probably wrong for the response to seem + // to take less than 1 second (since we only waited for 1 second). + // Regardless, these events should be normally ordered. + const [entry] = await agent.execute_script( + () => performance.getEntriesByType('navigation')); + assert_less_than_equal(entry.connectEnd, entry.requestStart); + assert_less_than_equal(entry.requestStart + 1000, entry.responseStart); + assert_greater_than(entry.responseStart, 1000); +}, "PerformanceNavigationTiming data should show noticeable TTFB if the response is slow"); - await agent.navigate(prefetchUrl); +subsetTestByKey('waitingForRedirect', promise_test, async t => { + const agent = await spawnWindow(t); + const landingUrl = agent.getExecutorURL({page: 2}); + const slowRedirectUrl = new URL(`/common/slow-redirect.py?delay=4&location=${encodeURIComponent(landingUrl)}`, document.baseURI); + await agent.forceSinglePrefetch(slowRedirectUrl, {}, /*wait_for_completion=*/false); + await new Promise(resolve => t.step_timeout(resolve, 1000)); - if (prefetchEnabled) { - assert_prefetched(await agent.getRequestHeaders(), - `Prefetch ${prefetchUrl.href} should work.`); - } else { - assert_not_prefetched(await agent.getRequestHeaders(), - `${prefetchUrl.href} should not be prefetched.`); - } + await agent.navigate(slowRedirectUrl, {expectedDestinationUrl: landingUrl}); + assert_prefetched(await agent.getRequestHeaders(), `${landingUrl} should have been prefetched.`); - const entries = await agent.execute_script( + // We should have to wait for this response. While timing is going to be + // somewhat variable here, it's probably wrong for the response to seem + // to take less than 1 second (since we only waited for 1 second). + // Regardless, these events should be normally ordered. + const [entry] = await agent.execute_script( () => performance.getEntriesByType('navigation')); - assert_equals(entries.length, 1, 'Wrong number of navigation entries'); - const entry = entries[0]; - - // Events timeline: - // ... -> connectEnd --> requestStart --> responseStart --> ... - if (prefetchEnabled) { - assert_equals(entry.connectEnd, entry.requestStart); - assert_equals(entry.requestStart, entry.responseStart); - } else { - assert_less_than_equal(entry.connectEnd, entry.requestStart); - assert_less_than_equal(entry.requestStart, entry.responseStart); - } - - }, "PerformanceNavigationTiming.requestStart/responseStart test, same origin prefetch."); + assert_less_than_equal(entry.connectEnd, entry.requestStart); + assert_less_than_equal(entry.requestStart, entry.responseStart); + assert_greater_than(entry.responseStart, 1000); +}, "PerformanceNavigationTiming data should show noticeable TTFB if the response is slow"); </script> diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/slow-executor.py b/tests/wpt/tests/speculation-rules/prefetch/resources/slow-executor.py new file mode 100644 index 00000000000..379ab552b94 --- /dev/null +++ b/tests/wpt/tests/speculation-rules/prefetch/resources/slow-executor.py @@ -0,0 +1,13 @@ +import os.path +import time + +from wptserve.pipes import template + +def main(request, response): + time.sleep(float(request.GET.first(b"delay"))) + response.headers.set(b"Content-Type", b"text/html") + response.headers.set(b"Cache-Control", b"no-store") + response.content = template( + request, + open(os.path.join(os.path.dirname(__file__), "executor.sub.html"), "rb").read()) + diff --git a/tests/wpt/tests/storage-access-api/WEB_FEATURES.yml b/tests/wpt/tests/storage-access-api/WEB_FEATURES.yml new file mode 100644 index 00000000000..a24e831c4aa --- /dev/null +++ b/tests/wpt/tests/storage-access-api/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: storage-access + files: "**" diff --git a/tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js index 6c3d616e26a..5c3089bf347 100644 --- a/tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js +++ b/tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js @@ -40,10 +40,10 @@ assert_true(cookieStringHasCookie("cookie", "unpartitioned", await MessageWorker(frame, {command: "load"})), "Worker's load was credentialed."); - assert_true(cookieStringHasCookie("cookie", "unpartitioned", + assert_false(cookieStringHasCookie("cookie", "unpartitioned", await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies})), - "Worker's fetch is credentialed."); - }, "Workers inherit storage access"); + "Worker's fetch is uncredentialed."); + }, "Workers don't inherit storage access"); promise_test(async (t) => { await MaybeSetStorageAccess("*", "*", "blocked"); diff --git a/tests/wpt/tests/svg/painting/reftests/paint-context-005-ref.svg b/tests/wpt/tests/svg/painting/reftests/paint-context-005-ref.svg deleted file mode 100644 index fa30a5361cb..00000000000 --- a/tests/wpt/tests/svg/painting/reftests/paint-context-005-ref.svg +++ /dev/null @@ -1,22 +0,0 @@ -<svg id="svg-root" - width="100%" height="100%" viewBox="0 0 480 360" - xmlns="http://www.w3.org/2000/svg" - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns:html="http://www.w3.org/1999/xhtml"> - <g id="testmeta"> - <title>Paint: 'paint-order'</title> - <html:link rel="author" - title="Stefan Zager" - href="mailto:szager@chromium.org"/> - </g> - - <defs> - <rect id="rectangle" width="120" height="120" /> - </defs> - - <g id="test-reference" font-size="16" style="fill:lime;stroke:blue;stroke-width:15px"> - <use xlink:href="#rectangle" transform="translate(60,120)"/> - <use xlink:href="#rectangle" transform="translate(300,120)" style="fill:lightblue;stroke:green"/> - </g> - -</svg> diff --git a/tests/wpt/tests/svg/painting/reftests/paint-context-005.svg b/tests/wpt/tests/svg/painting/reftests/paint-context-005.svg index 8bbfff8d474..a76c7af88ff 100644 --- a/tests/wpt/tests/svg/painting/reftests/paint-context-005.svg +++ b/tests/wpt/tests/svg/painting/reftests/paint-context-005.svg @@ -10,7 +10,6 @@ href="mailto:szager@chromium.org"/> <html:link rel="help" href="https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint"/> - <html:link rel="match" href="paint-context-005-ref.svg" /> </g> <html:script src="/resources/testharness.js"/> diff --git a/tests/wpt/tests/svg/types/scripted/SVGLength-rlh.html b/tests/wpt/tests/svg/types/scripted/SVGLength-rlh.html new file mode 100644 index 00000000000..411013b65b5 --- /dev/null +++ b/tests/wpt/tests/svg/types/scripted/SVGLength-rlh.html @@ -0,0 +1,31 @@ +<!DOCTYPE HTML> +<title>SVGLength with 'rlh' unit</title> +<link rel="help" href="https://www.w3.org/TR/SVG/types.html#InterfaceSVGLength"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> +:root { + font-family: initial; + font-size: 20px; +} +</style> +<div style="font-size: 10px"> + <div id="rlh_ref" style="width:10rlh"></div> + <svg> + <text id="rlh_test" x="10rlh"></text> + </svg> +</div> +<script> + let ref_width = rlh_ref.offsetWidth; + let rlh_length = rlh_test.x.baseVal[0]; + + test(() => { + assert_equals(rlh_length.unitType, SVGLength.SVG_LENGTHTYPE_UNKNOWN); + assert_equals(rlh_length.value, ref_width); + }, "rlh unit in SVGLength"); + + test(() => { + rlh_length.value = ref_width * 2; + assert_equals(rlh_length.valueInSpecifiedUnits, 20); + }, "Convert back to rlh from new user unit value"); +</script> diff --git a/tests/wpt/tests/tools/ci/requirements_build.txt b/tests/wpt/tests/tools/ci/requirements_build.txt index 7b4f8619b2e..e74e4e5302d 100644 --- a/tests/wpt/tests/tools/ci/requirements_build.txt +++ b/tests/wpt/tests/tools/ci/requirements_build.txt @@ -1,5 +1,5 @@ cairocffi==1.7.0 fonttools==4.51.0 genshi==0.7.7 -jinja2==3.1.3 +jinja2==3.1.4 pyyaml==6.0.1 diff --git a/tests/wpt/tests/tools/ci/requirements_tc.txt b/tests/wpt/tests/tools/ci/requirements_tc.txt index aa57643b9b5..b3c1c51f129 100644 --- a/tests/wpt/tests/tools/ci/requirements_tc.txt +++ b/tests/wpt/tests/tools/ci/requirements_tc.txt @@ -1,4 +1,4 @@ pygithub==2.3.0 pyyaml==6.0.1 requests==2.31.0 -taskcluster==64.2.7 +taskcluster==64.2.8 diff --git a/tests/wpt/tests/tools/lint/lint.py b/tests/wpt/tests/tools/lint/lint.py index e3a555413b8..32bc7ece7b1 100644 --- a/tests/wpt/tests/tools/lint/lint.py +++ b/tests/wpt/tests/tools/lint/lint.py @@ -394,10 +394,12 @@ def check_parsed(repo_root: Text, path: Text, f: IO[bytes]) -> List[rules.Error] if source_file.root is None: return [rules.ParseFailed.error(path)] - if source_file.type == "manual" and not source_file.name_is_manual: + test_type = source_file.type + + if test_type == "manual" and not source_file.name_is_manual: errors.append(rules.ContentManual.error(path)) - if source_file.type == "visual" and not source_file.name_is_visual: + if test_type == "visual" and not source_file.name_is_visual: errors.append(rules.ContentVisual.error(path)) about_blank_parts = urlsplit("about:blank") @@ -428,6 +430,10 @@ def check_parsed(repo_root: Text, path: Text, f: IO[bytes]) -> List[rules.Error] errors.append(rules.NonexistentRef.error(path, (reference_rel, href))) + if source_file.reftest_nodes: + if test_type not in ("print-reftest", "reftest"): + errors.append(rules.ReferenceInOtherType.error(path, (test_type,))) + if len(source_file.timeout_nodes) > 1: errors.append(rules.MultipleTimeout.error(path)) @@ -450,7 +456,6 @@ def check_parsed(repo_root: Text, path: Text, f: IO[bytes]) -> List[rules.Error] testharnessreport_nodes: List[ElementTree.Element] = [] if source_file.testharness_nodes: - test_type = source_file.manifest_items()[0] if test_type not in ("testharness", "manual"): errors.append(rules.TestharnessInOtherType.error(path, (test_type,))) if len(source_file.testharness_nodes) > 1: @@ -470,6 +475,9 @@ def check_parsed(repo_root: Text, path: Text, f: IO[bytes]) -> List[rules.Error] testdriver_vendor_nodes: List[ElementTree.Element] = [] if source_file.testdriver_nodes: + if test_type != "testharness": + errors.append(rules.TestdriverInUnsupportedType.error(path, (test_type,))) + if len(source_file.testdriver_nodes) > 1: errors.append(rules.MultipleTestdriver.error(path)) diff --git a/tests/wpt/tests/tools/lint/rules.py b/tests/wpt/tests/tools/lint/rules.py index c7b3a59b19e..8dba7817a9e 100644 --- a/tests/wpt/tests/tools/lint/rules.py +++ b/tests/wpt/tests/tools/lint/rules.py @@ -279,6 +279,11 @@ class TestdriverVendorPath(Rule): description = "testdriver-vendor.js script seen with incorrect path" +class TestdriverInUnsupportedType(Rule): + name = "TESTDRIVER-IN-UNSUPPORTED-TYPE" + description = "testdriver.js included in a %s test, which doesn't support testdriver.js" + + class OpenNoMode(Rule): name = "OPEN-NO-MODE" description = "File opened without providing an explicit mode (note: binary files must be read with 'b' in the mode flags)" @@ -324,6 +329,11 @@ class TestharnessInOtherType(Rule): description = "testharness.js included in a %s test" +class ReferenceInOtherType(Rule): + name = "REFERENCE-IN-OTHER-TYPE" + description = "Reference link included in a %s test" + + class DuplicateBasenamePath(Rule): name = "DUPLICATE-BASENAME-PATH" description = collapse(""" diff --git a/tests/wpt/tests/tools/lint/tests/test_file_lints.py b/tests/wpt/tests/tools/lint/tests/test_file_lints.py index f2ebcd9080a..e77048b3156 100644 --- a/tests/wpt/tests/tools/lint/tests/test_file_lints.py +++ b/tests/wpt/tests/tools/lint/tests/test_file_lints.py @@ -347,9 +347,47 @@ def test_multiple_testharnessreport(): ] +def test_testdriver_in_unsupported(): + code = b""" +<html xmlns="http://www.w3.org/1999/xhtml"> +<link rel="match" href="test-ref.html"/> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +</html> +""" + error_map = check_with_files(code) + + for (filename, (errors, kind)) in error_map.items(): + check_errors(errors) + + if kind in ["web-lax", "web-strict"]: + assert errors == [ + ( + "NON-EXISTENT-REF", + "Reference test with a non-existent 'match' relationship reference: " + "'test-ref.html'", + filename, + None, + ), + ( + "TESTDRIVER-IN-UNSUPPORTED-TYPE", + "testdriver.js included in a reftest test, which doesn't support " + "testdriver.js", + filename, + None, + ), + ] + elif kind == "python": + assert errors == [ + ("PARSE-FAILED", "Unable to parse file", filename, 2), + ] + + def test_early_testdriver_vendor(): code = b""" <html xmlns="http://www.w3.org/1999/xhtml"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> <script src="/resources/testdriver-vendor.js"></script> <script src="/resources/testdriver.js"></script> </html> @@ -669,6 +707,41 @@ def test_late_timeout(): ] +def test_reference_in_non_reference(): + code = b""" +<html xmlns="http://www.w3.org/1999/xhtml"> +<link rel="match" href="test-ref.html"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</html> +""" + error_map = check_with_files(code) + + for (filename, (errors, kind)) in error_map.items(): + check_errors(errors) + + if kind in ["web-lax", "web-strict"]: + assert errors == [ + ( + "NON-EXISTENT-REF", + "Reference test with a non-existent 'match' relationship reference: " + "'test-ref.html'", + filename, + None, + ), + ( + "REFERENCE-IN-OTHER-TYPE", + "Reference link included in a testharness test", + filename, + None, + ), + ] + elif kind == "python": + assert errors == [ + ("PARSE-FAILED", "Unable to parse file", filename, 2), + ] + + def test_print_function(): error_map = check_with_files(b"def foo():\n print('function')\n") diff --git a/tests/wpt/tests/tools/requirements_tests.txt b/tests/wpt/tests/tools/requirements_tests.txt index 24785f35313..74792e61314 100644 --- a/tests/wpt/tests/tools/requirements_tests.txt +++ b/tests/wpt/tests/tools/requirements_tests.txt @@ -2,5 +2,5 @@ httpx[http2]==0.27.0 json-e==4.7.0 jsonschema==4.17.3 pyyaml==6.0.1 -taskcluster==64.2.7 +taskcluster==64.2.8 mozterm==1.0.0 diff --git a/tests/wpt/tests/tools/webdriver/webdriver/bidi/transport.py b/tests/wpt/tests/tools/webdriver/webdriver/bidi/transport.py index d61ebaddea7..14b990f971d 100644 --- a/tests/wpt/tests/tools/webdriver/webdriver/bidi/transport.py +++ b/tests/wpt/tests/tools/webdriver/webdriver/bidi/transport.py @@ -6,6 +6,8 @@ from typing import Any, Callable, Coroutine, List, Optional, Mapping import websockets +from websockets.exceptions import ConnectionClosed + logger = logging.getLogger("webdriver.bidi") @@ -70,10 +72,13 @@ class Transport: async def read_messages(self) -> None: assert self.connection is not None - async for msg in self.connection: - if not isinstance(msg, str): - raise ValueError("Got a binary message") - await self.handle(msg) + try: + async for msg in self.connection: + if not isinstance(msg, str): + raise ValueError("Got a binary message") + await self.handle(msg) + except ConnectionClosed: + logger.debug("connection closed while reading messages") async def wait_closed(self) -> None: if self.connection and not self.connection.closed: diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/base.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/base.py index 6b1465cde8a..dd4fc314fc0 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/base.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/base.py @@ -3,8 +3,6 @@ import errno import os import platform import socket -import time -import traceback from abc import ABCMeta, abstractmethod from typing import cast, Any, List, Mapping, Optional, Tuple, Type @@ -12,7 +10,6 @@ import mozprocess from mozdebug import DebuggerInfo from mozlog.structuredlog import StructuredLogger -from ..environment import wait_for_service from ..testloader import GroupMetadata from ..wptcommandline import require_arg # noqa: F401 from ..wpttest import Test @@ -319,7 +316,6 @@ class WebDriverBrowser(Browser): self.env = os.environ.copy() if env is None else env self.webdriver_args = webdriver_args if webdriver_args is not None else [] - self.init_deadline: Optional[float] = None self._output_handler: Optional[OutputHandler] = None self._cmd = None self._proc: Optional[mozprocess.ProcessHandler] = None @@ -330,7 +326,6 @@ class WebDriverBrowser(Browser): return [self.webdriver_binary] + self.webdriver_args def start(self, group_metadata: GroupMetadata, **kwargs: Any) -> None: - self.init_deadline = time.time() + self.init_timeout try: self._run_server(group_metadata, **kwargs) except KeyboardInterrupt: @@ -345,7 +340,6 @@ class WebDriverBrowser(Browser): return OutputHandler(self.logger, cmd) def _run_server(self, group_metadata: GroupMetadata, **kwargs: Any) -> None: - assert self.init_deadline is not None cmd = self.make_command() self._output_handler = self.create_output_handler(cmd) @@ -365,21 +359,7 @@ class WebDriverBrowser(Browser): raise self._output_handler.after_process_start(self._proc.pid) - try: - wait_for_service( - self.logger, - self.host, - self.port, - timeout=self.init_deadline - time.time(), - server_process=self._proc, - ) - except Exception: - self.logger.error( - "WebDriver was not accessible " - f"within the timeout:\n{traceback.format_exc()}") - raise - finally: - self._output_handler.start(group_metadata=group_metadata, **kwargs) + self._output_handler.start(group_metadata=group_metadata, **kwargs) self.logger.debug("_run complete") def stop(self, force: bool = False) -> bool: diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox.py index d977930a289..d22da8568ad 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox.py @@ -910,6 +910,7 @@ class FirefoxWdSpecBrowser(WebDriverBrowser): self.binary = binary self.package_name = package_name self.webdriver_binary = webdriver_binary + self.init_deadline = None self.stackfix_dir = stackfix_dir self.symbols_path = symbols_path @@ -958,6 +959,7 @@ class FirefoxWdSpecBrowser(WebDriverBrowser): def start(self, group_metadata, **kwargs): self.leak_report_file = setup_leak_report(self.leak_check, self.profile, self.env) + self.init_deadline = time.time() + self.init_timeout super().start(group_metadata, **kwargs) def stop(self, force=False): diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py index f5641471562..46d38f14c55 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py @@ -22,7 +22,7 @@ from .executorwebdriver import ( WebDriverTestharnessExecutor, WebDriverTestharnessProtocolPart, ) -from .protocol import PrintProtocolPart +from .protocol import PrintProtocolPart, ProtocolPart here = os.path.dirname(__file__) @@ -80,8 +80,6 @@ class ChromeDriverTestharnessProtocolPart(WebDriverTestharnessProtocolPart): # exposed to the base WebDriver testharness executor. self.test_window = None self.reuse_window = self.parent.reuse_window - # Company prefix to apply to vendor-specific WebDriver extension commands. - self.cdp_company_prefix = "goog" def close_test_window(self): if self.test_window: @@ -106,13 +104,7 @@ class ChromeDriverTestharnessProtocolPart(WebDriverTestharnessProtocolPart): self.webdriver.window_handle = self.test_window # Reset navigation history with Chrome DevTools Protocol: # https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-resetNavigationHistory - body = { - "cmd": "Page.resetNavigationHistory", - "params": {}, - } - self.webdriver.send_session_command("POST", - self.cdp_company_prefix + "/cdp/execute", - body=body) + self.parent.cdp.execute_cdp_command("Page.resetNavigationHistory") self.webdriver.url = "about:blank" return except error.NoSuchWindowException: @@ -139,8 +131,6 @@ class ChromeDriverPrintProtocolPart(PrintProtocolPart): def setup(self): self.webdriver = self.parent.webdriver self.runner_handle = None - # Company prefix to apply to vendor-specific WebDriver extension commands. - self.cdp_company_prefix = "goog" def load_runner(self): url = urljoin(self.parent.executor.server_url("http"), "/print_pdf_runner.html") @@ -158,23 +148,18 @@ class ChromeDriverPrintProtocolPart(PrintProtocolPart): def render_as_pdf(self, width, height): margin = 0.5 - body = { - "cmd": "Page.printToPDF", - "params": { - # Chrome accepts dimensions in inches; we are using cm - "paperWidth": width / 2.54, - "paperHeight": height / 2.54, - "marginLeft": margin, - "marginRight": margin, - "marginTop": margin, - "marginBottom": margin, - "shrinkToFit": False, - "printBackground": True, - } + params = { + # Chrome accepts dimensions in inches; we are using cm + "paperWidth": width / 2.54, + "paperHeight": height / 2.54, + "marginLeft": margin, + "marginRight": margin, + "marginTop": margin, + "marginBottom": margin, + "shrinkToFit": False, + "printBackground": True, } - return self.webdriver.send_session_command("POST", - self.cdp_company_prefix + "/cdp/execute", - body=body)["data"] + return self.parent.cdp.execute_cdp_command("Page.printToPDF", params)["data"] def pdf_to_png(self, pdf_base64, ranges): handle = self.webdriver.window_handle @@ -191,19 +176,33 @@ render('%s').then(result => callback(result))""" % pdf_base64) class ChromeDriverFedCMProtocolPart(WebDriverFedCMProtocolPart): + def confirm_idp_login(self): + return self.webdriver.send_session_command("POST", + f"{self.parent.vendor_prefix}/fedcm/confirmidplogin") + + +class ChromeDriverDevToolsProtocolPart(ProtocolPart): + """A low-level API for sending Chrome DevTools Protocol [0] commands directly to the browser. + + Prefer using standard APIs where possible. + + [0]: https://chromedevtools.github.io/devtools-protocol/ + """ + name = "cdp" + def setup(self): self.webdriver = self.parent.webdriver - # Company prefix to apply to vendor-specific WebDriver extension commands. - self.fedcm_company_prefix = "goog" - - def confirm_idp_login(self): + def execute_cdp_command(self, command, params=None): + body = {"cmd": command, "params": params or {}} return self.webdriver.send_session_command("POST", - self.fedcm_company_prefix + "/fedcm/confirmidplogin") + f"{self.parent.vendor_prefix}/cdp/execute", + body=body) class ChromeDriverProtocol(WebDriverProtocol): implements = [ + ChromeDriverDevToolsProtocolPart, ChromeDriverFedCMProtocolPart, ChromeDriverPrintProtocolPart, ChromeDriverTestharnessProtocolPart, @@ -212,6 +211,8 @@ class ChromeDriverProtocol(WebDriverProtocol): part.name != ChromeDriverFedCMProtocolPart.name) ] reuse_window = False + # Prefix to apply to vendor-specific WebDriver extension commands. + vendor_prefix = "goog" class ChromeDriverRefTestExecutor(WebDriverRefTestExecutor, _SanitizerMixin): # type: ignore @@ -225,6 +226,24 @@ class ChromeDriverTestharnessExecutor(WebDriverTestharnessExecutor, _SanitizerMi super().__init__(*args, **kwargs) self.protocol.reuse_window = reuse_window + def setup(self, runner): + super().setup(runner) + # Chromium requires the `background-sync` permission for reporting APIs + # to work. Not all embedders (notably, `chrome --headless=old`) grant + # `background-sync` by default, so this CDP call ensures the permission + # is granted for all origins, in line with the background sync spec's + # recommendation [0]. + # + # WebDriver's "Set Permission" command can only act on the test's + # origin, which may be too limited. + # + # [0]: https://wicg.github.io/background-sync/spec/#permission + params = { + "permission": {"name": "background-sync"}, + "setting": "granted", + } + self.protocol.cdp.execute_cdp_command("Browser.setPermission", params) + class ChromeDriverPrintRefTestExecutor(ChromeDriverRefTestExecutor): protocol_cls = ChromeDriverProtocol diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py index 3b62cb7477b..ad546b7e840 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executoredge.py @@ -1,101 +1,82 @@ -# mypy: allow-untyped-defs
-
-import os
-
-from .executorwebdriver import (
- WebDriverCrashtestExecutor,
- WebDriverProtocol,
- WebDriverRefTestExecutor,
- WebDriverRun,
- WebDriverTestharnessExecutor,
-)
-
-from .executorchrome import (
- ChromeDriverPrintProtocolPart,
- ChromeDriverTestharnessProtocolPart,
- make_sanitizer_mixin,
-)
-
-here = os.path.dirname(__file__)
-
-_SanitizerMixin = make_sanitizer_mixin(WebDriverCrashtestExecutor)
-
-class EdgeDriverTestharnessProtocolPart(ChromeDriverTestharnessProtocolPart):
- def setup(self):
- super().setup()
- self.cdp_company_prefix = "ms"
-
-
-class EdgeDriverPrintProtocolPart(ChromeDriverPrintProtocolPart):
- def setup(self):
- super().setup()
- self.cdp_company_prefix = "ms"
-
-
-class EdgeDriverProtocol(WebDriverProtocol):
- implements = [
- EdgeDriverPrintProtocolPart,
- EdgeDriverTestharnessProtocolPart,
- *(part for part in WebDriverProtocol.implements
- if part.name != EdgeDriverTestharnessProtocolPart.name)
- ]
- reuse_window = False
-
-
-class EdgeDriverRefTestExecutor(WebDriverRefTestExecutor, _SanitizerMixin): # type: ignore
- protocol_cls = EdgeDriverProtocol
-
-
-class EdgeDriverTestharnessExecutor(WebDriverTestharnessExecutor, _SanitizerMixin): # type: ignore
- protocol_cls = EdgeDriverProtocol
-
- def __init__(self, *args, reuse_window=False, **kwargs):
- super().__init__(*args, **kwargs)
- self.protocol.reuse_window = reuse_window
-
-
-class EdgeDriverPrintRefTestExecutor(EdgeDriverRefTestExecutor):
- protocol_cls = EdgeDriverProtocol
-
- def setup(self, runner):
- super().setup(runner)
- self.protocol.pdf_print.load_runner()
- self.has_window = False
- with open(os.path.join(here, "reftest.js")) as f:
- self.script = f.read()
-
- def screenshot(self, test, viewport_size, dpi, page_ranges):
- # https://github.com/web-platform-tests/wpt/issues/7140
- assert dpi is None
-
- if not self.has_window:
- self.protocol.base.execute_script(self.script)
- self.protocol.base.set_window(self.protocol.webdriver.handles[-1])
- self.has_window = True
-
- self.viewport_size = viewport_size
- self.page_ranges = page_ranges.get(test.url)
- timeout = self.timeout_multiplier * test.timeout if self.debug_info is None else None
-
- test_url = self.test_url(test)
-
- return WebDriverRun(self.logger,
- self._render,
- self.protocol,
- test_url,
- timeout,
- self.extra_timeout).run()
-
- def _render(self, protocol, url, timeout):
- protocol.webdriver.url = url
-
- protocol.base.execute_script(self.wait_script, asynchronous=True)
-
- pdf = protocol.pdf_print.render_as_pdf(*self.viewport_size)
- screenshots = protocol.pdf_print.pdf_to_png(pdf, self.page_ranges)
- for i, screenshot in enumerate(screenshots):
- # strip off the data:img/png, part of the url
- if screenshot.startswith("data:image/png;base64,"):
- screenshots[i] = screenshot.split(",", 1)[1]
-
- return screenshots
+# mypy: allow-untyped-defs + +import os + +from .executorwebdriver import ( + WebDriverCrashtestExecutor, + WebDriverRefTestExecutor, + WebDriverRun, + WebDriverTestharnessExecutor, +) + +from .executorchrome import ( + ChromeDriverProtocol, + make_sanitizer_mixin, +) + +here = os.path.dirname(__file__) + +_SanitizerMixin = make_sanitizer_mixin(WebDriverCrashtestExecutor) + + +class EdgeDriverProtocol(ChromeDriverProtocol): + vendor_prefix = "ms" + + +class EdgeDriverRefTestExecutor(WebDriverRefTestExecutor, _SanitizerMixin): # type: ignore + protocol_cls = EdgeDriverProtocol + + +class EdgeDriverTestharnessExecutor(WebDriverTestharnessExecutor, _SanitizerMixin): # type: ignore + protocol_cls = EdgeDriverProtocol + + def __init__(self, *args, reuse_window=False, **kwargs): + super().__init__(*args, **kwargs) + self.protocol.reuse_window = reuse_window + + +class EdgeDriverPrintRefTestExecutor(EdgeDriverRefTestExecutor): + protocol_cls = EdgeDriverProtocol + + def setup(self, runner): + super().setup(runner) + self.protocol.pdf_print.load_runner() + self.has_window = False + with open(os.path.join(here, "reftest.js")) as f: + self.script = f.read() + + def screenshot(self, test, viewport_size, dpi, page_ranges): + # https://github.com/web-platform-tests/wpt/issues/7140 + assert dpi is None + + if not self.has_window: + self.protocol.base.execute_script(self.script) + self.protocol.base.set_window(self.protocol.webdriver.handles[-1]) + self.has_window = True + + self.viewport_size = viewport_size + self.page_ranges = page_ranges.get(test.url) + timeout = self.timeout_multiplier * test.timeout if self.debug_info is None else None + + test_url = self.test_url(test) + + return WebDriverRun(self.logger, + self._render, + self.protocol, + test_url, + timeout, + self.extra_timeout).run() + + def _render(self, protocol, url, timeout): + protocol.webdriver.url = url + + protocol.base.execute_script(self.wait_script, asynchronous=True) + + pdf = protocol.pdf_print.render_as_pdf(*self.viewport_size) + screenshots = protocol.pdf_print.pdf_to_png(pdf, self.page_ranges) + for i, screenshot in enumerate(screenshots): + # strip off the data:img/png, part of the url + if screenshot.startswith("data:image/png;base64,"): + screenshots[i] = screenshot.split(",", 1)[1] + + return screenshots diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/tests/browsers/test_base.py b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/browsers/test_base.py index a3d804336e1..b5e40e3f8df 100644 --- a/tests/wpt/tests/tools/wptrunner/wptrunner/tests/browsers/test_base.py +++ b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/browsers/test_base.py @@ -2,7 +2,6 @@ import sys from os.path import dirname, join -from unittest import mock import pytest @@ -30,19 +29,14 @@ def test_logging_immediate_exit(): handler = MozLogTestHandler() logger.add_handler(handler) - class CustomException(Exception): - pass - - with mock.patch.object(base, "wait_for_service", side_effect=CustomException): - browser = base.WebDriverBrowser( - logger, webdriver_binary="echo", webdriver_args=["sample output"] - ) - try: - with pytest.raises(CustomException): - browser.start(group_metadata={}) - finally: - # Ensure the `echo` process actually exits - browser._proc.wait() + browser = base.WebDriverBrowser( + logger, webdriver_binary="echo", webdriver_args=["sample output"] + ) + try: + browser.start(group_metadata={}) + finally: + # Ensure the `echo` process actually exits + browser._proc.wait() process_output_actions = [ data for data in handler.items if data["action"] == "process_output" diff --git a/tests/wpt/tests/tools/wptserve/wptserve/sslutils/openssl.py b/tests/wpt/tests/tools/wptserve/wptserve/sslutils/openssl.py index 25f86e019ec..2a388671b62 100644 --- a/tests/wpt/tests/tools/wptserve/wptserve/sslutils/openssl.py +++ b/tests/wpt/tests/tools/wptserve/wptserve/sslutils/openssl.py @@ -7,6 +7,7 @@ import shutil import subprocess import tempfile from datetime import datetime, timedelta, timezone +from email.utils import parsedate_to_datetime # Amount of time beyond the present to consider certificates "expired." This # allows certificates to be proactively re-generated in the "buffer" period @@ -310,12 +311,9 @@ class OpenSSLEnvironment: "-noout", "-enddate", "-in", cert_path).decode("utf8").split("=", 1)[1].strip() - # Not sure if this works in other locales - end_date = datetime.strptime(end_date_str, "%b %d %H:%M:%S %Y %Z") + # openssl outputs an RFC 822 date + end_date = parsedate_to_datetime(end_date_str) time_buffer = timedelta(**CERT_EXPIRY_BUFFER) - # Because `strptime` does not account for time zone offsets, it is - # always in terms of UTC, so the current time should be calculated - # accordingly. if end_date < datetime.now(timezone.utc) + time_buffer: return False diff --git a/tests/wpt/tests/trusted-types/Document-write.html b/tests/wpt/tests/trusted-types/Document-write.html index 87e9e724699..7902733f67c 100644 --- a/tests/wpt/tests/trusted-types/Document-write.html +++ b/tests/wpt/tests/trusted-types/Document-write.html @@ -11,4 +11,64 @@ document.write(html); assert_true(document.body.innerText.indexOf(RESULTS.HTML) !== -1); }, "document.write with html assigned via policy (successful transformation)."); + + test(t => { + document.body.innerText = ''; + let p = createHTML_policy(window, 1); + let html = p.createHTML(INPUTS.HTML); + document.writeln(html); + assert_true(document.body.innerText.indexOf(RESULTS.HTML) !== -1); + }, "document.writeln with html assigned via policy (successful transformation)."); + + test(t => { + document.body.innerText = ''; + let p = createHTML_policy(window, 1); + let a = p.createHTML("abcdef"); + let b = p.createHTML("ghijkl"); + document.write(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.write(TrustedHTML, TrustedHTML)"); + + test(t => { + document.body.innerText = ''; + let p = createHTML_policy(window, 1); + let a = p.createHTML("abcdef"); + let b = p.createHTML("ghijkl"); + document.writeln(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.writeln(TrustedHTML, TrustedHTML)"); + + test(t => { + document.body.innerText = ''; + let p = createHTML_policy(window, 1); + let a = p.createHTML("abcdef"); + let b = "ghijkl"; + document.write(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.write(TrustedHTML, String)"); + + test(t => { + document.body.innerText = ''; + let p = createHTML_policy(window, 1); + let a = p.createHTML("abcdef"); + let b = "ghijkl"; + document.writeln(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.writeln(TrustedHTML, String)"); + + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = "ghijkl"; + document.write(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.write(String, String)"); + + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = "ghijkl"; + document.writeln(a, b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.writeln(String, String)"); </script> diff --git a/tests/wpt/tests/trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP.html b/tests/wpt/tests/trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP.html index c0f72bb36ac..aafe3c70313 100644 --- a/tests/wpt/tests/trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP.html +++ b/tests/wpt/tests/trusted-types/Element-setAttribute-respects-Elements-node-documents-globals-CSP.html @@ -16,10 +16,7 @@ <body> <div id="nonSVGTestElements"> <iframe srcdoc="v"></iframe> - <embed src="v" /> <script src="v"></script> - <object data="v"></object> - <object codebase="v"></object> </div> <svg id="svgTestElements"> <script href="v"></script> diff --git a/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html b/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html index 974203c1133..d22be1118ce 100644 --- a/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html +++ b/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html @@ -18,6 +18,14 @@ assert_equals(document.body.innerText, RESULTS.HTML); }, "document.write with html assigned via policy (successful URL transformation)."); + test(t => { + document.body.innerText = ''; + let a = p.createHTML("abcdef"); + let b = p.createHTML("ghijkl"); + document.write(a,b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.write with multiple trusted arguments."); + // TrustedURL assignments do not throw. (Now for writeln.) test(t => { document.body.innerText = ''; @@ -26,6 +34,14 @@ assert_equals(document.body.innerText, RESULTS.HTML); }, "document.writeln with html assigned via policy (successful URL transformation)."); + test(t => { + document.body.innerText = ''; + let a = p.createHTML("abcdef"); + let b = p.createHTML("ghijkl"); + document.writeln(a,b); + assert_equals(document.body.innerText, "abcdefghijkl"); + }, "document.writeln with multiple trusted arguments."); + // String assignments throw. test(t => { const old = document.body.innerText; @@ -35,6 +51,26 @@ assert_equals(document.body.innerText, old); }, "`document.write(string)` throws"); + test(t => { + const old = document.body.innerText; + assert_throws_js(TypeError, _ => { + let a = "abcdef"; + let b = "ghijkl"; + document.write(a, b); + }); + assert_equals(document.body.innerText, old); + }, "`document.write(string, string)` throws"); + + test(t => { + const old = document.body.innerText; + assert_throws_js(TypeError, _ => { + let a = "abcdef"; + let b = p.createHTML("ghijkl"); + document.write(a, b); + }); + assert_equals(document.body.innerText, old); + }, "`document.write(string, TrustedHTML)` throws"); + // String assignments throw. (Now for writeln.) test(t => { const old = document.body.innerText; @@ -44,6 +80,26 @@ assert_equals(document.body.innerText, old); }, "`document.writeln(string)` throws"); + test(t => { + const old = document.body.innerText; + assert_throws_js(TypeError, _ => { + let a = "abcdef"; + let b = "ghijkl"; + document.writeln(a, b); + }); + assert_equals(document.body.innerText, old); + }, "`document.writeln(string, string)` throws"); + + test(t => { + const old = document.body.innerText; + assert_throws_js(TypeError, _ => { + let a = "abcdef"; + let b = p.createHTML("ghijkl"); + document.writeln(a, b); + }); + assert_equals(document.body.innerText, old); + }, "`document.writeln(string, TrustedHTML)` throws"); + // Null assignment throws. test(t => { const old = document.body.innerText; @@ -63,7 +119,11 @@ }, "`document.writeln(null)` throws"); let default_policy = trustedTypes.createPolicy('default', - { createHTML: createHTMLJS }, true ); + { createHTML: (html) => { + return html.replace("Hi", "Quack") + .replace("transformed", "a duck") + .replace("defghi", "zxcvbn") + } }, true ); // Default policy works. test(t => { @@ -72,10 +132,42 @@ assert_equals(document.body.innerText, RESULTS.HTML); }, "`document.write(string)` observes default policy"); + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = "ghijkl"; + document.write(a, b); + assert_equals(document.body.innerText, "abczxcvbnjkl"); + }, "`document.write(string, string)` observes default policy"); + + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = p.createHTML("ghijkl"); + document.write(a, b); + assert_equals(document.body.innerText, "abczxcvbnjkl"); + }, "`document.write(string, TrustedHTML)` observes default policy"); + // Default policy works. (Now for writeln.) test(t => { document.body.innerText = ''; document.writeln(INPUTS.HTML); assert_equals(document.body.innerText, RESULTS.HTML); }, "`document.writeln(string)` observes default policy"); + + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = "ghijkl"; + document.writeln(a, b); + assert_equals(document.body.innerText, "abczxcvbnjkl"); + }, "`document.writeln(string, string)` observes default policy"); + + test(t => { + document.body.innerText = ''; + let a = "abcdef"; + let b = p.createHTML("ghijkl"); + document.writeln(a, b); + assert_equals(document.body.innerText, "abczxcvbnjkl"); + }, "`document.writeln(string, TrustedHTML)` observes default policy"); </script> diff --git a/tests/wpt/tests/video-rvfc/WEB_FEATURES.yml b/tests/wpt/tests/video-rvfc/WEB_FEATURES.yml new file mode 100644 index 00000000000..f206d0be0b4 --- /dev/null +++ b/tests/wpt/tests/video-rvfc/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: request-video-frame-callback + files: "**" diff --git a/tests/wpt/tests/webauthn/createcredential-passing.https.html b/tests/wpt/tests/webauthn/createcredential-passing.https.html index f64a4ff0397..4124c2247ea 100644 --- a/tests/wpt/tests/webauthn/createcredential-passing.https.html +++ b/tests/wpt/tests/webauthn/createcredential-passing.https.html @@ -58,6 +58,10 @@ standardSetup(function() { new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [pkParamEC512, pkParamEC256]) .runTest("SelectEC256 pubKeyCredParams from a list"); + // pubKeyCredParams with unknown value + new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [{ "type": "unknown", alg: -7, }, { "type": "public-key", alg: -7, }]) + .runTest("pubKeyCredParams with unknown value"); + // timeout new CreateCredentialsTest({path: "options.publicKey.timeout", value: undefined}).runTest("passing credentials.create() with no timeout"); diff --git a/tests/wpt/tests/webauthn/createcredential-pubkeycredparams.https.html b/tests/wpt/tests/webauthn/createcredential-pubkeycredparams.https.html index d1df7952d67..cb830bfe92a 100644 --- a/tests/wpt/tests/webauthn/createcredential-pubkeycredparams.https.html +++ b/tests/wpt/tests/webauthn/createcredential-pubkeycredparams.https.html @@ -36,10 +36,10 @@ standardSetup(function() { new CreateCredentialsTest({path: "options.publicKey.pubKeyCredParams", value: undefined}).runTest("Bad pubKeyCredParams: pubKeyCredParams is undefined", TypeError); new CreateCredentialsTest("options.publicKey.pubKeyCredParams", "hi mom").runTest("Bad pubKeyCredParams: pubKeyCredParams is string", TypeError); new CreateCredentialsTest("options.publicKey.pubKeyCredParams", null).runTest("Bad pubKeyCredParams: pubKeyCredParams is null", TypeError); - new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badType]).runTest("Bad pubKeyCredParams: first param has bad type (\"something-else\")", TypeError); - new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyString]).runTest("Bad pubKeyCredParams: first param has bad type (\"\")", TypeError); - new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeNull]).runTest("Bad pubKeyCredParams: first param has bad type (null)", TypeError); - new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyObj]).runTest("Bad pubKeyCredParams: first param has bad type (empty object)", TypeError); + new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badType]).runTest("Bad pubKeyCredParams: first param has bad type (\"something-else\")", "NotSupportedError"); + new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyString]).runTest("Bad pubKeyCredParams: first param has bad type (\"\")", "NotSupportedError"); + new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeNull]).runTest("Bad pubKeyCredParams: first param has bad type (null)", "NotSupportedError"); + new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badTypeEmptyObj]).runTest("Bad pubKeyCredParams: first param has bad type (empty object)", "NotSupportedError"); new CreateCredentialsTest("options.publicKey.pubKeyCredParams", [badAlg]) .modify("options.publicKey.timeout", 300) .runTest("Bad pubKeyCredParams: first param has bad alg (42)", "NotAllowedError"); diff --git a/tests/wpt/tests/webauthn/getcredential-allowcredentials.https.html b/tests/wpt/tests/webauthn/getcredential-allowcredentials.https.html new file mode 100644 index 00000000000..0263774142c --- /dev/null +++ b/tests/wpt/tests/webauthn/getcredential-allowcredentials.https.html @@ -0,0 +1,77 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>navigator.credentials.get() tests with allowCredentials</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<script src=helpers.js></script> +<body></body> +<script> +standardSetup(async function() { + "use strict"; + + promise_test(async t => { + await navigator.credentials.get({publicKey: { + challenge: new Uint8Array(), + allowCredentials: [{ + id: (await createCredential()).rawId, + type: "public-key", + }], + }}); + }, "navigator.credentials.get() with public-key allowCredentials."); + + promise_test(async t => { + return promise_rejects_dom(t, "NotAllowedError", + navigator.credentials.get({publicKey: { + challenge: new Uint8Array(), + allowCredentials: [], + }})); + }, "navigator.credentials.get() with empty allowCredentials."); + + promise_test(async t => { + return promise_rejects_dom(t, "NotAllowedError", + navigator.credentials.get({publicKey: { + challenge: new Uint8Array(), + allowCredentials: [{ + id: (await createCredential()).rawId, + type: "not-yet-supported-by-browser", + }], + }})); + }, "navigator.credentials.get() with unknown allowCredentials."); + + promise_test(async t => { + await navigator.credentials.get({publicKey: { + challenge: new Uint8Array(), + allowCredentials: [{ + id: (await createCredential()).rawId, + type: "not-yet-supported-by-browser", + }, + { + id: (await createCredential()).rawId, + type: "public-key", + }], + }}); + }, "navigator.credentials.get() with mixing allowCredentials with first unknown type."); + + promise_test(async t => { + await navigator.credentials.get({publicKey: { + challenge: new Uint8Array(), + allowCredentials: [{ + id: (await createCredential()).rawId, + type: "public-key", + }, + { + id: (await createCredential()).rawId, + type: "not-yet-supported-by-browser", + }], + }}); + }, "navigator.credentials.get() with mixing allowCredentials with last unknown type."); +}, { + protocol: "ctap2_1", + hasResidentKey: true, + hasUserVerification: true, + isUserVerified: true, +}); +</script> diff --git a/tests/wpt/tests/webcodecs/videoFrame-copyTo-rgb.any.js b/tests/wpt/tests/webcodecs/videoFrame-copyTo-rgb.any.js index 442efc4b0f4..146b6756cb4 100644 --- a/tests/wpt/tests/webcodecs/videoFrame-copyTo-rgb.any.js +++ b/tests/wpt/tests/webcodecs/videoFrame-copyTo-rgb.any.js @@ -243,6 +243,8 @@ function test_unsupported_pixel_formats() { const data = new Uint32Array(16); const options = {format: pixelFormat}; const frame = new VideoFrame(data, init); + assert_throws_dom( + 'NotSupportedError', () => frame.allocationSize(options)); await promise_rejects_dom( t, 'NotSupportedError', frame.copyTo(data, options)) frame.close(); diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/locate_nodes/start_nodes.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/locate_nodes/start_nodes.py index f44a6d4857c..351020af4c2 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/locate_nodes/start_nodes.py +++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/locate_nodes/start_nodes.py @@ -232,3 +232,47 @@ async def test_locate_with_multiple_context_nodes(bidi_session, inline, top_cont ] recursive_compare(expected, result["nodes"]) + + +@pytest.mark.parametrize("type,value", [ + ("css", "p[data-class='one']"), + ("xpath", ".//p[@data-class='one']"), + ("innerText", "foo"), + ("accessibility", {"role": "banner", "name": "bar"}), +]) +@pytest.mark.asyncio +async def test_locate_with_document_context_node(bidi_session, inline, top_context, type, value): + url = inline(""" + <p data-class="one" role="banner" aria-label="bar">foo</p> + """) + await bidi_session.browsing_context.navigate( + context=top_context["context"], url=url, wait="complete" + ) + + context_node = await bidi_session.script.evaluate( + expression="document", + target=ContextTarget(top_context["context"]), + await_promise=True, + ) + + result = await bidi_session.browsing_context.locate_nodes( + context=top_context["context"], + locator={ "type": type, "value": value }, + start_nodes=[context_node] + ) + + expected = [ + { + "type": "node", + "sharedId": any_string, + "value": { + "attributes": {"data-class":"one"}, + "childNodeCount": 1, + "localName": "p", + "namespaceURI": "http://www.w3.org/1999/xhtml", + "nodeType": 1, + } + } + ] + + recursive_compare(expected, result["nodes"]) diff --git a/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/invalid.py b/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/invalid.py index 5397dc7b62e..d7172160721 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/invalid.py +++ b/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/invalid.py @@ -4,6 +4,7 @@ from webdriver.bidi.undefined import UNDEFINED pytestmark = pytest.mark.asyncio + @pytest.mark.parametrize("descriptor", [False, "SOME_STRING", 42, {}, [], {"name": 23}, None, UNDEFINED]) async def test_params_descriptor_invalid_type(bidi_session, descriptor): with pytest.raises(error.InvalidArgumentException): @@ -54,8 +55,8 @@ async def test_params_origin_invalid_type(bidi_session, origin): ) -@pytest.mark.parametrize("user_context", [False, 42, {}, [], None]) -async def test_params_origin_invalid_type(bidi_session, user_context): +@pytest.mark.parametrize("user_context", [False, 42, {}, []]) +async def test_params_user_context_invalid_type(bidi_session, user_context): with pytest.raises(error.InvalidArgumentException): await bidi_session.permissions.set_permission( descriptor={"name": "geolocation"}, diff --git a/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/set_permission.py b/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/set_permission.py index 45c50dbf883..18f8e6fed00 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/set_permission.py +++ b/tests/wpt/tests/webdriver/tests/bidi/external/permissions/set_permission/set_permission.py @@ -1,10 +1,10 @@ import pytest -import webdriver.bidi.error as error from . import get_context_origin, get_permission_state pytestmark = pytest.mark.asyncio + @pytest.mark.asyncio async def test_set_permission(bidi_session, new_tab, url): test_url = url("/common/blank.html", protocol="https") @@ -44,24 +44,6 @@ async def test_set_permission(bidi_session, new_tab, url): @pytest.mark.asyncio -async def test_set_permission_insecure_context(bidi_session, new_tab, url): - test_url = url("/common/blank.html", protocol="http") - await bidi_session.browsing_context.navigate( - context=new_tab["context"], - url=test_url, - wait="complete", - ) - - origin = await get_context_origin(bidi_session, new_tab) - - with pytest.raises(error.InvalidArgumentException): - await bidi_session.permissions.set_permission( - descriptor={"name": "push"}, - state="granted", - origin=origin, - ) - -@pytest.mark.asyncio async def test_set_permission_new_context(bidi_session, new_tab, url): test_url = url("/common/blank.html", protocol="https") diff --git a/tests/wpt/tests/webdriver/tests/bidi/input/perform_actions/wheel.py b/tests/wpt/tests/webdriver/tests/bidi/input/perform_actions/wheel.py index 4f897479e23..ee0d4d4600d 100644 --- a/tests/wpt/tests/webdriver/tests/bidi/input/perform_actions/wheel.py +++ b/tests/wpt/tests/webdriver/tests/bidi/input/perform_actions/wheel.py @@ -4,6 +4,7 @@ from webdriver.bidi.error import NoSuchFrameException from webdriver.bidi.modules.input import Actions, get_element_origin from webdriver.bidi.modules.script import ContextTarget +from tests.support.keys import Keys from .. import get_events, get_object_from_context from . import get_shadow_root_from_test_page @@ -159,3 +160,28 @@ async def test_scroll_shadow_tree( assert events[0]["deltaX"] >= 5 assert events[0]["deltaY"] >= 10 assert events[0]["target"] == "scrollableShadowTreeContent" + + +async def test_scroll_with_key_pressed( + bidi_session, setup_wheel_test, top_context, get_element +): + scrollable = await get_element("#scrollable") + + actions = Actions() + actions.add_key().key_down(Keys.R_SHIFT) + actions.add_wheel().scroll( + x=0, + y=0, + delta_x=5, + delta_y=10, + origin=get_element_origin(scrollable), + ) + actions.add_key().key_up(Keys.R_SHIFT) + + await bidi_session.input.perform_actions( + actions=actions, context=top_context["context"] + ) + events = await get_events(bidi_session, top_context["context"]) + assert len(events) == 1 + assert events[0]["type"] == "wheel" + assert events[0]["shiftKey"] == True diff --git a/tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py b/tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py index 924a4e8d797..8f832077e10 100644 --- a/tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py +++ b/tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py @@ -87,13 +87,6 @@ def test_stale_element_reference(session, stale_element, as_frame): assert_error(response, "stale element reference") -def test_getting_text_of_a_non_existant_element_is_an_error(session, inline): - session.url = inline("""<body>Hello world</body>""") - - result = get_element_text(session, "foo") - assert_error(result, "no such element") - - def test_read_element_text(session, inline): session.url = inline("Before f<span id='id'>oo</span> after") element = session.find.css("#id", all=False) @@ -102,6 +95,20 @@ def test_read_element_text(session, inline): assert_success(result, "oo") +@pytest.mark.parametrize("text, expected", [ + ("foo bar", "Foo Bar"), + ("foo-bar", "Foo-Bar"), + ("foo_bar", "Foo_bar"), +], ids=["space", "dash", "underscore"]) +def test_transform_capitalize(session, inline, text, expected): + session.url = inline( + f"""<div style="text-transform: capitalize;">{text}""") + element = session.find.css("div", all=False) + + result = get_element_text(session, element.id) + assert_success(result, expected) + + @pytest.mark.parametrize("text, inner_html, expected", [ ("cheese", "<slot><span>foo</span>bar</slot>", "cheese"), ("cheese", "<slot><span>foo</span></slot>bar", "cheesebar"), diff --git a/tests/wpt/tests/webdriver/tests/classic/perform_actions/wheel.py b/tests/wpt/tests/webdriver/tests/classic/perform_actions/wheel.py index a75a84378a6..6d0f9ddb11f 100644 --- a/tests/wpt/tests/webdriver/tests/classic/perform_actions/wheel.py +++ b/tests/wpt/tests/webdriver/tests/classic/perform_actions/wheel.py @@ -4,6 +4,7 @@ from webdriver.error import NoSuchWindowException from tests.classic.perform_actions.support.refine import get_events +from tests.support.keys import Keys def test_null_response_value(session, wheel_chain): @@ -111,3 +112,18 @@ def test_scroll_shadow_tree(session, get_test_page, wheel_chain, mode, nested): assert events[0]["deltaX"] == 5 assert events[0]["deltaY"] == 10 assert events[0]["target"] == "scrollableShadowTreeContent" + + +def test_scroll_with_key_pressed( + session, test_actions_scroll_page, key_chain, wheel_chain +): + scrollable = session.find.css("#scrollable", all=False) + + key_chain.key_down(Keys.R_SHIFT).perform() + wheel_chain.scroll(0, 0, 5, 10, origin=scrollable).perform() + key_chain.key_up(Keys.R_SHIFT).perform() + + events = get_events(session) + assert len(events) == 1 + assert events[0]["type"] == "wheel" + assert events[0]["shiftKey"] == True diff --git a/tests/wpt/tests/webdriver/tests/support/html/test_actions_scroll.html b/tests/wpt/tests/webdriver/tests/support/html/test_actions_scroll.html index db5952ed74d..edeff342fe4 100644 --- a/tests/wpt/tests/webdriver/tests/support/html/test_actions_scroll.html +++ b/tests/wpt/tests/webdriver/tests/support/html/test_actions_scroll.html @@ -63,6 +63,10 @@ "deltaZ": event.deltaZ, "deltaMode": event.deltaMode, "target": event.target.id, + "altKey": event.altKey, + "ctrlKey": event.ctrlKey, + "metaKey": event.metaKey, + "shiftKey": event.shiftKey, }); addMessage( @@ -75,7 +79,11 @@ "deltaY: " + event.deltaY + ", " + "deltaZ: " + event.deltaZ + ", " + "deltaMode: " + event.deltaMode + ", " + - "target id: " + event.target.id + "target id: " + event.target.id + ", " + + "altKey: " + event.altKey + ", " + + "ctrlKey: " + event.ctrlKey + ", " + + "metaKey: " + event.metaKey + ", " + + "shiftKey: " + event.shiftKey ); } @@ -121,7 +129,11 @@ "deltaY": event.deltaY, "deltaZ": event.deltaZ, "deltaMode": event.deltaMode, - "target": event.target + "target": event.target, + "altKey": event.altKey, + "ctrlKey": event.ctrlKey, + "metaKey": event.metaKey, + "shiftKey": event.shiftKey, }); }); </script> diff --git a/tests/wpt/tests/webnn/conformance_tests/buffer.https.any.js b/tests/wpt/tests/webnn/conformance_tests/buffer.https.any.js index 5a09b05c7dc..51804e7224f 100644 --- a/tests/wpt/tests/webnn/conformance_tests/buffer.https.any.js +++ b/tests/wpt/tests/webnn/conformance_tests/buffer.https.any.js @@ -14,6 +14,7 @@ if (navigator.ml) { testDestroyWebNNBuffer('destroyTwice'); testReadWebNNBuffer('read'); testWriteWebNNBuffer('write'); + testDispatchWebNNBuffer('dispatch'); } else { test(() => assert_implements(navigator.ml, 'missing navigator.ml')); } diff --git a/tests/wpt/tests/webnn/resources/test_data/conv_transpose2d.json b/tests/wpt/tests/webnn/resources/test_data/conv_transpose2d.json index 742752fd41d..241faf52633 100644 --- a/tests/wpt/tests/webnn/resources/test_data/conv_transpose2d.json +++ b/tests/wpt/tests/webnn/resources/test_data/conv_transpose2d.json @@ -171,15 +171,15 @@ 0.4307519793510437, 0.7198431491851807, 0.24069452285766602, - 0.023476747795939445, - 0.1003265455365181, - 0.06639400124549866, - 0.20330555737018585, - 0.5576914548873901, - 0.3199329376220703, - 0.3824205696582794, - 0.7745689153671265, - 0.3774891495704651 + 0.2449943870306015, + 0.20362859964370728, + 0.002522633643820882, + 0.9113409519195557, + 0.8747221827507019, + 0.10648936033248901, + 0.6482304930686951, + 0.865131676197052, + 0.2742191553115845 ], "type": "float32" } @@ -240,22 +240,22 @@ 0.5207441449165344, 0.19909898936748505, 0.24069452285766602, - 0.023476747795939445, - 0.08110900968313217, - 0.019217535853385925, - 0.06639400124549866, - 0.13846713304519653, - 0.16739553213119507, - 0.11334607005119324, - 0.13702619075775146, - 0.06483843177556992, - 0.22400806844234467, - 0.05294178053736687, - 0.18290674686431885, - 0.3824205696582794, - 0.4623154401779175, - 0.31225350499153137, - 0.3774891495704651 + 0.2449943870306015, + 0.0030817289371043444, + 0.20054687559604645, + 0.002522633643820882, + 0.23471179604530334, + 0.12160100787878036, + 0.19212977588176727, + 0.09953983873128891, + 0.6766291260719299, + 0.008511164225637913, + 0.5524802207946777, + 0.00694952392950654, + 0.6482304930686951, + 0.3358394503593445, + 0.5292922258377075, + 0.2742191553115845 ], "type": "float32" } diff --git a/tests/wpt/tests/webnn/resources/utils.js b/tests/wpt/tests/webnn/resources/utils.js index e5b80ae9f7f..c231f46bcf5 100644 --- a/tests/wpt/tests/webnn/resources/utils.js +++ b/tests/wpt/tests/webnn/resources/utils.js @@ -880,8 +880,19 @@ const variant = location.search.substring(1); const contextOptions = kContextOptionsForVariant[variant]; /** + * Checks if MLBuffer is implemented or not. + * @param {MLContext} ml_context - A ML context to test for MLBuffer support. + * @returns {Boolean} True if MLBuffer is supported; otherwise, False. + */ +const isMLBufferSupported = + (ml_context) => { + return (createBuffer(ml_context, 4) !== undefined); + } + +/** * Run WebNN operation tests. - * @param {(String[]|String)} operationName - An operation name array or an operation name + * @param {(String[]|String)} operationName - An operation name array or an + * operation name * @param {Function} buildFunc - A build function for an operation */ const testWebNNOperation = (operationName, buildFunc) => { @@ -1384,3 +1395,428 @@ const testReadWebNNBuffer = (testName) => { t, TypeError, another_ml_context.readBuffer(ml_buffer)); }, `${testName} / context_mismatch`); }; + +/** + * WebNN dispatch buffer operation test. + * @param {String} testName - The name of the test operation. + */ +const testDispatchWebNNBuffer = (testName) => { + let ml_context; + let ml_graph; + const shape = [3, 5]; + let inputs = {}; + let outputs = {}; + promise_setup(async () => { + let supported = false; + try { + ml_context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); + // Construct a simple graph: A = B + C, with two outputs. + const builder = new MLGraphBuilder(ml_context); + const operandType = {dataType: 'float32', dimensions: shape}; + const lhs_operand = builder.input('lhs', operandType); + const rhs_operand = builder.input('rhs', operandType); + const output_1_operand = builder.add(lhs_operand, rhs_operand); + const output_2_operand = builder.add(lhs_operand, rhs_operand); + ml_graph = await builder.build( + {'output1': output_1_operand, 'output2': output_2_operand}); + const ml_buffer_size = + TypedArrayDict['float32'].BYTES_PER_ELEMENT * sizeOfShape(shape); + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + inputs = { + 'lhs': ml_context.createBuffer({size: ml_buffer_size}), + 'rhs': ml_context.createBuffer({size: ml_buffer_size}), + }; + outputs = { + 'output1': ml_context.createBuffer({size: ml_buffer_size}), + 'output2': ml_context.createBuffer({size: ml_buffer_size}), + }; + }); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + let another_ml_context = await navigator.ml.createContext(contextOptions); + + // Control case, same context. + ml_context.dispatch(ml_graph, inputs, outputs); + + // Test the wrong context being used for inputs. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': + another_ml_context.createBuffer({size: inputs['lhs'].size()}), + 'rhs': inputs['rhs'], + }, + outputs)); + + // Test the wrong context being used for outputs. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': + another_ml_context.createBuffer({size: outputs['output1'].size()}), + 'output2': outputs['output2'], + })); + }, `${testName} / context_mismatch`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + // Control case, valid size. + ml_context.dispatch(ml_graph, inputs, outputs); + + // Input is too large. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size() + 1}), + 'rhs': inputs['rhs'], + }, + outputs)); + + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': inputs['lhs'], + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size() + 1}), + }, + outputs)); + + // Output is too large. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': ml_context.createBuffer({size: outputs['output1'].size() + 1}), + 'output2': outputs['output2'], + })); + + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': outputs['output1'], + 'output2': ml_context.createBuffer({size: outputs['output2'].size() + 1}), + })); + }, `${testName} / invalid_size`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + // Control case, valid names. + ml_context.dispatch(ml_graph, inputs, outputs); + + // No names is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, {}, {})); + + // Input name is invalid. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'a_different_input_name': inputs['lhs'], + 'rhs': inputs['rhs'], + }, + outputs)); + + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': inputs['lhs'], + 'a_different_input_name': inputs['rhs'], + }, + outputs)); + + // Output name is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'a_different_output_name': outputs['output1'], + 'output2': outputs['output2'], + })); + + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': outputs['output1'], + 'a_different_output_name': outputs['output2'], + })); + + // Too few named inputs is invalid. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': inputs['lhs'], + }, + outputs)); + + // Too many named inputs is invalid. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': inputs['lhs'], + 'rhs': inputs['rhs'], + 'a_different_input_name': + ml_context.createBuffer({size: inputs['rhs'].size()}), + }, + outputs)); + + // Too few named outputs is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': outputs['output1'] + })); + + // Too many named outputs is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': outputs['output1'], + 'output2': outputs['output2'], + 'a_different_output_name': + ml_context.createBuffer({size: outputs['output2'].size()}), + })); + }, `${testName} / invalid_name`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + // Control case, valid buffers. + ml_context.dispatch(ml_graph, inputs, outputs); + + // Same buffer used as outputs more than once is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': outputs['output1'], + 'output2': outputs['output1'], + })); + + // Same buffer used as input and output is invalid. + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': inputs['lhs'], + 'output2': outputs['output2'], + })); + + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': outputs['output1'], + 'rhs': inputs['rhs'], + }, + outputs)); + + // Buffer that does not exist is invalid. + assert_throws_js( + TypeError, + () => ml_context.dispatch( + ml_graph, { + 'lhs': undefined, + 'rhs': inputs['rhs'], + }, + outputs)); + + assert_throws_js(TypeError, () => ml_context.dispatch(ml_graph, inputs, { + 'output1': undefined, + 'output2': outputs['output2'], + })); + }, `${testName} / invalid_buffer`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + const dispatch_inputs = { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size}), + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size}), + }; + + const dispatch_1_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + const dispatch_2_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + // Initialize inputs + const input_data = + new TypedArrayDict['float32'](sizeOfShape(shape)).fill(1.0); + ml_context.writeBuffer(dispatch_inputs['lhs'], input_data); + ml_context.writeBuffer(dispatch_inputs['rhs'], input_data); + + // Output_1 = LHS + RHS = 1 + 1 = 2 + ml_context.dispatch(ml_graph, dispatch_inputs, dispatch_1_outputs); + + // Output_2 = LHS + RHS = 1 + 1 = 2 + ml_context.dispatch(ml_graph, dispatch_inputs, dispatch_2_outputs); + + await assert_buffer_data_equals( + ml_context, dispatch_1_outputs['output1'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + + await assert_buffer_data_equals( + ml_context, dispatch_1_outputs['output2'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + + await assert_buffer_data_equals( + ml_context, dispatch_2_outputs['output1'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + + await assert_buffer_data_equals( + ml_context, dispatch_2_outputs['output2'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + }, `${testName} / same_inputs`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + const dispatch_1_inputs = { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size}), + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size}), + }; + + const dispatch_2_inputs = { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size}), + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size}), + }; + + const dispatch_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + // Initialize inputs + const input_1_data = + new TypedArrayDict['float32'](sizeOfShape(shape)).fill(1.0); + ml_context.writeBuffer(dispatch_1_inputs['lhs'], input_1_data); + ml_context.writeBuffer(dispatch_1_inputs['rhs'], input_1_data); + + const input_2_data = + new TypedArrayDict['float32'](sizeOfShape(shape)).fill(2.0); + ml_context.writeBuffer(dispatch_2_inputs['lhs'], input_2_data); + ml_context.writeBuffer(dispatch_2_inputs['rhs'], input_2_data); + + // Output = LHS_1 + RHS_1 = 1 + 1 = 2 + ml_context.dispatch(ml_graph, dispatch_1_inputs, dispatch_outputs); + + // Output = LHS_2 + RHS_2 = 2 + 2 = 4 + ml_context.dispatch(ml_graph, dispatch_2_inputs, dispatch_outputs); + + await assert_buffer_data_equals( + ml_context, dispatch_outputs['output1'], + new Float32Array(sizeOfShape(shape)).fill(4.0)); + + await assert_buffer_data_equals( + ml_context, dispatch_outputs['output2'], + new Float32Array(sizeOfShape(shape)).fill(4.0)); + }, `${testName} / same_outputs`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + const dispatch_inputs = { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size}), + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size}), + }; + + const dispatch_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + // Initialize inputs + const input_data = + new TypedArrayDict['float32'](sizeOfShape(shape)).fill(1.0); + ml_context.writeBuffer(dispatch_inputs['lhs'], input_data); + ml_context.writeBuffer(dispatch_inputs['rhs'], input_data); + + // Output = LHS + RHS = 1 + 1 = 2 + ml_context.dispatch(ml_graph, dispatch_inputs, dispatch_outputs); + ml_context.dispatch(ml_graph, dispatch_inputs, dispatch_outputs); + + await assert_buffer_data_equals( + ml_context, dispatch_outputs['output1'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + + await assert_buffer_data_equals( + ml_context, dispatch_outputs['output2'], + new Float32Array(sizeOfShape(shape)).fill(2.0)); + }, `${testName} / same_inputs_and_outputs`); + + promise_test(async () => { + // MLBuffer was unsupported for the deviceType. + if (!isMLBufferSupported(ml_context)) { + return; + } + + const dispatch_inputs = { + 'lhs': ml_context.createBuffer({size: inputs['lhs'].size}), + 'rhs': ml_context.createBuffer({size: inputs['rhs'].size}), + }; + + const dispatch_1_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + const dispatch_2_outputs = { + 'output1': ml_context.createBuffer({size: outputs['output1'].size}), + 'output2': ml_context.createBuffer({size: outputs['output2'].size}), + }; + + // Initialize inputs + const input_data = + new TypedArrayDict['float32'](sizeOfShape(shape)).fill(1.0); + ml_context.writeBuffer(dispatch_inputs['lhs'], input_data); + ml_context.writeBuffer(dispatch_inputs['rhs'], input_data); + + // Output_1 = LHS + RHS = 1 + 1 = 2 + ml_context.dispatch(ml_graph, dispatch_inputs, dispatch_1_outputs); + + // Output_2 = Output_1_LHS + Output_1_RHS = 2 + 2 = 4 + ml_context.dispatch( + ml_graph, { + 'lhs': dispatch_1_outputs['output1'], + 'rhs': dispatch_1_outputs['output2'], + }, + dispatch_2_outputs); + + // Output_1 = Output_2_LHS + Output_2_RHS = 4 + 4 = 8 + ml_context.dispatch( + ml_graph, { + 'lhs': dispatch_2_outputs['output1'], + 'rhs': dispatch_2_outputs['output2'], + }, + dispatch_1_outputs); + + await assert_buffer_data_equals( + ml_context, dispatch_1_outputs['output1'], + new Float32Array(sizeOfShape(shape)).fill(8)); + + await assert_buffer_data_equals( + ml_context, dispatch_1_outputs['output2'], + new Float32Array(sizeOfShape(shape)).fill(8)); + }, `${testName} / outputs_as_inputs`); +}; diff --git a/tests/wpt/tests/webnn/validation_tests/elementwise-unary.https.any.js b/tests/wpt/tests/webnn/validation_tests/elementwise-unary.https.any.js index f87c61b4e45..c735183aab1 100644 --- a/tests/wpt/tests/webnn/validation_tests/elementwise-unary.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/elementwise-unary.https.any.js @@ -16,14 +16,14 @@ kElementwiseUnaryOperators.forEach((operatorName) => { const kElementwiseUnaryOperations = [ { name: 'abs', - supportedDataTypes: [...floatingPointTypes, ...signedIntegerTypes] + supportedDataTypes: [...floatingPointTypes, 'int32', 'int8'] }, {name: 'ceil', supportedDataTypes: floatingPointTypes}, {name: 'exp', supportedDataTypes: floatingPointTypes}, {name: 'floor', supportedDataTypes: floatingPointTypes}, {name: 'log', supportedDataTypes: floatingPointTypes}, { name: 'neg', - supportedDataTypes: [...floatingPointTypes, ...signedIntegerTypes] + supportedDataTypes: [...floatingPointTypes, 'int32', 'int8'] }, {name: 'sin', supportedDataTypes: floatingPointTypes}, {name: 'tan', supportedDataTypes: floatingPointTypes}, diff --git a/tests/wpt/tests/webnn/validation_tests/pooling.https.any.js b/tests/wpt/tests/webnn/validation_tests/pooling.https.any.js index e8add0511f9..08a78f25baf 100644 --- a/tests/wpt/tests/webnn/validation_tests/pooling.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/pooling.https.any.js @@ -11,7 +11,6 @@ kPoolingOperators.forEach((operatorName) => { operatorName, {dataType: 'float32', dimensions: [2, 2, 2, 2]}); }); - const tests = [ { name: 'Test pool2d with default options.', @@ -20,11 +19,11 @@ const tests = [ }, { name: 'Test pool2d with windowDimensions', - input: {dataType: 'float32', dimensions: [1, 3, 4, 4]}, + input: {dataType: 'float16', dimensions: [1, 3, 4, 4]}, options: { windowDimensions: [3, 3], }, - output: {dataType: 'float32', dimensions: [1, 3, 2, 2]} + output: {dataType: 'float16', dimensions: [1, 3, 2, 2]} }, { name: 'Test pool2d with padding.', @@ -37,12 +36,12 @@ const tests = [ }, { name: 'Test pool2d with strides.', - input: {dataType: 'float32', dimensions: [1, 3, 5, 5]}, + input: {dataType: 'float16', dimensions: [1, 3, 5, 5]}, options: { windowDimensions: [2, 2], strides: [2, 2], }, - output: {dataType: 'float32', dimensions: [1, 3, 2, 2]} + output: {dataType: 'float16', dimensions: [1, 3, 2, 2]} }, { name: 'Test pool2d with strides and padding.', @@ -77,14 +76,14 @@ const tests = [ }, { name: 'Test pool2d with strides, padding and roundingType="ceil".', - input: {dataType: 'float32', dimensions: [1, 3, 7, 7]}, + input: {dataType: 'float16', dimensions: [1, 3, 7, 7]}, options: { windowDimensions: [4, 4], padding: [1, 1, 1, 1], strides: [2, 2], roundingType: 'ceil', }, - output: {dataType: 'float32', dimensions: [1, 3, 4, 4]} + output: {dataType: 'float16', dimensions: [1, 3, 4, 4]} }, { name: 'Test pool2d with explicit outputSizes ignored roundingType', @@ -131,12 +130,12 @@ const tests = [ }, { name: 'Test pool2d with layout="nhwc".', - input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + input: {dataType: 'float16', dimensions: [1, 5, 5, 2]}, options: { windowDimensions: [3, 3], layout: 'nhwc', }, - output: {dataType: 'float32', dimensions: [1, 3, 3, 2]} + output: {dataType: 'float16', dimensions: [1, 3, 3, 2]} }, { name: 'Throw if the input is not a 4-D tensor.', @@ -273,3 +272,24 @@ tests.forEach( } }); }, test.name)); + +['int32', 'uint32', 'int8', 'uint8'].forEach( + dataType => promise_test(async t => { + const input = builder.input( + 'input', {dataType: dataType, dimensions: [1, 3, 4, 4]}); + const output = builder.maxPool2d(input); + assert_equals(output.dataType(), dataType); + assert_array_equals(output.shape(), [1, 3, 1, 1]); + }, `[maxPool2d] Test maxPool2d with data type ${dataType}`)); + +promise_test(async t => { + const input = + builder.input('input', {dataType: 'int64', dimensions: [1, 2, 3, 3]}); + assert_throws_js(TypeError, () => builder.averagePool2d(input)); +}, '[averagePool2d] Throw if the input data type is not floating point'); + +promise_test(async t => { + const input = + builder.input('input', {dataType: 'uint8', dimensions: [1, 2, 4, 4]}); + assert_throws_js(TypeError, () => builder.l2Pool2d(input)); +}, '[l2Pool2d] Throw if the input data type is not floating point'); diff --git a/tests/wpt/tests/webnn/validation_tests/prelu.https.any.js b/tests/wpt/tests/webnn/validation_tests/prelu.https.any.js index 865f9f684c1..fa89df9631b 100644 --- a/tests/wpt/tests/webnn/validation_tests/prelu.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/prelu.https.any.js @@ -5,3 +5,87 @@ 'use strict'; validateTwoInputsFromMultipleBuilders('prelu'); + +const tests = [ + { + name: + '[prelu] Test slope\'s shape = [3, 2, 5] which is the same as input\'s shape.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'float32', dimensions: [3, 2, 5]}, + output: {dataType: 'float32', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Test slope\'s shape = [5] which is unidirectionally broadcastable to input\'s shape.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'float32', dimensions: [5]}, + output: {dataType: 'float32', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Test slope\'s shape = [] which is unidirectionally broadcastable to input\'s shape.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'float32', dimensions: []}, + output: {dataType: 'float32', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Test slope\'s shape = [2, 5] which is unidirectionally broadcastable to input\'s shape.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'float32', dimensions: [2, 5]}, + output: {dataType: 'float32', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Test with input\'s dataType = int32 and slope\'s dataType = int32.', + input: {dataType: 'int32', dimensions: [3, 2, 5]}, + slope: {dataType: 'int32', dimensions: [2, 5]}, + output: {dataType: 'int32', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Test with input\'s dataType = int8 and slope\'s dataType = int8.', + input: {dataType: 'int8', dimensions: [3, 2, 5]}, + slope: {dataType: 'int8', dimensions: [2, 5]}, + output: {dataType: 'int8', dimensions: [3, 2, 5]}, + }, + { + name: + '[prelu] Throw if the shape of slope is not broadcastable to the shape of input.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'float32', dimensions: [2]}, + }, + { + name: + '[prelu] Throw if the data type of slope does not match the data type of input.', + input: {dataType: 'float32', dimensions: [3, 2, 5]}, + slope: {dataType: 'int32', dimensions: [3, 2, 5]}, + }, + { + name: '[prelu] Throw if the data type of input is int64.', + input: {dataType: 'int64', dimensions: [3, 2, 5]}, + slope: {dataType: 'int64', dimensions: [3, 2, 5]}, + }, + { + name: '[prelu] Throw if the data type of input is uint32.', + input: {dataType: 'uint32', dimensions: [3, 2, 5]}, + slope: {dataType: 'uint32', dimensions: [3, 2, 5]}, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + const slope = builder.input( + 'input', + {dataType: test.slope.dataType, dimensions: test.slope.dimensions}); + if (test.output) { + const output = builder.prelu(input, slope); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js(TypeError, () => builder.prelu(input, slope)); + } + }, test.name)); diff --git a/tests/wpt/tests/webnn/validation_tests/reduction.https.any.js b/tests/wpt/tests/webnn/validation_tests/reduction.https.any.js index 60f09786788..7da6b24dcf0 100644 --- a/tests/wpt/tests/webnn/validation_tests/reduction.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/reduction.https.any.js @@ -17,7 +17,111 @@ const kReductionOperators = [ 'reduceSumSquare', ]; +const kFloatRestrictReductionOperators = [ + 'reduceL2', + 'reduceLogSum', + 'reduceLogSumExp', + 'reduceMean', +]; + +const kFloatAllowReductionOperators = [ + 'reduceL1', + 'reduceMax', + 'reduceMin', + 'reduceProduct', + 'reduceSum', + 'reduceSumSquare', +]; + +const allReductionOperatorsTests = [ + { + name: '[reduce] Test reduce with default options.', + input: {dataType: 'float32', dimensions: [1, 3, 4, 4]}, + output: {dataType: 'float32', dimensions: []} + }, + { + name: '[reduce] Test reduce when input\'s datatype is float16.', + input: {dataType: 'float16', dimensions: [1, 3, 4, 4]}, + output: {dataType: 'float16', dimensions: []} + }, + { + name: '[reduce] Test reduce with keepDimensions=true.', + input: {dataType: 'float32', dimensions: [1, 3, 4, 4]}, + options: { + keepDimensions: true, + }, + output: {dataType: 'float32', dimensions: [1, 1, 1, 1]} + }, + { + name: '[reduce] Test reduce with axes=[0, 1] and keep_dimensions=false.', + input: {dataType: 'float32', dimensions: [1, 3, 5, 5]}, + options: {axes: [0, 1]}, + output: {dataType: 'float32', dimensions: [5, 5]} + }, + { + name: '[reduce] Throw if a value in axes is out of range of [0, N-1].', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + axes: [4], + }, + }, + { + name: '[reduce] Throw if the two values are same in axes sequence.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + axes: [0, 1, 1], + }, + }, +]; + +const kFloatRestrictOperatorsTests = [ + { + name: + '[reduce] Throw if the input data type is not one of the floating point.', + input: {dataType: 'int32', dimensions: [1, 2, 5, 5]}, + options: { + axes: [0, 1], + }, + }, +]; + +const kFloatAllowOperatorsTests = [ + { + name: + '[reduce] Test when the input data type is not one of the floating point.', + input: {dataType: 'int32', dimensions: [1, 3, 4, 4]}, + output: {dataType: 'int32', dimensions: []} + }, +]; + +function runReductionTests(operatorName, tests) { + tests.forEach(test => { + promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + + if (test.output) { + const output = builder[operatorName](input, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder[operatorName](input, test.options)); + } + }, test.name.replace('[reduce]', `[${operatorName}]`)); + }); +} + kReductionOperators.forEach((operatorName) => { - validateOptionsAxes(operatorName); validateInputFromAnotherBuilder(operatorName); + runReductionTests(operatorName, allReductionOperatorsTests); +}); + +kFloatRestrictReductionOperators.forEach((operatorName) => { + runReductionTests(operatorName, kFloatRestrictOperatorsTests); +}); + +kFloatAllowReductionOperators.forEach((operatorName) => { + runReductionTests(operatorName, kFloatAllowOperatorsTests); }); diff --git a/tests/wpt/tests/webnn/validation_tests/relu.https.any.js b/tests/wpt/tests/webnn/validation_tests/relu.https.any.js index 237c1c3eda3..61b0d1938fe 100644 --- a/tests/wpt/tests/webnn/validation_tests/relu.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/relu.https.any.js @@ -7,4 +7,4 @@ validateInputFromAnotherBuilder('relu'); validateUnaryOperation( - 'relu', allWebNNOperandDataTypes, /*alsoBuildActivation=*/ true); + 'relu', [...floatingPointTypes, 'int32', 'int8'], /*alsoBuildActivation=*/ true); diff --git a/tests/wpt/tests/webnn/validation_tests/resample2d.https.any.js b/tests/wpt/tests/webnn/validation_tests/resample2d.https.any.js index de44c6a333a..cc52cf97f4f 100644 --- a/tests/wpt/tests/webnn/validation_tests/resample2d.https.any.js +++ b/tests/wpt/tests/webnn/validation_tests/resample2d.https.any.js @@ -25,6 +25,13 @@ const tests = [ }, { name: + '[resample2d] Test building resample2d with input\'s dataType = float16', + input: {dataType: 'float16', dimensions: [1, 1, 5, 5]}, + options: {scales: [0.5, 0.5]}, + output: {dataType: 'float16', dimensions: [1, 1, 2, 2]}, + }, + { + name: '[resample2d] Test building resample2d with scales=[0.5, 0.5] and explicit axes=[2, 3]', input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, options: {scales: [0.5, 0.5], axes: [2, 3]}, @@ -52,6 +59,11 @@ const tests = [ output: {dataType: 'float32', dimensions: [1, 1, 3, 6]}, }, { + name: + '[resample2d] Throw if the dataType of input is not float32 or float16', + input: {dataType: 'int32', dimensions: [2, 4]}, + }, + { name: '[resample2d] Throw if the rank of input is not 4', input: {dataType: 'float32', dimensions: [2, 4]}, }, @@ -76,6 +88,11 @@ const tests = [ options: {sizes: [1, 1, 4, 6]}, }, { + name: '[resample2d] Throw if input data type is not floating type', + input: {dataType: 'int32', dimensions: [1, 1, 2, 4]}, + options: {sizes: [1, 1, 4, 6]}, + }, + { name: '[resample2d] Throw if any size value is out of \'unsigned long\' value range', input: {dataType: 'float32', dimensions: [1, 1, 2, 4]}, diff --git a/tests/wpt/tests/webrtc/RTCPeerConnection-createAnswer.html b/tests/wpt/tests/webrtc/RTCPeerConnection-createAnswer.html index 1970db0737a..7e31dda6290 100644 --- a/tests/wpt/tests/webrtc/RTCPeerConnection-createAnswer.html +++ b/tests/wpt/tests/webrtc/RTCPeerConnection-createAnswer.html @@ -18,14 +18,14 @@ promise_test(async t => { const pc = new RTCPeerConnection(); t.add_cleanup(() => pc.close()); - const offer = await generateVideoReceiveOnlyOffer(pc); + const offer = await pc.createOffer(); await pc.setRemoteDescription(offer); const answer = await pc.createAnswer(); assert_equals(typeof answer, 'object', - 'Expect answer to be plain object dictionary RTCSessionDescriptionInit'); + 'Expect answer to be plain object (dictionary RTCSessionDescriptionInit)'); assert_false(answer instanceof RTCSessionDescription, 'Expect answer to not be instance of RTCSessionDescription'); -}, 'createAnswer() after setting remote description should succeed'); +}, 'createAnswer() returns RTCSessionDescriptionInit'); promise_test(async t => { const pc = new RTCPeerConnection(); diff --git a/tests/wpt/tests/webrtc/RTCPeerConnection-createOffer.html b/tests/wpt/tests/webrtc/RTCPeerConnection-createOffer.html index 7287980a5b4..4eabdffa04a 100644 --- a/tests/wpt/tests/webrtc/RTCPeerConnection-createOffer.html +++ b/tests/wpt/tests/webrtc/RTCPeerConnection-createOffer.html @@ -25,20 +25,17 @@ * with its type member initialized to the string "offer" and its sdp member * initialized to sdpString. */ - promise_test(t => { + promise_test(async t => { const pc = new RTCPeerConnection() - t.add_cleanup(() => pc.close()); - return pc.createOffer() - .then(offer => { - assert_equals(typeof offer, 'object', - 'Expect offer to be plain object dictionary RTCSessionDescriptionInit'); + const offer = await pc.createOffer() + assert_equals(typeof offer, 'object', + 'Expect offer to be plain object (dictionary RTCSessionDescriptionInit)'); - assert_false(offer instanceof RTCSessionDescription, - 'Expect offer to not be instance of RTCSessionDescription') - }); - }, 'createOffer() with no argument from newly created RTCPeerConnection should succeed'); + assert_false(offer instanceof RTCSessionDescription, + 'Expect offer to not be instance of RTCSessionDescription') + }, 'createOffer() returns RTCSessionDescriptionInit'); promise_test(t => { const pc = new RTCPeerConnection(); diff --git a/tests/wpt/tests/webrtc/WEB_FEATURES.yml b/tests/wpt/tests/webrtc/WEB_FEATURES.yml new file mode 100644 index 00000000000..117b04f81fe --- /dev/null +++ b/tests/wpt/tests/webrtc/WEB_FEATURES.yml @@ -0,0 +1,4 @@ +features: +- name: webrtc-sctp + files: + - RTCSctpTransport-* diff --git a/tests/wpt/tests/webvtt/parsing/cue-text-parsing/tests/tree-building.html b/tests/wpt/tests/webvtt/parsing/cue-text-parsing/tests/tree-building.html index 6cd617decef..06bc8b9d62d 100644 --- a/tests/wpt/tests/webvtt/parsing/cue-text-parsing/tests/tree-building.html +++ b/tests/wpt/tests/webvtt/parsing/cue-text-parsing/tests/tree-building.html @@ -18,6 +18,7 @@ runTests([ {name:'325c1e590e74f1ff33ca5b4838c04cf6b6dd71ba', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C/rt%3E%3C/ruby%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%20%20%20%20%20%20%22test%22'}, {name:'92847ed2694c9639ba96f4cc61e2215362a74904', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C/ruby%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%20%20%20%20%20%20%22test%22'}, {name:'c0da62d1c8716ca544c96799f06ac7e4664500fb', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C/rt%3E%3C/ruby%3E%3C/b%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%20%20%20%20%22test%22'}, -{name:'b85bd616672eba0591718182ef32e3307d223bb0', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C/rt%3E%3C/b%3E%3C/ruby%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%22test%22'} +{name:'b85bd616672eba0591718182ef32e3307d223bb0', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C/rt%3E%3C/b%3E%3C/ruby%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%22test%22'}, +{name:'421c76d77563afa1914846b010bd164f395bd34c', input:'%3Cruby%3Etest%3Crt%3E%3Cb%3Etest%3C%2Frt%3E%3C%2Fb%3Etest%3C%2Fruby%3Etest', expected:'%23document-fragment%0A%7C%20%3Cruby%3E%0A%7C%20%20%20%22test%22%0A%7C%20%20%20%3Crt%3E%0A%7C%20%20%20%20%20%3Cb%3E%0A%7C%20%20%20%20%20%20%20%22test%22%0A%7C%20%20%20%20%20%22test%22%0A%7C%20%22test%22'} ]); </script> diff --git a/tests/wpt/tests/workers/modules/WEB_FEATURES.yml b/tests/wpt/tests/workers/modules/WEB_FEATURES.yml new file mode 100644 index 00000000000..ab73efc0d04 --- /dev/null +++ b/tests/wpt/tests/workers/modules/WEB_FEATURES.yml @@ -0,0 +1,7 @@ +features: +- name: js-modules-workers + files: + - dedicated-worker-* +- name: js-modules-shared-workers + files: + - shared-worker-* |