aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorServo WPT Sync <32481905+servo-wpt-sync@users.noreply.github.com>2024-02-17 23:56:46 -0500
committerGitHub <noreply@github.com>2024-02-18 04:56:46 +0000
commit6c67fa8b9e856c25d4167bbf7c85b28c20afc14e (patch)
tree6d3c16972363f3f2c8f78985f8906f5e6be04da4
parentc999d4546c7dbfee670da38553dd95929c05b82b (diff)
downloadservo-6c67fa8b9e856c25d4167bbf7c85b28c20afc14e.tar.gz
servo-6c67fa8b9e856c25d4167bbf7c85b28c20afc14e.zip
Update web-platform-tests to revision b'504dbb9401e985461bdc3fb534cb26fd5bb9d9ad' (#31372)
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini144
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-color-mix-function.html.ini24
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-hsl.html.ini9
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini144
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini144
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-cascade.html.ini1
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-rule-none.html.ini1
-rw-r--r--tests/wpt/meta-legacy-layout/css/css-variables/variables-animation-math-functions-tentative.html.ini108
-rw-r--r--tests/wpt/meta-legacy-layout/css/cssom-view/scroll-behavior-smooth-navigation.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/css/cssom/getComputedStyle-pseudo-with-argument.html.ini15
-rw-r--r--tests/wpt/meta-legacy-layout/css/mediaqueries/display-mode.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-005.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-006.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/dom/events/webkit-transition-end-event.html.ini14
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini (renamed from tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini)2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini (renamed from tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini)2
-rw-r--r--tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/about-srcdoc-navigation-blocked.window.js.ini1
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigate-to-unparseable-url.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/canvas/element/manual/text/canvas.2d.disconnected.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-assorted.window.js.ini6
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-shadow-42.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini9
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/html/semantics/popovers/popover-open-overflow-display-2.html.ini18
-rw-r--r--tests/wpt/meta-legacy-layout/resource-timing/test_resource_timing.https.html.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini4
-rw-r--r--tests/wpt/meta-legacy-layout/workers/constructors/Worker/Worker-constructor.html.ini2
-rw-r--r--tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini3
-rw-r--r--tests/wpt/meta-legacy-layout/xhr/xhr-timeout-longtask.any.js.ini6
-rw-r--r--tests/wpt/meta/MANIFEST.json1191
-rw-r--r--tests/wpt/meta/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini144
-rw-r--r--tests/wpt/meta/css/css-color/parsing/color-computed-color-mix-function.html.ini24
-rw-r--r--tests/wpt/meta/css/css-color/parsing/color-valid-hsl.html.ini9
-rw-r--r--tests/wpt/meta/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini144
-rw-r--r--tests/wpt/meta/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini144
-rw-r--r--tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini12
-rw-r--r--tests/wpt/meta/css/css-transitions/starting-style-cascade.html.ini1
-rw-r--r--tests/wpt/meta/css/css-transitions/starting-style-rule-none.html.ini1
-rw-r--r--tests/wpt/meta/css/css-variables/variables-animation-math-functions-tentative.html.ini108
-rw-r--r--tests/wpt/meta/css/cssom/getComputedStyle-pseudo-with-argument.html.ini15
-rw-r--r--tests/wpt/meta/css/mediaqueries/display-mode.html.ini3
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-001.html.ini2
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-002.html.ini2
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-003.html.ini2
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-004.html.ini2
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-005.html.ini2
-rw-r--r--tests/wpt/meta/css/selectors/has-style-sharing-pseudo-006.html.ini2
-rw-r--r--tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini3
-rw-r--r--tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini (renamed from tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini)2
-rw-r--r--tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini (renamed from tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini)2
-rw-r--r--tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.js.ini6
-rw-r--r--tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini3
-rw-r--r--tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini2
-rw-r--r--tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini2
-rw-r--r--tests/wpt/meta/html/dom/elements/global-attributes/dir-assorted.window.js.ini6
-rw-r--r--tests/wpt/meta/html/dom/elements/global-attributes/dir-shadow-42.html.ini2
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/editing/editing-0/writing-suggestions/writingsuggestions.html.ini222
-rw-r--r--tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini5
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini4
-rw-r--r--tests/wpt/meta/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/popovers/popover-open-overflow-display-2.html.ini18
-rw-r--r--tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/remove-initial-about-blankness.window.js.ini3
-rw-r--r--tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini2
-rw-r--r--tests/wpt/meta/resource-timing/content-type-parsing.html.ini4
-rw-r--r--tests/wpt/meta/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini3
-rw-r--r--tests/wpt/meta/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini3
-rw-r--r--tests/wpt/mozilla/meta-legacy-layout/mozilla/service-workers/service-worker-registration.https.html.ini1
-rw-r--r--tests/wpt/tests/.taskcluster.yml2
-rw-r--r--tests/wpt/tests/IndexedDB/back-forward-cache-open-connection.window.js4
-rw-r--r--tests/wpt/tests/clipboard-apis/clipboard-item.https.html6
-rw-r--r--tests/wpt/tests/css/css-anchor-position/anchor-position-auto-001.html71
-rw-r--r--tests/wpt/tests/css/css-anchor-position/anchor-position-auto-002.html200
-rw-r--r--tests/wpt/tests/css/css-anchor-position/anchor-position-auto-003.html168
-rw-r--r--tests/wpt/tests/css/css-anchor-position/anchor-position-auto-004.html60
-rw-r--r--tests/wpt/tests/css/css-anchor-position/parsing/position-try-parsing.html44
-rw-r--r--tests/wpt/tests/css/css-borders/border-image-width-interpolation-math-functions-tentative.html46
-rw-r--r--tests/wpt/tests/css/css-break/out-of-flow-in-multicolumn-117.html14
-rw-r--r--tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html21
-rw-r--r--tests/wpt/tests/css/css-color/parsing/color-valid-hsl.html6
-rw-r--r--tests/wpt/tests/css/css-flexbox/negative-overflow-002.html10
-rw-r--r--tests/wpt/tests/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html47
-rw-r--r--tests/wpt/tests/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html46
-rw-r--r--tests/wpt/tests/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html8
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length1.html27
-rw-r--r--tests/wpt/tests/css/css-multicol/multicol-fill-balance-029.html10
-rw-r--r--tests/wpt/tests/css/css-overflow/scroller-covered-by-empty-svg.html53
-rw-r--r--tests/wpt/tests/css/css-page/cssom/page-001.html41
-rw-r--r--tests/wpt/tests/css/css-page/cssom/page-002.html37
-rw-r--r--tests/wpt/tests/css/css-pseudo/chrome-first-letter-container-query-crash.html27
-rw-r--r--tests/wpt/tests/css/css-pseudo/first-letter-with-before-after-ref.html5
-rw-r--r--tests/wpt/tests/css/css-pseudo/first-letter-with-before-after.html12
-rw-r--r--tests/wpt/tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/prefer-inner-target.html148
-rw-r--r--tests/wpt/tests/css/css-text/crashtests/eol-spaces-bidi-min-content-crash.html12
-rw-r--r--tests/wpt/tests/css/css-transitions/starting-style-cascade.html4
-rw-r--r--tests/wpt/tests/css/css-transitions/starting-style-rule-none.html4
-rw-r--r--tests/wpt/tests/css/css-transitions/support/helper.js6
-rw-r--r--tests/wpt/tests/css/css-variables/variables-animation-math-functions-tentative.html52
-rw-r--r--tests/wpt/tests/css/css-view-transitions/class-specificity-ref.html17
-rw-r--r--tests/wpt/tests/css/css-view-transitions/class-specificity.html54
-rw-r--r--tests/wpt/tests/css/css-view-transitions/pseudo-element-animations.html36
-rw-r--r--tests/wpt/tests/css/cssom/getComputedStyle-pseudo-with-argument.html56
-rw-r--r--tests/wpt/tests/css/mediaqueries/display-mode.html1
-rw-r--r--tests/wpt/tests/css/motion/animation/offset-rotate-interpolation-math-functions-tentative.html47
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001.html20
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002.html20
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003.html21
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004.html21
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005.html20
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006.html20
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007.html20
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008-ref.html19
-rw-r--r--tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008.html20
-rw-r--r--tests/wpt/tests/document-picture-in-picture/display-mode.https.html18
-rw-r--r--tests/wpt/tests/document-picture-in-picture/focus-opener.https.html36
-rw-r--r--tests/wpt/tests/document-picture-in-picture/support/focus-opener.js3
-rw-r--r--tests/wpt/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html11
-rw-r--r--tests/wpt/tests/editing/edit-context/edit-context-basics.tentative.html13
-rw-r--r--tests/wpt/tests/editing/other/paste-in-list-with-inline-style.tentative.html30
-rw-r--r--tests/wpt/tests/event-timing/interactionid-composition-manual.html162
-rw-r--r--tests/wpt/tests/event-timing/interactionid-keypress.html39
-rw-r--r--tests/wpt/tests/event-timing/modal-dialog-interrupt-paint.html38
-rw-r--r--tests/wpt/tests/fenced-frame/resources/unreached.https.html15
-rw-r--r--tests/wpt/tests/fenced-frame/resources/utils.js5
-rw-r--r--tests/wpt/tests/fenced-frame/revoke-popup.https.html47
-rw-r--r--tests/wpt/tests/fenced-frame/revoke-unfenced-top-navigation.https.html47
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html26
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html (renamed from tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html)0
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.html (renamed from tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html)0
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.https.html61
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/resources/empty.html1
-rw-r--r--tests/wpt/tests/fetch/security/dangling-markup/service-worker.js35
-rw-r--r--tests/wpt/tests/fledge/tentative/auction-config.https.window.js77
-rw-r--r--tests/wpt/tests/fledge/tentative/component-auction.https.window.js2
-rw-r--r--tests/wpt/tests/fledge/tentative/cross-origin.https.window.js4
-rw-r--r--tests/wpt/tests/fledge/tentative/direct-from-seller-signals.https.window.js56
-rw-r--r--tests/wpt/tests/fledge/tentative/generate-bid-browser-signals.https.window.js147
-rw-r--r--tests/wpt/tests/fledge/tentative/generate-bid-recency.https.window.js34
-rw-r--r--tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js12
-rw-r--r--tests/wpt/tests/fledge/tentative/kanon-status-below-threshold.https.window.js2
-rw-r--r--tests/wpt/tests/fledge/tentative/kanon-status-not-calculated.https.window.js2
-rw-r--r--tests/wpt/tests/fledge/tentative/register-ad-beacon.https.window.js48
-rw-r--r--tests/wpt/tests/fledge/tentative/reporting-arguments.https.window.js8
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py4
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js51
-rw-r--r--tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py4
-rw-r--r--tests/wpt/tests/fledge/tentative/round-a-value.https.window.js18
-rw-r--r--tests/wpt/tests/fledge/tentative/send-report-to.https.window.js20
-rw-r--r--tests/wpt/tests/fledge/tentative/trusted-scoring-signals.https.window.js20
-rw-r--r--tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html29
-rw-r--r--tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage.html33
-rw-r--r--tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html29
-rw-r--r--tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html36
-rw-r--r--tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html50
-rw-r--r--tests/wpt/tests/html/canvas/tools/yaml-new/layers.yaml43
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir-assorted.window.js5
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html2
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html25
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42.html33
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html6
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html4
-rw-r--r--tests/wpt/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html5
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html6
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html4
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html8
-rw-r--r--tests/wpt/tests/html/dom/render-blocking/support/utils.js13
-rw-r--r--tests/wpt/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html599
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html49
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html52
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal.html52
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html57
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-3.html65
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-4.html58
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-5.html61
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested.html57
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller.html49
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-form-element/form-indexed-element-shadow.html26
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css4
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-select-element/select-attribute-crash.html18
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute-ref.html15
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute.html18
-rw-r--r--tests/wpt/tests/html/semantics/popovers/popover-open-overflow-display-2.html69
-rw-r--r--tests/wpt/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html4
-rw-r--r--tests/wpt/tests/inert/inert-iframe-hittest.html10
-rw-r--r--tests/wpt/tests/mediacapture-record/MediaRecorder-mimetype.html2
-rw-r--r--tests/wpt/tests/orientation-event/motion/rounding.https.html38
-rw-r--r--tests/wpt/tests/orientation-event/orientation/null-values.https.html41
-rw-r--r--tests/wpt/tests/orientation-event/orientation/rounding.https.html29
-rw-r--r--tests/wpt/tests/orientation-event/resources/orientation-event-helpers.js11
-rw-r--r--tests/wpt/tests/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js2
-rw-r--r--tests/wpt/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js2
-rw-r--r--tests/wpt/tests/pointerevents/META.yml8
-rw-r--r--tests/wpt/tests/preload/prefetch-document.html51
-rw-r--r--tests/wpt/tests/selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html30
-rw-r--r--tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-basic.html43
-rw-r--r--tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats-2.html36
-rw-r--r--tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats.html53
-rw-r--r--tests/wpt/tests/shared-storage/resources/credentials-test-helper.py22
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-add-module-credentials-include.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-add-module-credentials-omit.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-add-module-credentials-same-origin.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-include.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-omit.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-same-origin.tentative.https.sub.html30
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/replacestate.tentative.html14
-rw-r--r--tests/wpt/tests/storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.js8
-rw-r--r--tests/wpt/tests/storage-access-api/resources/bless_cross_site_permissions.html17
-rw-r--r--tests/wpt/tests/storage-access-api/resources/embedded_responder.js2
-rw-r--r--tests/wpt/tests/storage-access-api/resources/embedded_worker.js17
-rw-r--r--tests/wpt/tests/storage-access-api/resources/embedded_worker.py31
-rw-r--r--tests/wpt/tests/storage-access-api/resources/get_cookies.py10
-rw-r--r--tests/wpt/tests/storage-access-api/resources/set_cookies.py10
-rw-r--r--tests/wpt/tests/storage-access-api/resources/shared-worker-cookies.py37
-rw-r--r--tests/wpt/tests/storage-access-api/resources/shared-worker-relay.js10
-rw-r--r--tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html46
-rw-r--r--tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html34
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.js48
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js5
-rw-r--r--tests/wpt/tests/svg/painting/reftests/marker-path-001.svg1
-rw-r--r--tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations-ref.svg66
-rw-r--r--tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations.svg38
-rw-r--r--tests/wpt/tests/svg/pservers/reftests/gradient-transform-03.svg22
-rw-r--r--tests/wpt/tests/svg/pservers/reftests/pattern-transform-03.svg21
-rw-r--r--tests/wpt/tests/tools/ci/tc/tasks/test.yml2
-rw-r--r--tests/wpt/tests/tools/docker/Dockerfile1
-rw-r--r--tests/wpt/tests/tools/webdriver/webdriver/bidi/modules/storage.py44
-rw-r--r--tests/wpt/tests/tools/wpt/browser.py59
-rw-r--r--tests/wpt/tests/tools/wpt/run.py53
-rw-r--r--tests/wpt/tests/tools/wptrunner/requirements_edge.txt1
-rw-r--r--tests/wpt/tests/tools/wptrunner/requirements_ie.txt2
-rw-r--r--tests/wpt/tests/tools/wptrunner/tox.ini4
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/__init__.py3
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge.py109
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py27
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py4
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/ie.py50
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce.py4
-rwxr-xr-xtests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce_setup/edge-prerun.bat9
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/tests/base.py1
-rw-r--r--tests/wpt/tests/trusted-types/trusted-types-from-literal.tentative.html (renamed from tests/wpt/tests/trusted-types/trusted-types-from-literal.html)0
-rw-r--r--tests/wpt/tests/url/resources/urltestdata.json30
-rw-r--r--tests/wpt/tests/webaudio/the-audio-api/the-oscillatornode-interface/osc-basic-waveform.html2
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/browsing_context/fragment_navigated/fragment_navigated.py2
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/integration/navigation.py67
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/__init__.py15
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/conftest.py12
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/__init__.py0
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/filter.py559
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/invalid.py155
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/partition.py258
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/storage/set_cookie/invalid.py20
-rw-r--r--tests/wpt/tests/webdriver/tests/classic/get_element_text/get.py2
-rw-r--r--tests/wpt/tests/webdriver/tests/support/fixtures_bidi.py67
-rw-r--r--tests/wpt/tests/webdriver/tests/support/helpers.py6
-rw-r--r--tests/wpt/tests/webhid/resources/automation.js42
-rw-r--r--tests/wpt/tests/webrtc-extensions/RTCRtpParameters-codec.html84
-rw-r--r--tests/wpt/tests/webrtc-svc/RTCRtpParameters-scalability.html14
-rw-r--r--tests/wpt/tests/webrtc-svc/svc-helper.js4
-rw-r--r--tests/wpt/tests/webrtc/RTCDTMFSender-helper.js10
-rw-r--r--tests/wpt/tests/webrtc/RTCPeerConnection-helper.js7
-rw-r--r--tests/wpt/tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html30
-rw-r--r--tests/wpt/tests/webrtc/RTCRtpReceiver-getStats.https.html13
-rw-r--r--tests/wpt/tests/webrtc/RTCRtpSender-getStats.https.html18
-rw-r--r--tests/wpt/tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html103
-rw-r--r--tests/wpt/tests/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js2
-rw-r--r--tests/wpt/tests/webrtc/resources/webrtc-test-helpers.sub.js14
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/first-party.all.tentative.https.window.js26
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/first-party.default.tentative.https.window.js26
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/first-party.none.tentative.https.window.js26
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/get_cookies.py13
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/get_cookies_redirect.py9
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/iframe-iframe.html6
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/iframe.sub.html2
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/set_cookies.py10
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/util.js46
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/worker.js5
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/worker.py38
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/resources/worker_redirect.py9
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js36
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js38
-rw-r--r--tests/wpt/tests/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js38
392 files changed, 8906 insertions, 1881 deletions
diff --git a/tests/wpt/meta-legacy-layout/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini b/tests/wpt/meta-legacy-layout/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini
new file mode 100644
index 00000000000..fcc2d8205dd
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini
@@ -0,0 +1,144 @@
+[border-image-width-interpolation-math-functions-tentative.html]
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-color-mix-function.html.ini b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-color-mix-function.html.ini
index 3f3a52b9d50..49dceb7d0a5 100644
--- a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-color-mix-function.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-computed-color-mix-function.html.ini
@@ -814,3 +814,27 @@
[Property color value 'color-mix(in oklch, oklab(0.5 0 0), black)']
expected: FAIL
+
+ [Property color value 'color-mix(in hsl, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hsl, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hwb, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hwb, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in lch, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in lch, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in oklch, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in oklch, white 10%, blue)']
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-hsl.html.ini b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-hsl.html.ini
index fb22c6bf352..a3d8c949834 100644
--- a/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-hsl.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-color/parsing/color-valid-hsl.html.ini
@@ -49,3 +49,12 @@
[e.style['color'\] = "hsl(120 30 50 / none)" should set the property value]
expected: FAIL
+
+ [e.style['color'\] = "hsl(30 -50% 60)" should set the property value]
+ expected: FAIL
+
+ [e.style['color'\] = "hsl(0 -50 40%)" should set the property value]
+ expected: FAIL
+
+ [e.style['color'\] = "hsl(30 -50 60)" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini b/tests/wpt/meta-legacy-layout/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini
new file mode 100644
index 00000000000..ac7fa1b4461
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini
@@ -0,0 +1,144 @@
+[font-size-adjust-interpolation-math-functions.tentative.html]
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini b/tests/wpt/meta-legacy-layout/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini
new file mode 100644
index 00000000000..30f9f12ae64
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini
@@ -0,0 +1,144 @@
+[font-stretch-interpolation-math-functions.tentative.html]
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-cascade.html.ini b/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-cascade.html.ini
index b29e178ab54..4fcdc07a655 100644
--- a/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-cascade.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-cascade.html.ini
@@ -1,4 +1,5 @@
[starting-style-cascade.html]
+ expected: ERROR
[Overridden @starting-style - order of appearance]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-rule-none.html.ini b/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-rule-none.html.ini
index f01ead5128a..1ade9851ece 100644
--- a/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-rule-none.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/css-transitions/starting-style-rule-none.html.ini
@@ -1,3 +1,4 @@
[starting-style-rule-none.html]
+ expected: ERROR
[@starting-style with display:none]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/css-variables/variables-animation-math-functions-tentative.html.ini b/tests/wpt/meta-legacy-layout/css/css-variables/variables-animation-math-functions-tentative.html.ini
new file mode 100644
index 00000000000..fc4c1ab570a
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/css-variables/variables-animation-math-functions-tentative.html.ini
@@ -0,0 +1,108 @@
+[variables-animation-math-functions-tentative.html]
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/cssom-view/scroll-behavior-smooth-navigation.html.ini b/tests/wpt/meta-legacy-layout/css/cssom-view/scroll-behavior-smooth-navigation.html.ini
index 647c7fb29b2..f4121525268 100644
--- a/tests/wpt/meta-legacy-layout/css/cssom-view/scroll-behavior-smooth-navigation.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/cssom-view/scroll-behavior-smooth-navigation.html.ini
@@ -4,6 +4,3 @@
[Make sure the page is ready for animation.]
expected: FAIL
-
- [Smooth scrolling while doing history navigation.]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/cssom/getComputedStyle-pseudo-with-argument.html.ini b/tests/wpt/meta-legacy-layout/css/cssom/getComputedStyle-pseudo-with-argument.html.ini
new file mode 100644
index 00000000000..2507753f7ef
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/cssom/getComputedStyle-pseudo-with-argument.html.ini
@@ -0,0 +1,15 @@
+[getComputedStyle-pseudo-with-argument.html]
+ [This pseudo-element should parse: ::highlight(name)]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight(\nname]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight(name\t]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight( name ]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight( n\\61me )]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/mediaqueries/display-mode.html.ini b/tests/wpt/meta-legacy-layout/css/mediaqueries/display-mode.html.ini
index 5a1060ad0f6..69978c1538a 100644
--- a/tests/wpt/meta-legacy-layout/css/mediaqueries/display-mode.html.ini
+++ b/tests/wpt/meta-legacy-layout/css/mediaqueries/display-mode.html.ini
@@ -16,3 +16,6 @@
[Check that display-mode evaluates to true in the boolean context]
expected: FAIL
+
+ [Should be known: '(display-mode: picture-in-picture)']
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-005.html.ini b/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-005.html.ini
new file mode 100644
index 00000000000..245fb34babc
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-005.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-005.html]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-006.html.ini b/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-006.html.ini
new file mode 100644
index 00000000000..40739ba8a40
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/css/selectors/has-style-sharing-pseudo-006.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-006.html]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/dom/events/webkit-transition-end-event.html.ini b/tests/wpt/meta-legacy-layout/dom/events/webkit-transition-end-event.html.ini
index eb8b8d11dff..b7fe8688a23 100644
--- a/tests/wpt/meta-legacy-layout/dom/events/webkit-transition-end-event.html.ini
+++ b/tests/wpt/meta-legacy-layout/dom/events/webkit-transition-end-event.html.ini
@@ -1,5 +1,4 @@
[webkit-transition-end-event.html]
- expected: TIMEOUT
[dispatchEvent of an transitionend event does not trigger a prefixed event handler or listener]
expected: FAIL
@@ -13,25 +12,16 @@
expected: FAIL
[event types for prefixed and unprefixed transitionend event listeners should be named appropriately]
- expected: NOTRUN
+ expected: FAIL
[ontransitionend and onwebkittransitionend are not aliases]
expected: FAIL
[webkitTransitionEnd event listener should trigger for an animation]
- expected: TIMEOUT
+ expected: FAIL
[dispatchEvent of a webkitTransitionEnd event does trigger a prefixed event handler or listener]
expected: FAIL
[onwebkittransitionend event handler should not trigger if an unprefixed event handler also exists]
expected: FAIL
-
- [webkitTransitionEnd event listener should not trigger if an unprefixed listener also exists]
- expected: NOTRUN
-
- [webkitTransitionEnd event listener should not trigger if an unprefixed event handler also exists]
- expected: NOTRUN
-
- [webkitTransitionEnd event listener is case sensitive]
- expected: NOTRUN
diff --git a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini
index eccca660243..f9de5391ad6 100644
--- a/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini
+++ b/tests/wpt/meta-legacy-layout/fetch/metadata/generated/css-images.sub.tentative.html.ini
@@ -146,6 +146,3 @@
[list-style-image sec-fetch-site - HTTPS downgrade-upgrade]
expected: FAIL
-
- [border-image sec-fetch-dest - Not sent to non-trustworthy same-origin destination]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini
new file mode 100644
index 00000000000..6c1cf88513e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini
@@ -0,0 +1,3 @@
+[dangling-markup-mitigation-allowed-apis.html]
+ [Does not block window.open(`resources/empty.html?\n<`,'_self')]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini
index 5af5dc2813d..429fb6d6f29 100644
--- a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini
+++ b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini
@@ -1,4 +1,4 @@
-[dangling-markup-mitigation-data-url.tentative.sub.html]
+[dangling-markup-mitigation-data-url.sub.html]
[<img id="dangling" src="data:image/svg+xml;utf8,\\n <svg width='1' height='1' xmlns='http://www.w3.org/2000/svg'>\\n <rect width='100%' height='100%' fill='rebeccapurple'/>\\n <rect x='10%' y='10%' width='80%' height='80%' fill='lightgreen'/>\\n </svg>">]
expected: FAIL
diff --git a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini
index 3b0a8472abf..c7893561e27 100644
--- a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini
+++ b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini
@@ -1,4 +1,4 @@
-[dangling-markup-mitigation.tentative.html]
+[dangling-markup-mitigation.html]
[Fetch: /images/gre\\nen-1x1.png?img=<]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini
new file mode 100644
index 00000000000..50ec2d74bb6
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini
@@ -0,0 +1,3 @@
+[dangling-markup-mitigation.https.html]
+ [Only blocks dangling markup requests]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/about-srcdoc-navigation-blocked.window.js.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/about-srcdoc-navigation-blocked.window.js.ini
index ea9cbb0b4de..4f8ca6048f2 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/about-srcdoc-navigation-blocked.window.js.ini
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/about-srcdoc-navigation-blocked.window.js.ini
@@ -1,5 +1,4 @@
[about-srcdoc-navigation-blocked.window.html]
- expected: TIMEOUT
[Navigations to about:srcdoc via window.location must be blocked]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigate-to-unparseable-url.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigate-to-unparseable-url.html.ini
index 24d2f8ac554..27889a98fb5 100644
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigate-to-unparseable-url.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigate-to-unparseable-url.html.ini
@@ -1,3 +1,6 @@
[navigate-to-unparseable-url.html]
[location.href setter throws a SyntaxError DOMException for unparseable URLs]
expected: FAIL
+
+ [<a> tag navigate fails for unparseable URLs]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini
deleted file mode 100644
index 4ecd6d9f753..00000000000
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.js.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[navigation-unload-cross-origin.sub.window.html]
- [Cross-origin navigation started from unload handler must be ignored]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html.ini b/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html.ini
deleted file mode 100644
index 60a4fa51f8a..00000000000
--- a/tests/wpt/meta-legacy-layout/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[a-click.html]
- [aElement.click() before the load event must NOT replace]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/browsers/history/the-history-interface/traverse_the_history_2.html.ini b/tests/wpt/meta-legacy-layout/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-legacy-layout/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-legacy-layout/html/canvas/element/manual/text/canvas.2d.disconnected.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/text/canvas.2d.disconnected.html.ini
index 5cdcce07c65..17247137cb1 100644
--- a/tests/wpt/meta-legacy-layout/html/canvas/element/manual/text/canvas.2d.disconnected.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/canvas/element/manual/text/canvas.2d.disconnected.html.ini
@@ -1,2 +1,2 @@
[canvas.2d.disconnected.html]
- expected: FAIL
+ expected: CRASH
diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini
new file mode 100644
index 00000000000..e7c121bc3d8
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini
@@ -0,0 +1,2 @@
+[2d.layer.drawImage.html]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini
new file mode 100644
index 00000000000..bfd27f9b357
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini
@@ -0,0 +1,2 @@
+[2d.layer.drawImage.w.html]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-assorted.window.js.ini b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-assorted.window.js.ini
index 6d541106aee..64245a9ccfe 100644
--- a/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-assorted.window.js.ini
+++ b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-assorted.window.js.ini
@@ -94,3 +94,9 @@
[directionality of bdi elements: no dir attribute empty in rtl parent]
expected: FAIL
+
+ [directionality of bdi elements: dir=auto numbers in ltr parent]
+ expected: FAIL
+
+ [directionality of bdi elements: dir=auto numbers in rtl parent]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-shadow-42.html.ini b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-shadow-42.html.ini
new file mode 100644
index 00000000000..1a4b5035cc0
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/elements/global-attributes/dir-shadow-42.html.ini
@@ -0,0 +1,2 @@
+[dir-shadow-42.html]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini
new file mode 100644
index 00000000000..346d7282c0a
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-001.tentative.html]
+ [blocking defers frames until full parsing]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini
new file mode 100644
index 00000000000..92a6b95f046
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-003.tentative.html]
+ [adding link in the head defers frames]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini
deleted file mode 100644
index b3fd8fa38aa..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-004.tentative.html]
- [removing link in the head makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini
deleted file mode 100644
index 42f9c7342db..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-005.tentative.html]
- [removing 'blocking' makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini
new file mode 100644
index 00000000000..a6e9373200b
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-006.tentative.html]
+ [adding 'blocking=render' in the head makes it blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini
deleted file mode 100644
index 6c63b2db412..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-007.tentative.html]
- [link with non-matching media has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini
new file mode 100644
index 00000000000..9561d696beb
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-008.tentative.html]
+ [changing media to matching causes link to have an effect]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini
deleted file mode 100644
index 3c105de1140..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-009.tentative.html]
- [changing media to non-matching makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini
deleted file mode 100644
index ef4e023dfa6..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-010.tentative.html]
- [changing rel to non-expect makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini
new file mode 100644
index 00000000000..0675b813616
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-011.tentative.html]
+ [changing rel to expect in the head causes it to be blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini
new file mode 100644
index 00000000000..1e31c3f000e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-012.tentative.html]
+ [adding href in the head makes it blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini
deleted file mode 100644
index 9ce1660b44c..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-013.tentative.html]
- [removing href makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini
deleted file mode 100644
index d338af1ff52..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-014.tentative.html]
- [link in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini
deleted file mode 100644
index 0dd5e871106..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-015.tentative.html]
- [removing link the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini
deleted file mode 100644
index 7718cf5bef3..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-016.tentative.html]
- [removing 'blocking' in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini
deleted file mode 100644
index 3c50d660460..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-017.tentative.html]
- [adding 'blocking=render' in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini
deleted file mode 100644
index 98fda576808..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-018.tentative.html]
- [changing media to matching in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini
deleted file mode 100644
index 55b1e8fcbc4..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-019.tentative.html]
- [changing media to non-matching in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini
deleted file mode 100644
index d9ca447f339..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-020.tentative.html]
- [changing rel to non-expect in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini
deleted file mode 100644
index 9944597e235..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-021.tentative.html]
- [changing rel to expect in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini
deleted file mode 100644
index 17d86d7881a..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-022.tentative.html]
- [adding href in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini
deleted file mode 100644
index a0bd7e500ca..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-023.tentative.html]
- [removing href in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini
new file mode 100644
index 00000000000..3e821238f4e
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-024.tentative.html]
+ [unknown href causes the whole document to be blocked]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini
deleted file mode 100644
index 6d1a662295c..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-025.tentative.html]
- [adding an id in the body satisfies render block]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini
deleted file mode 100644
index 76fadb90c93..00000000000
--- a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-026.tentative.html]
- [removing id after it was renderer keeps render block satisfied]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini
new file mode 100644
index 00000000000..61f04ef7a4d
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-027.tentative.html]
+ [unknown href causes the whole document to be blocked (with href changes!)]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini
new file mode 100644
index 00000000000..891c20353ba
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini
@@ -0,0 +1,3 @@
+[iframe-loading-lazy-in-scroller-far.html]
+ [Test that lazy-loaded iframes do not load when far from viewport.]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini
new file mode 100644
index 00000000000..ccd3db41d22
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini
@@ -0,0 +1,2 @@
+[iframe-loading-lazy-in-scroller-horizontal-far.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
index 6bec7a732b8..49e3449f144 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
@@ -1,4 +1,4 @@
[iframe_sandbox_popups_nonescaping-2.html]
type: testharness
[Check that popups from a sandboxed iframe do not escape the sandbox]
- expected: FAIL
+ expected: NOTRUN
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini
index 4d8c04fb3bd..b6c08d28a2c 100644
--- a/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini
+++ b/tests/wpt/meta-legacy-layout/html/semantics/forms/form-submission-0/text-plain.window.js.ini
@@ -175,3 +175,12 @@
[text/plain: 0x00 in name (normal form)]
expected: FAIL
+
+ [text/plain: 0x00 in value (formdata event)]
+ expected: FAIL
+
+ [text/plain: \\n in value (normal form)]
+ expected: FAIL
+
+ [text/plain: \\r\\n in filename (formdata event)]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini
new file mode 100644
index 00000000000..1dcebc9a5ff
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini
@@ -0,0 +1,3 @@
+[form-indexed-element-shadow.html]
+ [form.elements: indexed access reflects DOM order, not flat tree]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/html/semantics/popovers/popover-open-overflow-display-2.html.ini b/tests/wpt/meta-legacy-layout/html/semantics/popovers/popover-open-overflow-display-2.html.ini
new file mode 100644
index 00000000000..2d7a15adecb
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/html/semantics/popovers/popover-open-overflow-display-2.html.ini
@@ -0,0 +1,18 @@
+[popover-open-overflow-display-2.html]
+ [Absolute popover inside absolute element]
+ expected: FAIL
+
+ [Absolute element inside absolute popover]
+ expected: FAIL
+
+ [Fixed popover inside fixed element]
+ expected: FAIL
+
+ [Fixed element inside fixed popover]
+ expected: FAIL
+
+ [Absolute popover inside fixed element]
+ expected: FAIL
+
+ [Fixed element inside absolute popover]
+ expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/resource-timing/test_resource_timing.https.html.ini b/tests/wpt/meta-legacy-layout/resource-timing/test_resource_timing.https.html.ini
index 32d149c8ae9..54e3ef35665 100644
--- a/tests/wpt/meta-legacy-layout/resource-timing/test_resource_timing.https.html.ini
+++ b/tests/wpt/meta-legacy-layout/resource-timing/test_resource_timing.https.html.ini
@@ -68,6 +68,3 @@
[PerformanceEntry has correct name, initiatorType, startTime, and duration (link)]
expected: NOTRUN
-
- [PerformanceEntry has correct name, initiatorType, startTime, and duration (img)]
- expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini b/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini
new file mode 100644
index 00000000000..b7b36c1d3a4
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/webmessaging/without-ports/018.html.ini
@@ -0,0 +1,4 @@
+[018.html]
+ expected: TIMEOUT
+ [origin of the script that invoked the method, javascript:]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/workers/constructors/Worker/Worker-constructor.html.ini b/tests/wpt/meta-legacy-layout/workers/constructors/Worker/Worker-constructor.html.ini
new file mode 100644
index 00000000000..80f9a4f15b8
--- /dev/null
+++ b/tests/wpt/meta-legacy-layout/workers/constructors/Worker/Worker-constructor.html.ini
@@ -0,0 +1,2 @@
+[Worker-constructor.html]
+ expected: ERROR
diff --git a/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini b/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
index eddd0aa6c39..3280d281582 100644
--- a/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
+++ b/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
@@ -1,3 +1,4 @@
[third-party.default.tentative.sub.https.window.html]
+ expected: ERROR
[Check SharedWorker sameSiteCookies option default for third-party]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini b/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
index 46f1697bd35..b9f12992e36 100644
--- a/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
+++ b/tests/wpt/meta-legacy-layout/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
@@ -1,3 +1,4 @@
[third-party.none.tentative.sub.https.window.html]
+ expected: ERROR
[Check SharedWorker sameSiteCookies option none for third-party]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta-legacy-layout/xhr/xhr-timeout-longtask.any.js.ini b/tests/wpt/meta-legacy-layout/xhr/xhr-timeout-longtask.any.js.ini
deleted file mode 100644
index 36b2068c5a6..00000000000
--- a/tests/wpt/meta-legacy-layout/xhr/xhr-timeout-longtask.any.js.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[xhr-timeout-longtask.any.worker.html]
- [Long tasks should not trigger load timeout]
- expected: FAIL
-
-
-[xhr-timeout-longtask.any.html]
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index a00e44c55ba..c39d1f22ab2 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -3774,6 +3774,13 @@
{}
]
],
+ "chrome-first-letter-container-query-crash.html": [
+ "6647e38731516ff001beccffb8a9969125a04a17",
+ [
+ null,
+ {}
+ ]
+ ],
"chrome-first-letter-inside-replaced-crash.html": [
"cf9e2d71633e5c5c45ba458b394c986a21acc13d",
[
@@ -4211,6 +4218,13 @@
]
],
"crashtests": {
+ "eol-spaces-bidi-min-content-crash.html": [
+ "d8c3ec337b38d8b2cba6313d7cc3034b393b1406",
+ [
+ null,
+ {}
+ ]
+ ],
"line-break-float-crash.html": [
"bdf47c3e8ae024e596629dc4061cc7e075503150",
[
@@ -6591,6 +6605,13 @@
{}
]
],
+ "select-attribute-crash.html": [
+ "5330411a5dcae0e9becb76bad1897c681dad7419",
+ [
+ null,
+ {}
+ ]
+ ],
"select-in-table-crash.html": [
"d1f1cee2177a1e58d635c8e96f257cee557a39ea",
[
@@ -20465,6 +20486,15 @@
]
]
},
+ "event-timing": {
+ "interactionid-composition-manual.html": [
+ "2b4f2aab0943c1f41f8a8ba9092029ce812df5f6",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"feature-policy": {
"experimental-features": {
"vertical-scroll-disabled-frame-no-scroll-manual.tentative.html": [
@@ -150623,6 +150653,19 @@
{}
]
],
+ "out-of-flow-in-multicolumn-117.html": [
+ "886a12acaba969b0b514342b04a3992bde8897be",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"overflow-clip-000.html": [
"72b10f5cdd3092a042f1f90bff04e9428d61608e",
[
@@ -209140,7 +209183,7 @@
]
],
"two-clip-path-animation-diff-length1.html": [
- "f647c1af59095735217eb60e51291a64b79fce70",
+ "5f6bb7299fc592a9f11f1708bdd6f41617bf5ca0",
[
null,
[
@@ -216706,6 +216749,19 @@
{}
]
],
+ "multicol-fill-balance-029.html": [
+ "837141bd0593716c5b5fb46ef3f68efb4aaf077e",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"multicol-fill-balance-nested-000.html": [
"5e466df8077545b4d6474389d296bc26c5b28b86",
[
@@ -227423,6 +227479,19 @@
{}
]
],
+ "first-letter-with-before-after.html": [
+ "95150a0e9627994b7248ba1730fc9abaef7f31bc",
+ [
+ null,
+ [
+ [
+ "/css/css-pseudo/first-letter-with-before-after-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"first-letter-with-preceding-new-line.html": [
"5243b042882328443daf07e6f05f1cac68cede84",
[
@@ -292880,6 +292949,19 @@
}
]
],
+ "class-specificity.html": [
+ "55de2ec3884c174a4978be193fde2220fb0c5164",
+ [
+ null,
+ [
+ [
+ "/css/css-view-transitions/class-specificity-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"content-smaller-than-box-size.html": [
"d2b8f63ca068ffc744b7b1a7b0ca8d1c25a32854",
[
@@ -317911,6 +317993,110 @@
{}
]
],
+ "has-style-sharing-pseudo-001.html": [
+ "6edb3da03eed5c9328d194c4d365f04b19a5025b",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-002.html": [
+ "59dd2a9a1b5f38a08c35c26bb255d675b6551903",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-002-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-003.html": [
+ "f94636f5dcc234796e408a80940d7ad267c258c1",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-003-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-004.html": [
+ "82e42005d0630b1c6b5a72c4b82ad63541bae077",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-004-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-005.html": [
+ "9e7cbe96fcf74c345029e51849115e8afddc5d12",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-006.html": [
+ "d8747abd4a4a310a7f728d9319d6c0bf0f6e7e29",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-006-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-007.html": [
+ "0e245f5aaff172483e0cbaa1e44affdb58e5868c",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-007-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "has-style-sharing-pseudo-008.html": [
+ "59844419ffaa467afb51daee7f3c387a85a56ab6",
+ [
+ null,
+ [
+ [
+ "/css/selectors/has-style-sharing-pseudo-008-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"has-visited.html": [
"8fe322c8b1751b2f4232e9898fa71bab5e203cde",
[
@@ -322751,6 +322937,19 @@
{}
]
],
+ "2d.layer.drawImage.html": [
+ "58206c3eb87408b2993740cf9912bf271d84d3f1",
+ [
+ null,
+ [
+ [
+ "/html/canvas/element/layers/2d.layer.drawImage-expected.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"2d.layer.flush-on-frame-presentation.html": [
"c8a118f8a2e860e4110f8b254fe08408930173ff",
[
@@ -325050,6 +325249,32 @@
{}
]
],
+ "2d.layer.drawImage.html": [
+ "37718f6f2c5290c91879564dee61039bd3c93142",
+ [
+ null,
+ [
+ [
+ "/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "2d.layer.drawImage.w.html": [
+ "78a235597d53188057a570f34632aba7147e9123",
+ [
+ null,
+ [
+ [
+ "/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"2d.layer.global-filter.html": [
"2388a06a964222700dd1f71b57ad0b7004becfbb",
[
@@ -327067,6 +327292,19 @@
{}
]
],
+ "dir-shadow-42.html": [
+ "b9697678cbc79cc9f5c7e4721c5ce1ec241f6168",
+ [
+ null,
+ [
+ [
+ "/html/dom/elements/global-attributes/dir-shadow-42-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"dir_auto-EN-L.html": [
"fa8d793bd043d008a98020063dcea6549e9d3e19",
[
@@ -327133,7 +327371,7 @@
]
],
"dir_auto-N-EN.html": [
- "467b4d093943953da64513d8344598f4c239fd80",
+ "5d948d34568aa5481ffc6f438190d1677ee0839e",
[
null,
[
@@ -333913,6 +334151,19 @@
{}
]
],
+ "top-layer-remove-popover-attribute.html": [
+ "3827e90c5bdb01c1b59fc159bd312a2afbd09342",
+ [
+ null,
+ [
+ [
+ "/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"top-layer-stacking-correct-order-remove-readd.html": [
"4fdd28820dbb27af2d397d747573e0bd7cbecf35",
[
@@ -334274,7 +334525,7 @@
},
"the-bdi-element": {
"bdi-auto-dir-default.html": [
- "3a9d90c76b33795c0760796762400ca9662f7db5",
+ "e658500a4ebf02ef92b416a060d5c7335d640ca2",
[
null,
[
@@ -342176,7 +342427,7 @@
]
],
"marker-path-001.svg": [
- "7fb4adf4277321eb69e50fecb9018c1950aef4ca",
+ "75bc5703b7b0851b92727cb00f078960346ce500",
[
null,
[
@@ -342185,7 +342436,23 @@
"=="
]
],
- {}
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 8
+ ],
+ [
+ 0,
+ 8
+ ]
+ ]
+ ]
+ ]
+ }
]
],
"marker-path-002.svg": [
@@ -342396,6 +342663,19 @@
{}
]
],
+ "paintorder-text-decorations.svg": [
+ "5b313220bd30a11aceaba1a45bcbaab44207ff9a",
+ [
+ null,
+ [
+ [
+ "/svg/painting/reftests/paintorder-text-decorations-ref.svg",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"percentage-attribute.svg": [
"d245999db08ec13ea34c6c832483d3c1135ceec0",
[
@@ -342818,6 +343098,19 @@
{}
]
],
+ "gradient-transform-03.svg": [
+ "25e304614dbe43422e5d0daa9b9e03f9944aabe0",
+ [
+ null,
+ [
+ [
+ "/svg/pservers/reftests/reference/green-100x100.svg",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"meshgradient-basic-001.svg": [
"24290d40d6c37583d86aae4a098293c6cb8a6653",
[
@@ -342974,6 +343267,19 @@
{}
]
],
+ "pattern-transform-03.svg": [
+ "b2e0e7aaa2ef1b107586ea03230dc173d1133de1",
+ [
+ null,
+ [
+ [
+ "/svg/pservers/reftests/reference/green-100x100.svg",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"pattern-viewbox-01.svg": [
"618b8fc29e69d2624d5556d6bbcdba600ce21a4a",
[
@@ -348061,7 +348367,7 @@
[]
],
".taskcluster.yml": [
- "53518a9498a7cd3dafcc6f0a0ca5b952c0fd9330",
+ "38af7fa10af8396c8b41732b7b617bf408df0446",
[]
],
".well-known": {
@@ -415304,6 +415610,10 @@
"8ebb00b9dcc10f43df0efea20991af653f5cb691",
[]
],
+ "first-letter-with-before-after-ref.html": [
+ "89bab0829ab6c078e490fd17cf8e684fe23a5c11",
+ []
+ ],
"first-letter-with-quote-ref.html": [
"0eebf0a51f10c90c64736e61a1403379fb9ed725",
[]
@@ -424708,7 +425018,7 @@
[]
],
"helper.js": [
- "d5fa61b15eff12f48d0a76df51595b104579f757",
+ "a37aae918300d1136debbebbfbb75d46259e0bce",
[]
],
"import-green.css": [
@@ -426898,6 +427208,10 @@
"c47b31e4d5a3a2121bf8191c1e612b5a5f2f1663",
[]
],
+ "class-specificity-ref.html": [
+ "5c882ada040ec700eda008e016d0a1827e31d368",
+ []
+ ],
"content-object-fit-fill-ref.html": [
"b86e0a95a172bcc191f17d954b2cf6bd710a1fd1",
[]
@@ -432014,6 +432328,38 @@
"0f26fb2987e0dbc25573f53c5c37d8676f7db8ec",
[]
],
+ "has-style-sharing-pseudo-001-ref.html": [
+ "c45db87fa321ffd68e0cec1f3c4c07d141f1b3c9",
+ []
+ ],
+ "has-style-sharing-pseudo-002-ref.html": [
+ "a8138c257265bfd0f7a66ddc7076133ac0307868",
+ []
+ ],
+ "has-style-sharing-pseudo-003-ref.html": [
+ "a9b8e248d69b49a8384279aee653eceaaf482715",
+ []
+ ],
+ "has-style-sharing-pseudo-004-ref.html": [
+ "0d97e1d1c2fbcfda33eeffac68597e62862daf3a",
+ []
+ ],
+ "has-style-sharing-pseudo-005-ref.html": [
+ "97c2bf2ade16862b795e4eb84a14934b59cb672a",
+ []
+ ],
+ "has-style-sharing-pseudo-006-ref.html": [
+ "d052141d8ede8c87993e0f02d1181d32b88a4cec",
+ []
+ ],
+ "has-style-sharing-pseudo-007-ref.html": [
+ "24f4502b786c071cacfa92702db5326918052cf6",
+ []
+ ],
+ "has-style-sharing-pseudo-008-ref.html": [
+ "ad293bab59eff620f595b4b1a3e471467082b8a3",
+ []
+ ],
"has-visited-ref.html": [
"3f54e2e3914f62a81c3199bbe3d8c0339b9c2ba8",
[]
@@ -433224,7 +433570,13 @@
"WEB_FEATURES.yml": [
"cf364db88ef847fae3df7ae1803d9ef7dd01f1c3",
[]
- ]
+ ],
+ "support": {
+ "focus-opener.js": [
+ "679eef3b22e80cddaab0fa8866a786be6a081840",
+ []
+ ]
+ }
},
"document-policy": {
"META.yml": [
@@ -436888,8 +437240,12 @@
"e2b453f4638fd0efd8a0b89e6cdae05d351b8b12",
[]
],
+ "unreached.https.html": [
+ "bd389ec4fbd5a8f47b83f7c8299d5669890120cd",
+ []
+ ],
"utils.js": [
- "cbea173f17a6ad89a9d5dea3e304cff534971edb",
+ "77af9449b293c3868ea517c05bee9cdf74a2f9c4",
[]
],
"web-bluetooth-inner.html": [
@@ -438358,11 +438714,19 @@
"security": {
"dangling-markup": {
"resources": {
+ "empty.html": [
+ "0e76edd65b7baf5316fc9d0c4da59a3502e4c27a",
+ []
+ ],
"helper.js": [
"100bcba7b5184a12955c6c99ce21c483301ef446",
[]
]
- }
+ },
+ "service-worker.js": [
+ "837e216a013be499cf8f2f0b7681d851644de4ed",
+ []
+ ]
},
"support": {
"embedded-credential-window.sub.html": [
@@ -438440,7 +438804,7 @@
[]
],
"decision-logic.sub.py": [
- "78d459e3f9dac36241d8cf92c33fd031c7046af0",
+ "3a23f981620d6a467a293333b3eff5ee1df098fc",
[]
],
"direct-from-seller-signals.py": [
@@ -438456,7 +438820,7 @@
[]
],
"fledge-util.sub.js": [
- "69573d499832b1c7f61c8caae9b2c3bf8d839f02",
+ "4fc77933634aa276e4ea83bd53be5ad612789e1d",
[]
],
"fledge_http_server_util.py": [
@@ -438496,7 +438860,7 @@
[]
],
"trusted-scoring-signals.py": [
- "80488a5d6af99e33654b3d14661ba0ec0e1a9468",
+ "eccef5e76283c61e05adfebd510a3361c4391fe0",
[]
],
"wasm-helper.py": [
@@ -443040,6 +443404,10 @@
"60f78d80965fd0dec9ea11bc21d3652fc3d7bad1",
[]
],
+ "2d.layer.drawImage-expected.html": [
+ "26f6e752149102af7cd3bda76045092545712ba4",
+ []
+ ],
"2d.layer.flush-on-frame-presentation-expected.html": [
"532c29576cff610107dec60f91ea8dd2231df888",
[]
@@ -444120,6 +444488,10 @@
"60f78d80965fd0dec9ea11bc21d3652fc3d7bad1",
[]
],
+ "2d.layer.drawImage-expected.html": [
+ "26f6e752149102af7cd3bda76045092545712ba4",
+ []
+ ],
"2d.layer.global-filter-expected.html": [
"88057fc354a4e593191a4b3d5c94cdfa7d466126",
[]
@@ -444575,7 +444947,7 @@
[]
],
"layers.yaml": [
- "a44cb2ea2c1e379a130e084839e0c4ba0416dd7e",
+ "dfef55d081b9d46ba71d216ec76cbf9c0fe6f338",
[]
],
"line-styles.yaml": [
@@ -445565,7 +445937,11 @@
[]
],
"dir-shadow-41-ref.html": [
- "b52e08df20e88ae91b6d38a6ff5a5e55d4b59ca3",
+ "79b844edbe513b49686bd720a6497b68e7cd25c7",
+ []
+ ],
+ "dir-shadow-42-ref.html": [
+ "8ea1100246005bc17400d6abc3ece2ee1dc5810a",
[]
],
"dir-shadow-utils.js": [
@@ -445593,7 +445969,7 @@
[]
],
"dir_auto-N-EN-ref.html": [
- "0d938b2e168beecdacecf479798079ac2a99c899",
+ "496d699d73c79cff07633af95c410e2c4ba0afa3",
[]
],
"dir_auto-N-L-ref.html": [
@@ -445963,7 +446339,7 @@
[]
],
"utils.js": [
- "9a890ab685c675ee5baca618ce5d85b367761760",
+ "8a9a537e96df89a2944d62dcc2915b8a51796fd5",
[]
]
}
@@ -452280,7 +452656,7 @@
[]
],
"stylable-select-styles.css": [
- "726380f940d2e32b390269afca9617c88e3bb251",
+ "a7e9a87cdfa96a56cd82da56e78717efb4b0c966",
[]
]
},
@@ -452690,6 +453066,10 @@
"01eff8c4de5f1f5e6a951f177fd0e920ca289d4b",
[]
],
+ "top-layer-remove-popover-attribute-ref.html": [
+ "7aadaf51b72692f99f0e391d8c6a6be807e243c7",
+ []
+ ],
"top-layer-stacking-correct-order-remove-readd-ref.html": [
"392d1ca46ec175f841e06d5ca5e585a5a5743b9f",
[]
@@ -462303,7 +462683,7 @@
],
"resources": {
"orientation-event-helpers.js": [
- "01e91c62aecd4d8f58be304f095bdbb4d99b1d37",
+ "dab876fc6a320bbf11e9bc85b28631850b094269",
[]
]
}
@@ -463418,7 +463798,7 @@
},
"pointerevents": {
"META.yml": [
- "1962feaf8af08b003e519fa525271e70451984d5",
+ "e6dbf9deecfb9478166316cbdfd451479b846152",
[]
],
"README.md": [
@@ -470132,6 +470512,10 @@
"a475ee4f96ebdba21095eae2ecf98e524d344d72",
[]
],
+ "credentials-test-helper.py": [
+ "81a988e3581f0567a29a58b7303f124c5cc5e38e",
+ []
+ ],
"delete-key.https.html": [
"41595f3ee3868a1e7fa1f866bcc8936de16f5cbd",
[]
@@ -471174,16 +471558,24 @@
[]
],
"resources": {
+ "bless_cross_site_permissions.html": [
+ "c3c5b6c0b073d0c0c15bfb6d78ef2335bd228034",
+ []
+ ],
"echo-cookie-header.py": [
"f1599e3a89919adfe0a0de60515ef1d44a898190",
[]
],
"embedded_responder.js": [
- "bc13c7e7e8259aa67a99a38dd6fa3c31f3bb269d",
+ "228a262f16ecefc0804efbeeaa5d6f97c4d919a7",
+ []
+ ],
+ "embedded_worker.py": [
+ "0aa457657f1f571a5d9ac2d197e77801476b73ef",
[]
],
- "embedded_worker.js": [
- "f3a0fb257adf204431a2df4ade796c74c0643950",
+ "get_cookies.py": [
+ "07e8c2dae3ceaa86766b2050784850a7f5ca23b8",
[]
],
"hasStorageAccess-ABA-iframe.https.html": [
@@ -471230,12 +471622,24 @@
"e937ba2ca4eca2421ea0025c5a527d3bb6b574f4",
[]
],
+ "set_cookies.py": [
+ "fe182dd00cb6c3374e652072a16b7260039aab39",
+ []
+ ],
+ "shared-worker-cookies.py": [
+ "9307c4112c5fa0af31309d2a339ec0fc3814cc8c",
+ []
+ ],
+ "shared-worker-relay.js": [
+ "c94acefec999cef61e16d49fcfb529fe60e7b98f",
+ []
+ ],
"storage-access-beyond-cookies-iframe-iframe.html": [
- "ffb419f7995ff46a6fdc6b6846b534fb1cef71ce",
+ "2d5e22fa7199cb720ad3a40a16b88499077b48d9",
[]
],
"storage-access-beyond-cookies-iframe.sub.html": [
- "8c30973416e3e2793629d0a1816b7287fc498561",
+ "a9247a00020b16cb9c18c10778cfe48446022aca",
[]
]
}
@@ -471917,6 +472321,10 @@
"7822a80b942fee54a87106d7def13429454cc26e",
[]
],
+ "paintorder-text-decorations-ref.svg": [
+ "c209d88a77c75417fa0f75e0332d0923abf9b4e3",
+ []
+ ],
"percentage-ref.svg": [
"610a3ddb2d21da119fb4a53f5f351dff0190880c",
[]
@@ -472759,7 +473167,7 @@
],
"tasks": {
"test.yml": [
- "ea9c7f9daea38df2d1ccbfde3932e6ba964aa656",
+ "d62312737c843cd2050b5a9730f7a7b3ba8f8c5e",
[]
]
},
@@ -472829,7 +473237,7 @@
[]
],
"Dockerfile": [
- "a9162559ab87641da1c49f9f4b5bbb9af01074c8",
+ "e1ff6b9020515f4cca024614dff04021ff6974b5",
[]
],
"README.md": [
@@ -482876,7 +483284,7 @@
[]
],
"storage.py": [
- "4dfc82695e3c23175c6c63b4410f5e1d67fe62f3",
+ "882306ea72b9054287dbdbc3ebdce8f02488d943",
[]
]
},
@@ -482957,7 +483365,7 @@
[]
],
"browser.py": [
- "c8998fee4aaf17bd82820aca5d41d103ef6bfa78",
+ "c7f67d334e13a6c5be5ce0cf74c5fc94f00631d9",
[]
],
"commands.json": [
@@ -482997,7 +483405,7 @@
[]
],
"run.py": [
- "dcf721ef39f8382bda51155a10517e29eedfcb51",
+ "fd5382b45c30140798df68ca96c402102577538c",
[]
],
"testfiles.py": [
@@ -483160,18 +483568,10 @@
"883b061589837d34d6a65c9b91a2f31fb7c81c01",
[]
],
- "requirements_edge.txt": [
- "30b14b692fd46979178ee266d0d017faed3b492b",
- []
- ],
"requirements_firefox.txt": [
"3ba4731494acfef5fc9bd75ff3e76111575b2851",
[]
],
- "requirements_ie.txt": [
- "4ff0fedd321ab3a6083778af39eaf7fc84b0bd56",
- []
- ],
"requirements_opera.txt": [
"4ff0fedd321ab3a6083778af39eaf7fc84b0bd56",
[]
@@ -483189,7 +483589,7 @@
[]
],
"tox.ini": [
- "2a3f2bdf10952a56d3d9129fae681726d70780ab",
+ "82d3ac6f555ac7625cd0ef096a8dcab301c806c8",
[]
],
"wptrunner": {
@@ -483199,7 +483599,7 @@
],
"browsers": {
"__init__.py": [
- "4d10457699d5abd9e1cb5e02a2b58e825be1b417",
+ "81dc549d730fc4d234dcba12d5665922bbaae407",
[]
],
"android_weblayer.py": [
@@ -483238,14 +483638,6 @@
"23f4e99da62291005bb94450cde7d5ce592288a0",
[]
],
- "edge.py": [
- "5b49545a38a5003cb21490d609beb551715c2b0b",
- []
- ],
- "edge_webdriver.py": [
- "e985361e41283b68b1d2d79a755812b72746e99a",
- []
- ],
"edgechromium.py": [
"4f5bffa06c498e2b046789da21755915f6df9d8d",
[]
@@ -483259,11 +483651,7 @@
[]
],
"firefox_android.py": [
- "aa9cf63323298d65dc3dabb348120ec21e1677de",
- []
- ],
- "ie.py": [
- "87b989c028b0edaabbb75e5f6361f7f7538e80a1",
+ "3ce3b11d1f245539a31b2c1db35872c7d40f1415",
[]
],
"ladybird.py": [
@@ -483279,14 +483667,10 @@
[]
],
"sauce.py": [
- "0f7651638dc8240402e2f0147b0fee0df42489df",
+ "0f21afd38f2162a2b3f7fc986eb0432587391f84",
[]
],
"sauce_setup": {
- "edge-prerun.bat": [
- "1a3e6fee3094bcb512b5a1e058e1074e117b0477",
- []
- ],
"safari-prerun.sh": [
"39390e618fdc599e443e17b76470e989d93864e7",
[]
@@ -483535,7 +483919,7 @@
[]
],
"base.py": [
- "176eef6a42392ebb5db16674079379783cd59368",
+ "8e71aba812de83b1dccd4dfe58de2ca6d57e2ba4",
[]
],
"browsers": {
@@ -484893,7 +485277,7 @@
[]
],
"urltestdata.json": [
- "69767a20db90bf4d6b37fb6ade5cf2ea5d6686be",
+ "9f1be0449c63d306b2e5938e8163661b3c769b1a",
[]
]
},
@@ -487207,13 +487591,19 @@
},
"storage": {
"__init__.py": [
- "763e0054f1d5983b4dd0dff79ef37bc18be062e1",
+ "0d7cea96bce369323028f2910c5738ac095ece0a",
[]
],
"conftest.py": [
- "31b2c3f3e6bec2032e21b88ae33ed5995eb3cb74",
+ "0941411fab84f20df84563698821f5cdb7a13ccd",
[]
],
+ "get_cookies": {
+ "__init__.py": [
+ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
+ []
+ ]
+ },
"set_cookie": {
"__init__.py": [
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
@@ -487684,7 +488074,7 @@
[]
],
"fixtures_bidi.py": [
- "177bdda160e3dba97cfa9ccf165d673dd8cb220e",
+ "9566e6ebd19283b9d6cf9174bf4e2320d1e79fa7",
[]
],
"fixtures_http.py": [
@@ -487692,7 +488082,7 @@
[]
],
"helpers.py": [
- "9870643b3d95e6e09396f514b901aebd08c5c551",
+ "678733e951f083d121c9946c72cfea75d090d2b4",
[]
],
"html": {
@@ -487832,10 +488222,6 @@
[]
],
"resources": {
- "automation.js": [
- "f7477d1eccf816e507c401c26d9deaf360f33699",
- []
- ],
"common.js": [
"1d0904af837814ad0bd19a79a08a88faaa616164",
[]
@@ -488316,11 +488702,11 @@
[]
],
"RTCDTMFSender-helper.js": [
- "4316c3804a28f44d1f86af97c86e478570b2437a",
+ "23465603f4d77f0bf31f9fd39eb2e3dcabe21f1f",
[]
],
"RTCPeerConnection-helper.js": [
- "5d188328e80331748677d77832eb44c3018cc5ef",
+ "92e4ccfa43acd3340becf3b5c1f1298294a72069",
[]
],
"RTCPeerConnection-perfect-negotiation-helper.js": [
@@ -488371,7 +488757,7 @@
[]
],
"webrtc-test-helpers.sub.js": [
- "48882b30ccc263c6fb72e9e910d3dbe9f06d8141",
+ "8a46302668a2d6d443728122942bbef0cfe9a5f8",
[]
]
},
@@ -488550,7 +488936,7 @@
[]
],
"svc-helper.js": [
- "e73ccfa750255ab633c10372f272465301293139",
+ "6a357f085bcd2b713ca9179a40d6bf80c49c69b4",
[]
]
},
@@ -491863,16 +492249,36 @@
],
"same-site-cookies": {
"resources": {
+ "get_cookies.py": [
+ "61b138321d02f1507c18c48456f306c6cf5859db",
+ []
+ ],
+ "get_cookies_redirect.py": [
+ "0f3a647a2b88a9107c36cd8303b03cc062089f04",
+ []
+ ],
"iframe-iframe.html": [
- "0c5582176d4fe04e47f7f5f106a855f289107c79",
+ "efd4f3a65468e8627b6369d2794f4e8196e22c4a",
[]
],
"iframe.sub.html": [
- "2531f3d62039dfb5a687db95bd8210ca118d8fa9",
+ "c4724d01d2f5f02481f4047f2bb61955e81fb61d",
[]
],
- "worker.js": [
- "658f499e92ac50078471fac11ead60fdc5e7577f",
+ "set_cookies.py": [
+ "c721cc51f72dc853f3396d097c8cb0fa4fde95f1",
+ []
+ ],
+ "util.js": [
+ "67d9ee5c06bfd23f4a0e1cf28089318866f8c071",
+ []
+ ],
+ "worker.py": [
+ "8440c2d70ea173ccc4b651eff460a5b282c3ca40",
+ []
+ ],
+ "worker_redirect.py": [
+ "633a3ae67efa2cf2ffe0d01ff7cde6bb8fb4b206",
[]
]
}
@@ -494007,7 +494413,7 @@
]
],
"back-forward-cache-open-connection.window.js": [
- "cee7287a0bbc1ca229ab7b6127f17b738bd0e6ab",
+ "db51daa121c0b3f9271ce2439a6c545870d0b99e",
[
"IndexedDB/back-forward-cache-open-connection.window.html",
{
@@ -515861,7 +516267,7 @@
]
],
"clipboard-item.https.html": [
- "b50a1c97d746168fd4166726ead0964faa03aa39",
+ "7e148703a2679286d563053904d3accc820900a9",
[
null,
{}
@@ -529896,34 +530302,6 @@
{}
]
],
- "anchor-position-auto-001.html": [
- "b5e19522b00d8327e2eb1da96a2714ff2c62c60b",
- [
- null,
- {}
- ]
- ],
- "anchor-position-auto-002.html": [
- "1c86fe2e4678f5fc7600d16f6580b24b60117330",
- [
- null,
- {}
- ]
- ],
- "anchor-position-auto-003.html": [
- "33ef58b2af4692f071596aa005f4e72954d6c04f",
- [
- null,
- {}
- ]
- ],
- "anchor-position-auto-004.html": [
- "befd5fcff068d7af8d9b9a1a658eddfb3008b55d",
- [
- null,
- {}
- ]
- ],
"anchor-position-borders-001.html": [
"1e2ecbc909cee0f9f301481c12ab6a8fc9b4ff0c",
[
@@ -530407,6 +530785,13 @@
null,
{}
]
+ ],
+ "position-try-parsing.html": [
+ "7f50459710629cefd0282a8d78a60e8d760e719f",
+ [
+ null,
+ {}
+ ]
]
},
"position-fallback-001.html": [
@@ -532153,6 +532538,13 @@
}
},
"css-borders": {
+ "border-image-width-interpolation-math-functions-tentative.html": [
+ "70539beb263c5fbe4a26d687a2a32337b946e1a4",
+ [
+ null,
+ {}
+ ]
+ ],
"border-width-rounding.tentative.html": [
"04c4ddf40bd7452ee5a135e4c1b4c2a7667fc1cd",
[
@@ -533587,7 +533979,7 @@
]
],
"color-computed-color-mix-function.html": [
- "f0e2f6cce02889715b63efe3d7d11871b548a700",
+ "b54aa0da12ad9216fc148b0094b45b9c9d53fb70",
[
null,
{}
@@ -533755,7 +534147,7 @@
]
],
"color-valid-hsl.html": [
- "7ab1274176fd9fbbaed10d1644d18c2eb05b41e3",
+ "b3a9d7944e82c1aae5d733e3bf1d48779dae0396",
[
null,
{}
@@ -537799,7 +538191,7 @@
]
],
"negative-overflow-002.html": [
- "171095d2b553a6c907c4c2f1d1c72d54ec41633f",
+ "7c8d6337b9012b2a7edf32ceb9888da4616f366b",
[
null,
{}
@@ -538547,6 +538939,13 @@
{}
]
],
+ "font-size-adjust-interpolation-math-functions.tentative.html": [
+ "d173fb03bbb6b67569e1fc09a023832309747a5d",
+ [
+ null,
+ {}
+ ]
+ ],
"font-size-relative-across-calc-ff-bug-001.html": [
"167de8888725ca55090ac80cda43cddb299b7c7d",
[
@@ -538554,6 +538953,13 @@
{}
]
],
+ "font-stretch-interpolation-math-functions.tentative.html": [
+ "9029eefcb44169ac870d0545a47dae0d11ac18e9",
+ [
+ null,
+ {}
+ ]
+ ],
"font-style-angle.html": [
"baf69be5c1310f6f88b2e2b5c9de1a312d95311c",
[
@@ -542257,7 +542663,7 @@
]
],
"grid-container-ignores-first-letter-001.html": [
- "8e322fe38e1136a27c49264fb4e0dfac4ed6675d",
+ "db466b82cd8113832e689643666a009fb6547851",
[
null,
{}
@@ -545995,6 +546401,15 @@
null,
{}
]
+ ],
+ "scroller-covered-by-empty-svg.html": [
+ "f877b6b281d980093e26af4e4199da2e9a855fe1",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
},
"css-overscroll-behavior": {
@@ -546055,6 +546470,22 @@
}
},
"css-page": {
+ "cssom": {
+ "page-001.html": [
+ "2f6b4dde0500cf7ef40b2187708539523472d33a",
+ [
+ null,
+ {}
+ ]
+ ],
+ "page-002.html": [
+ "0060d295b4a4f0949ac2d4ed0bb699b891007630",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"inheritance.html": [
"565287bce50fa46fdc17cf438ff9eeb2862106a7",
[
@@ -549007,6 +549438,15 @@
"testdriver": true
}
]
+ ],
+ "prefer-inner-target.html": [
+ "053b6a1d7e6e2224a58172f603944b1f28888427",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
},
"not-resnap-outside-proximity-threshold.html": [
@@ -556557,7 +556997,7 @@
]
],
"starting-style-cascade.html": [
- "263e47217425c82c81f74748aae9b4e5002cc546",
+ "cef3e88b656d1d65d3e02179c6f44e878fd246d3",
[
null,
{}
@@ -556578,7 +557018,7 @@
]
],
"starting-style-rule-none.html": [
- "fd6879b5ee4238b87d4fd05135f562082ac2e7fa",
+ "91e4fe353409b94a5889b944b4796d98ccd816a5",
[
null,
{}
@@ -561029,6 +561469,13 @@
{}
]
],
+ "variables-animation-math-functions-tentative.html": [
+ "7c33d6cfa364efcad60ab224a926686ba6279b47",
+ [
+ null,
+ {}
+ ]
+ ],
"variables-substitute-guaranteed-invalid.html": [
"4abfe28d1f21b2891599543b3972b26fbd15b77e",
[
@@ -561263,6 +561710,13 @@
{}
]
],
+ "pseudo-element-animations.html": [
+ "a7c3247479d01f4044b9033726282037c1b4bc9f",
+ [
+ null,
+ {}
+ ]
+ ],
"pseudo-get-computed-style.html": [
"2481a713133b7e1bf47cedf0b4966a51dd777d78",
[
@@ -562743,6 +563197,13 @@
{}
]
],
+ "getComputedStyle-pseudo-with-argument.html": [
+ "452f2bb2c63e13615c1c66cc57702b40226e1d37",
+ [
+ null,
+ {}
+ ]
+ ],
"getComputedStyle-pseudo.html": [
"c07347a1973cf2fa9105907bbdd0015081bed417",
[
@@ -564698,7 +565159,7 @@
]
],
"display-mode.html": [
- "e6633de856c5f438e47ebe1d05b1593753948fbf",
+ "4ade16799f9db32f502df643f33094e5a2552e70",
[
null,
{}
@@ -564966,6 +565427,13 @@
{}
]
],
+ "offset-rotate-interpolation-math-functions-tentative.html": [
+ "34e0abf2b0debc151c85d439c649de60b47ab5d2",
+ [
+ null,
+ {}
+ ]
+ ],
"offset-rotate-interpolation.html": [
"55845108ebf5f3c42a8b0532121199136160d695",
[
@@ -568126,6 +568594,15 @@
}
]
],
+ "display-mode.https.html": [
+ "4888535357683d637030712c53ef9050bbf8cd65",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"enter-event.https.html": [
"1cac0ff22d79bbd98450b59d8fd8cffdb72ec141",
[
@@ -568135,6 +568612,15 @@
}
]
],
+ "focus-opener.https.html": [
+ "880e9d915efbc6db6f0cd1a9412070d871d4db86",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"iframe-document-pip.https.html": [
"b978a2d4e6ca2b28db67b9c3f0bed7e9cf4492b5",
[
@@ -569680,7 +570166,7 @@
]
],
"overscroll-event-fired-to-scrolled-element.html": [
- "cfc782a809a7e73a9d0a84d938caac6a704d784d",
+ "be4176df59d6a1d59d90beee839bc5ca6a72f1c5",
[
null,
{
@@ -572787,7 +573273,7 @@
"editing": {
"edit-context": {
"edit-context-basics.tentative.html": [
- "78b6824921a3bbbbf29a5f3e0d43da45e0555403",
+ "0011270c812fdd2ccea80699f0729ef2f7fc214e",
[
null,
{}
@@ -575746,6 +576232,13 @@
}
]
],
+ "paste-in-list-with-inline-style.tentative.html": [
+ "97710e805dd635f586cd2fafe6a443bd663122f4",
+ [
+ null,
+ {}
+ ]
+ ],
"recursive-exec-command-calls.tentative.html": [
"60a3b03099f358cf88e8e10c67347d9322cc9124",
[
@@ -589555,6 +590048,16 @@
}
]
],
+ "interactionid-keypress.html": [
+ "a6f200996714f473056a69e849837fffb1792dca",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
"interactionid-press-key-as-input.html": [
"b1e725b5c6f76d9eb3d413e679bfdeb331d1b0b2",
[
@@ -589629,6 +590132,15 @@
}
]
],
+ "modal-dialog-interrupt-paint.html": [
+ "011311a03a37df4e33e6b3a67d9c07ea2776843c",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"mousedown.html": [
"35a07faeb1bcaaadb0ca606f8948004b45a115ae",
[
@@ -592454,6 +592966,26 @@
}
]
],
+ "revoke-popup.https.html": [
+ "e4a2bb26ad2f74354bbeeb6e5f8edada9b30ba99",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
+ "revoke-unfenced-top-navigation.https.html": [
+ "873404768f0cdca9e912337f1829c47c67f7a9f1",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
"sandbox-attribute.https.html": [
"1458145e4377e573f8aa13f5cb4d0dfdc7e09182",
[
@@ -606729,20 +607261,36 @@
]
],
"dangling-markup": {
- "dangling-markup-mitigation-data-url.tentative.sub.html": [
+ "dangling-markup-mitigation-allowed-apis.html": [
+ "66456a8876b609fce084d40df0b280afeb48bffa",
+ [
+ null,
+ {}
+ ]
+ ],
+ "dangling-markup-mitigation-data-url.sub.html": [
"f27735daa1dd650726525d72a48b91d58d62535b",
[
null,
{}
]
],
- "dangling-markup-mitigation.tentative.html": [
+ "dangling-markup-mitigation.html": [
"61a931608ba5f3dc7f53f3f7a14ef5111737b07d",
[
null,
{}
]
],
+ "dangling-markup-mitigation.https.html": [
+ "3f038cbb7be452757196838539a7bf95e4f6e945",
+ [
+ null,
+ {
+ "timeout": "long"
+ }
+ ]
+ ],
"media.html": [
"2649edcf32008566c8d05352d42057fdedd4fa39",
[
@@ -607213,7 +607761,7 @@
]
],
"auction-config.https.window.js": [
- "3b5814b5d4aa5139684a52a1e62d3c45293f495f",
+ "8fbdc95dfc5596d9484608c1902909175781b53d",
[
"fledge/tentative/auction-config.https.window.html?1-5",
{
@@ -608054,7 +608602,7 @@
]
],
"component-auction.https.window.js": [
- "63771d42b86d361634bf2408d48caf1538c64278",
+ "c70532024ce87aaa7776c2b69a4a66abf61e2204",
[
"fledge/tentative/component-auction.https.window.html?1-5",
{
@@ -608233,7 +608781,7 @@
]
],
"cross-origin.https.window.js": [
- "788558e5cf364d2a3cc6b611d843ade2628821ff",
+ "a8cf93049fa05ced5c922f45890d3a3f680481aa",
[
"fledge/tentative/cross-origin.https.window.html?1-4",
{
@@ -608991,7 +609539,7 @@
]
],
"direct-from-seller-signals.https.window.js": [
- "339bc32ee564320d155f43e1a555847da7ec125b",
+ "d0c0e550c4232bd4dad1661b0b418084111a48a6",
[
"fledge/tentative/direct-from-seller-signals.https.window.html?1-4",
{
@@ -609487,10 +610035,10 @@
{}
]
],
- "generate-bid-recency.https.window.js": [
- "07da463a2dc50178a39a9ab5d8461a62d3152827",
+ "generate-bid-browser-signals.https.window.js": [
+ "3ab8bbf51f6baf80e9c6f293c53160c2be703242",
[
- "fledge/tentative/generate-bid-recency.https.window.html",
+ "fledge/tentative/generate-bid-browser-signals.https.window.html?1-last",
{
"script_metadata": [
[
@@ -609506,8 +610054,16 @@
"resources/fledge-util.sub.js"
],
[
+ "script",
+ "/common/subset-tests.js"
+ ],
+ [
"timeout",
"long"
+ ],
+ [
+ "variant",
+ "?1-last"
]
],
"timeout": "long"
@@ -611280,7 +611836,7 @@
]
],
"join-leave-ad-interest-group.https.window.js": [
- "b5dfe025bf275dbf8de24348147a3b6164ab5b2f",
+ "02148ef36b76b80178ee99775c4ae1dea534c01b",
[
"fledge/tentative/join-leave-ad-interest-group.https.window.html?1-10",
{
@@ -611859,7 +612415,7 @@
]
],
"kanon-status-below-threshold.https.window.js": [
- "4eac4a8e917b17a7e6d43b60261e5abdecad76e5",
+ "787283d687ff55e5a2b448764370416bfa90285e",
[
"fledge/tentative/kanon-status-below-threshold.https.window.html",
{
@@ -611885,7 +612441,7 @@
]
],
"kanon-status-not-calculated.https.window.js": [
- "a3ac19bd85e5f2abcedba9c973177bcf602d4cb2",
+ "4a750cd3529df529c63f0fa1cf4d083abeacc542",
[
"fledge/tentative/kanon-status-not-calculated.https.window.html",
{
@@ -612729,7 +613285,7 @@
]
],
"register-ad-beacon.https.window.js": [
- "19fab2ac1b1b825e51a65d5200b64a60eb8a611c",
+ "3643e4466277144a389b08d3f029f294aa0a4480",
[
"fledge/tentative/register-ad-beacon.https.window.html?1-5",
{
@@ -612852,7 +613408,7 @@
]
],
"reporting-arguments.https.window.js": [
- "f26a969328ff0ccbd5a8b867147c36ea93e53c96",
+ "c7c71202403edfe72f6d7a676c749839dc494e65",
[
"fledge/tentative/reporting-arguments.https.window.html?1-5",
{
@@ -613031,7 +613587,7 @@
]
],
"round-a-value.https.window.js": [
- "5bccd4ab078fee069404096ef868e4a15ebbaa57",
+ "90523e2256c3a5582ef188d41ab0adcc107ffd93",
[
"fledge/tentative/round-a-value.https.window.html",
{
@@ -613058,7 +613614,7 @@
]
],
"send-report-to.https.window.js": [
- "65a2520420675184032ffde2d1823e91928606c3",
+ "e3cf0a95f17c171444d79a2b0f16d0fe1f1acbd4",
[
"fledge/tentative/send-report-to.https.window.html?1-5",
{
@@ -614339,7 +614895,7 @@
]
],
"trusted-scoring-signals.https.window.js": [
- "67ae3577e4f1f0a3fbad8450924c11b32f10689f",
+ "4de5cfc0f394732cd29c76b9ad08bef4013444b8",
[
"fledge/tentative/trusted-scoring-signals.https.window.html?1-5",
{
@@ -651717,7 +652273,7 @@
]
],
"dir-assorted.window.js": [
- "0d4e4b82d9b9531087ed631fd38d9eb6ab6215e0",
+ "2017269f0bdfa186d9ceced3887f68480a89118e",
[
"html/dom/elements/global-attributes/dir-assorted.window.html",
{}
@@ -651822,7 +652378,7 @@
]
],
"the-anchor-attribute-003.tentative.html": [
- "fe4657aabb33e63f58d7b623d1fd27d55e38b7c6",
+ "ec2d8d5ead9673e307350bc7346a5f3b971a391b",
[
null,
{}
@@ -652171,196 +652727,196 @@
]
],
"element-render-blocking-001.tentative.html": [
- "9624b41a194946794fc17c71f66fb4cc2ec6abe1",
+ "36567f9d54adea41a703b23adac438e160f397cf",
[
null,
{}
]
],
"element-render-blocking-002.tentative.html": [
- "ab0fd511156bc9edb89fe9350d87a000616f2438",
+ "3c907597f7ac35b84e29ccd37627499c347f511a",
[
null,
{}
]
],
"element-render-blocking-003.tentative.html": [
- "eb3a347a6ebbb7b05a5e3bb7905c9098bf755c51",
+ "2858798a35f58e1152b7047c35359878d1820ecc",
[
null,
{}
]
],
"element-render-blocking-004.tentative.html": [
- "2c50f2d362a54c8252f92222a71025301222aa9f",
+ "f45f5587204674691349f298f9367204233aa235",
[
null,
{}
]
],
"element-render-blocking-005.tentative.html": [
- "04cdab467deff3f8880855592cd5724d064b3371",
+ "098a3c57676cc88788a23efa0818e00b9a8e6344",
[
null,
{}
]
],
"element-render-blocking-006.tentative.html": [
- "1c9da255a622503c2f2bb74fc98876938bce19e1",
+ "223e42109e5c65985e0aec2b0c24ef8f1d810d15",
[
null,
{}
]
],
"element-render-blocking-007.tentative.html": [
- "df8f9ae3d1258194088f4b8cbadbf2eee9b85500",
+ "9aa0aeea79834833ff0151227723c1a6c17e06e2",
[
null,
{}
]
],
"element-render-blocking-008.tentative.html": [
- "c2458a0bab31244de67c707d32b2669a5aaa746a",
+ "e671dda19c43b44d3f065b8de0e68f7326e88aba",
[
null,
{}
]
],
"element-render-blocking-009.tentative.html": [
- "d765ac8a5d3c9b742fa9b24d3401d6c1ff098a08",
+ "8498816ea5c435cce0ea3d597b7f0b381d73d7f6",
[
null,
{}
]
],
"element-render-blocking-010.tentative.html": [
- "7ef6a1baf35b460791ac54b8891dc3e019aaee85",
+ "ef6f709012e4bd4bb222b8cc74317abdbc40768f",
[
null,
{}
]
],
"element-render-blocking-011.tentative.html": [
- "31df9b068c01b5a149941f24d619898f6b926301",
+ "dee82d8c5950c16360d2ff799393a50bed1f7a95",
[
null,
{}
]
],
"element-render-blocking-012.tentative.html": [
- "8f2594d25903a60911f89d7eb6a39968ca2e9d82",
+ "4110e54c5f20420d8da783d21e43d2f9961aed5a",
[
null,
{}
]
],
"element-render-blocking-013.tentative.html": [
- "9d65bd96b73189f4fafbbcd59261261e0f154fb9",
+ "ecd97be86a6633daf0d03f86f231de295abee459",
[
null,
{}
]
],
"element-render-blocking-014.tentative.html": [
- "d042b96b64370c1ad08cd235729a2c0e6abb597e",
+ "ea8948de42dec015384aa2bd7a13edb283b6d522",
[
null,
{}
]
],
"element-render-blocking-015.tentative.html": [
- "f7ac0b1015d79635d83fced00cbcb8c7c5e6400b",
+ "a775ee417403ab3fef3635194ff1d62b4c335266",
[
null,
{}
]
],
"element-render-blocking-016.tentative.html": [
- "d32a0468e79b4109607d920ec72279ae0af0e0d6",
+ "8968c5dacd329537b9d7c1d0d0ce38786077f583",
[
null,
{}
]
],
"element-render-blocking-017.tentative.html": [
- "d3a6046cbb37f90b3bf5721f1799f8df313d06c7",
+ "2d3b5747216f50902714bff725cddf50ec7556c0",
[
null,
{}
]
],
"element-render-blocking-018.tentative.html": [
- "0d7402201accb05ce81636be43057128cfaf976b",
+ "76e6394b5b16586de768ad553c671b8594d0635e",
[
null,
{}
]
],
"element-render-blocking-019.tentative.html": [
- "fea9e3a2b21821722eb956beac19acfb44721034",
+ "80a7019edc4beb272ef65d7cd1d28f88fb18a813",
[
null,
{}
]
],
"element-render-blocking-020.tentative.html": [
- "7fc0fe19bbae57d15b5a8bbc27cfb6400661114b",
+ "10019c943f402c91c0ca07efefe462d5bc6ece48",
[
null,
{}
]
],
"element-render-blocking-021.tentative.html": [
- "29430349f04689578cc7e5f90ba86ef77626bde5",
+ "1ca2114689a6cdbc961c9eecd1fa4e328117d431",
[
null,
{}
]
],
"element-render-blocking-022.tentative.html": [
- "6548c9ec4df21169af9c97dfa30acf49acb1c95a",
+ "5dfbcac30a4c065a888f5ea804ba306758d83e6c",
[
null,
{}
]
],
"element-render-blocking-023.tentative.html": [
- "c3661bcaa6a9c3b2e6fc64dc937c73688041a43d",
+ "8fe8b6a8c8e30f05250c2ca569f5b4d938bed71c",
[
null,
{}
]
],
"element-render-blocking-024.tentative.html": [
- "c98022cfeabef10171061432168274eb81324834",
+ "19e4020fb769bb59053a6a64cc1c499583044c73",
[
null,
{}
]
],
"element-render-blocking-025.tentative.html": [
- "29868b92cbc76a7f9b6da3e645e02c0701f5e31b",
+ "689ae69f452d421b66554c8e547ca95f5f269af9",
[
null,
{}
]
],
"element-render-blocking-026.tentative.html": [
- "dc23211b8b00d2011592dd529bd554670456acc5",
+ "6abfc43b8b237b3f8f0f6474d36fcce1c3aaac52",
[
null,
{}
]
],
"element-render-blocking-027.tentative.html": [
- "5b8a5eb24d5e973a25ca8fbf594f85f006ba7a06",
+ "56f88e0fc2b773f74afb86e306f42a1aa39d9c1b",
[
null,
{}
]
],
"element-render-blocking-028.tentative.html": [
- "57ba3d602602d59f55bdaa34d18eeb06254e826a",
+ "a64d542c4ac7ef97a2e3427dabe485519da97518",
[
null,
{}
@@ -652921,6 +653477,15 @@
{}
]
]
+ },
+ "writing-suggestions": {
+ "writingsuggestions.html": [
+ "664659d90ab37cf8692c3cd780e1313df034ad86",
+ [
+ null,
+ {}
+ ]
+ ]
}
},
"focus": {
@@ -660153,6 +660718,69 @@
{}
]
],
+ "iframe-loading-lazy-in-scroller-far.html": [
+ "eeb05b7b98ec1bf96a2912f8b174edc0dad53cb9",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-horizontal-far.html": [
+ "f058b46fbd9fa80288eb4d09b0e1ed54afa5c4c6",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-horizontal.html": [
+ "80ba0829a9a5465030507b10908f1ddc924a4662",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-nested-2.html": [
+ "9eec621c891e8357818a9646e3822c19618a95a0",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-nested-3.html": [
+ "aa02bb415161340f7264cbada530b848fac8bc84",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-nested-4.html": [
+ "e15d891fb5b5d86bc787e84838b31f9a61f3f948",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-nested-5.html": [
+ "b36265024d55366a315905e43a8403ca46cd60ef",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller-nested.html": [
+ "50b5e7ee0adc6a38aa2145a48a2bf345543ced43",
+ [
+ null,
+ {}
+ ]
+ ],
+ "iframe-loading-lazy-in-scroller.html": [
+ "631710e740de48dc925d3a778662c17b39061c3b",
+ [
+ null,
+ {}
+ ]
+ ],
"iframe-loading-lazy-load-event.html": [
"bf98bf7585cf608e6ebb46d025663e22bce8324c",
[
@@ -662761,6 +663389,13 @@
{}
]
],
+ "form-indexed-element-shadow.html": [
+ "a108ce8a93fcc75bc9144b6409c083943fcb93f3",
+ [
+ null,
+ {}
+ ]
+ ],
"form-indexed-element.html": [
"5ea96d3d1b21ac6d143b01ec325261a5255c1e8a",
[
@@ -665608,6 +666243,13 @@
}
]
],
+ "popover-open-overflow-display-2.html": [
+ "f2388b7642e49f90bcc3ad79e51db40e1001c5f0",
+ [
+ null,
+ {}
+ ]
+ ],
"popover-overlay.html": [
"a607844aee4f59e2a8b96528bbfa380688a1bb34",
[
@@ -676728,7 +677370,7 @@
]
],
"inert-iframe-hittest.html": [
- "8d7facf17230d70350adf4cd54a32151e30fc11b",
+ "d6c3551e996e4ae727096f1bef82b5706fd5bc97",
[
null,
{
@@ -685012,7 +685654,7 @@
]
],
"MediaRecorder-mimetype.html": [
- "30df91c9587e32040207aecd862fbe04691f43e3",
+ "74248d65f4660a25742d7baa5d050e40ed4199bd",
[
null,
{}
@@ -691238,6 +691880,15 @@
]
}
]
+ ],
+ "rounding.https.html": [
+ "846da79dfb545434290043b36bbf0c3fb447cf42",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
},
"orientation": {
@@ -691303,7 +691954,7 @@
]
],
"null-values.https.html": [
- "c54d73da50cdc2eedf07c80a5033d66ac42cc507",
+ "9505e009542076ef39dc827da46176f7df7558df",
[
null,
{
@@ -691345,6 +691996,15 @@
}
]
],
+ "rounding.https.html": [
+ "89bfa1d53c3571064a5f802c787602ee73c60986",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"updates.https.html": [
"fe1811535b3b473336dbf90f65279511a6c93284",
[
@@ -692918,7 +693578,7 @@
],
"not-restored-reasons": {
"abort-block-bfcache.window.js": [
- "8488dd60ccf0a1d6ed032c461e6bb714e24950a7",
+ "09a73509b8a834eca47032972d90b14c430bd1af",
[
"performance-timeline/not-restored-reasons/abort-block-bfcache.window.html",
{
@@ -693207,7 +693867,7 @@
]
],
"performance-navigation-timing-navigation-failure.tentative.window.js": [
- "4022e6e59f1c010207051697d0bf098143bfc309",
+ "5812ebb2b3637c9528997c369fc55c69a7ab3d39",
[
"performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.html",
{
@@ -696955,7 +697615,7 @@
]
],
"prefetch-document.html": [
- "bdb12bd58a036a1f7429e362acb078f0d2f75d4b",
+ "9f9810be46cc43ddcfacae40e1f53f4ac45af7e5",
[
null,
{}
@@ -715033,7 +715693,7 @@
]
],
"modifying-selection-with-non-primary-mouse-button.tentative.html": [
- "cb2e44295a9405e8a247bcc0aa9760e42a0b8286",
+ "79fc52ac7dbfa75884cef22017e89df1f38a9e4c",
[
"selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html?middle",
{
@@ -718980,7 +719640,7 @@
]
],
"declarative-shadow-dom-basic.html": [
- "8bc6bec5f50f741e8b48e5c2f1020707c8d56408",
+ "4f174b8e5f7c4afab0c49b665788aa3bbf8d41be",
[
null,
{}
@@ -718993,8 +719653,15 @@
{}
]
],
+ "declarative-shadow-dom-repeats-2.html": [
+ "74b14b8d8ff679f889297b3d21d14eb090a9ff27",
+ [
+ null,
+ {}
+ ]
+ ],
"declarative-shadow-dom-repeats.html": [
- "69f5c0f077afbc651fdeb7c8f99091942ef2f57d",
+ "9cee41f2f3160e19c279693bd27d1794b46bc5be",
[
null,
{}
@@ -720523,6 +721190,48 @@
{}
]
],
+ "same-origin-add-module-credentials-include.tentative.https.sub.html": [
+ "a9082661a8b6cee451e7258b154631e2d1f1831d",
+ [
+ null,
+ {}
+ ]
+ ],
+ "same-origin-add-module-credentials-omit.tentative.https.sub.html": [
+ "a5945725c010950aaacf5e252ffc4ebdb096158f",
+ [
+ null,
+ {}
+ ]
+ ],
+ "same-origin-add-module-credentials-same-origin.tentative.https.sub.html": [
+ "aea76264384afffe37da04e919e843d554a87637",
+ [
+ null,
+ {}
+ ]
+ ],
+ "same-origin-create-worklet-credentials-include.tentative.https.sub.html": [
+ "2e1d9cf723562416844c1ee550073b7bac4ee2d7",
+ [
+ null,
+ {}
+ ]
+ ],
+ "same-origin-create-worklet-credentials-omit.tentative.https.sub.html": [
+ "ef90c02d6434a6b472e618e3f3d95ad7e4d08775",
+ [
+ null,
+ {}
+ ]
+ ],
+ "same-origin-create-worklet-credentials-same-origin.tentative.https.sub.html": [
+ "6d9fd7c1362a06930df2f71d3c2fbd193e2746d4",
+ [
+ null,
+ {}
+ ]
+ ],
"select-url-keep-alive.tentative.https.sub.html": [
"f3755538b9d4b23e026fec85c161cb730531d4dc",
[
@@ -721501,7 +722210,7 @@
]
],
"replacestate.tentative.html": [
- "42e9a718997bec9327ace8936225b42b6356a77b",
+ "d47b9b653881f57e085fef94360c9245e23c022f",
[
null,
{
@@ -724780,7 +725489,7 @@
]
],
"requestStorageAccess-dedicated-worker.tentative.sub.https.window.js": [
- "f2d766575db00ca877570bc31e91810b978af7cd",
+ "6c3d616e26aaa796e9aa7226621f0430cff2d4b2",
[
"storage-access-api/requestStorageAccess-dedicated-worker.tentative.sub.https.window.html",
{
@@ -724997,7 +725706,7 @@
]
],
"storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js": [
- "d709cdcd10f807f2f2e879d560cd9f85fd4abc51",
+ "feb268b4b8146290eec743779c4a8d9567bc74b3",
[
"storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.html",
{
@@ -725014,8 +725723,26 @@
}
]
],
+ "storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.js": [
+ "ed4f25517f71604b12d401b8777a6814a27c72d3",
+ [
+ "storage-access-api/storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.html",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "/resources/testdriver.js"
+ ],
+ [
+ "script",
+ "/resources/testdriver-vendor.js"
+ ]
+ ]
+ }
+ ]
+ ],
"storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js": [
- "6ef0bd08d4dc7175a1b241baa348776172b34d8c",
+ "cc2785b6fac73ffbd3a18c8bd23228a1c8130e9c",
[
"storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.html",
{
@@ -725033,7 +725760,7 @@
]
],
"storage-access-beyond-cookies.caches.tentative.sub.https.window.js": [
- "dda1e54565407ed438f9f23b6f0c84336e7b7748",
+ "7907084e6381471c9c3630ca8879673d68ae7482",
[
"storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.html",
{
@@ -725051,7 +725778,7 @@
]
],
"storage-access-beyond-cookies.cookies.tentative.sub.https.window.js": [
- "c352ab2935540fb5d99a79ceceff4b90e781d263",
+ "1ff00fa91938df81d1c0fc7e774f12973e12e917",
[
"storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.html",
{
@@ -725069,7 +725796,7 @@
]
],
"storage-access-beyond-cookies.estimate.tentative.sub.https.window.js": [
- "2e9f6eed127898a21c890b6f6dfe588db9197852",
+ "fb15dfee0928810e3517fe80ec5eb6600fbdef4d",
[
"storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.html",
{
@@ -725087,7 +725814,7 @@
]
],
"storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js": [
- "5038afc969afd8139b099a42ca0e2df65554b91a",
+ "b3b8f7e8e2301fc1e9ae69fcf6ae0c23f70075b7",
[
"storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.html",
{
@@ -725105,7 +725832,7 @@
]
],
"storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js": [
- "18c4317bbe9c6598551787feaf9df9d4ad5210db",
+ "8e9420da0da652f4bade46c9deedd66af8decf3c",
[
"storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.html",
{
@@ -725123,7 +725850,7 @@
]
],
"storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js": [
- "6243cb1fa8c5c25e15747dfc22de3f3c108eea98",
+ "80021317790587e8da7fea06324cc03a1504a8ce",
[
"storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.html",
{
@@ -725141,7 +725868,7 @@
]
],
"storage-access-beyond-cookies.locks.tentative.sub.https.window.js": [
- "83aa28c018e1a3e4fd0b5ffe794a2acb751de287",
+ "ed7d6ea48479a1b2a433db5f438ab001bae93598",
[
"storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.html",
{
@@ -725159,7 +725886,7 @@
]
],
"storage-access-beyond-cookies.none.tentative.sub.https.window.js": [
- "3715fdf39ed562a3946c9ed3406e9d81de57ea7a",
+ "ba5ea3279dffe0253f29293536ce2b408a4fe72a",
[
"storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.html",
{
@@ -725177,7 +725904,7 @@
]
],
"storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js": [
- "1b12f133b2c36ea2ed8eaa3cfd86b8d268dbff9c",
+ "93b243f6c1104401f05aff207acdf16186b97899",
[
"storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.html",
{
@@ -735181,7 +735908,7 @@
{}
]
],
- "trusted-types-from-literal.html": [
+ "trusted-types-from-literal.tentative.html": [
"a7d5659e16a1471ac5cb900dce7b3a102a14af89",
[
null,
@@ -748841,7 +749568,7 @@
]
],
"osc-basic-waveform.html": [
- "abd1ff8d0e5d8453bfbfd1e37dc7c36ef4337f40",
+ "ce6e262fa9f60fdf66498d6f787e315f7176f93f",
[
null,
{}
@@ -760752,7 +761479,7 @@
]
],
"RTCPeerConnection-setRemoteDescription-offer.html": [
- "d5acb7e1c933aa13a774b69f54ba4282905d2f4d",
+ "9da03fe7a1596356ea1f44591e6036938d912d16",
[
null,
{}
@@ -760905,7 +761632,7 @@
]
],
"RTCRtpReceiver-getStats.https.html": [
- "d9344b176e39dcb697d11b70a626706f4b794445",
+ "2fcf33dc2e4aac738f3da39663a7812320deb5e2",
[
null,
{
@@ -760939,7 +761666,7 @@
]
],
"RTCRtpSender-getStats.https.html": [
- "797365e9f4e89b649839fb9b7bc8a19b879df672",
+ "6aeed650e58c7be225b773095b8f035cd216d5d0",
[
null,
{
@@ -761003,7 +761730,7 @@
]
],
"RTCRtpTransceiver-setCodecPreferences.html": [
- "f779f5a94ca4959004c90f2331783ceed4c21820",
+ "120b28527fbb6db33e07bc7ff5a28261168f4c30",
[
null,
{}
@@ -761184,7 +761911,7 @@
]
],
"back-forward-cache-with-open-webrtc-connection.https.window.js": [
- "a516aa4c79988fabceca08da087c56734175ca0f",
+ "5cc3b745b3bc830aa3931db6556a2b21b0af112a",
[
"webrtc/back-forward-cache-with-open-webrtc-connection.https.window.html",
{
@@ -761986,10 +762713,12 @@
]
],
"RTCRtpParameters-codec.html": [
- "cce2c1661f7d7761da12d2ee4ba7be1446fcfe9b",
+ "5fc1401badf49d6fbc2f46c9936b3711cd3c2466",
[
null,
- {}
+ {
+ "timeout": "long"
+ }
]
],
"RTCRtpReceiver-jitterBufferTarget-stats.html": [
@@ -762214,7 +762943,7 @@
]
],
"RTCRtpParameters-scalability.html": [
- "ff28c2b5e95636708568cdc20c5da5fc2db0dcba",
+ "134a28bd5e13eaf47ced84a5694f9a38f4851b05",
[
null,
{
@@ -780793,7 +781522,7 @@
],
"same-site-cookies": {
"first-party.all.tentative.https.window.js": [
- "d7e5f2ee42ca31d1e05ebfd68c7c1aefb75d411f",
+ "ac6030e654031d33bdf9c47f7b6d848fb514248b",
[
"workers/same-site-cookies/first-party.all.tentative.https.window.html",
{
@@ -780805,13 +781534,17 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
]
],
"first-party.default.tentative.https.window.js": [
- "b120014c1a82bacb64a51c06799731e82b5d4ecd",
+ "2c64ff628f5b86e09005c2b8a5b4f90d5af2bffd",
[
"workers/same-site-cookies/first-party.default.tentative.https.window.html",
{
@@ -780823,13 +781556,17 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
]
],
"first-party.none.tentative.https.window.js": [
- "762d924eb92c03380252b62db29fbdb0f3f33e0d",
+ "76a8b1d8bcb50e97c633c1ab096f81425e463d08",
[
"workers/same-site-cookies/first-party.none.tentative.https.window.html",
{
@@ -780841,13 +781578,17 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
]
],
"third-party.all.tentative.sub.https.window.js": [
- "51ad1d3b02543baa10ba62e4ab9e0e8b7afb7230",
+ "21b53819d93f7a1b0cf1db4f13e32316150cec6d",
[
"workers/same-site-cookies/third-party.all.tentative.sub.https.window.html",
{
@@ -780859,13 +781600,17 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
]
],
"third-party.default.tentative.sub.https.window.js": [
- "194df38390ed40e8127aede98b507bdd92da048a",
+ "bf499c1992c91f0401c3f38067eb3e6208147bfe",
[
"workers/same-site-cookies/third-party.default.tentative.sub.https.window.html",
{
@@ -780877,13 +781622,17 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
]
],
"third-party.none.tentative.sub.https.window.js": [
- "b91b9d7ab27ce80b94db4dd8a51866b1e843ea7f",
+ "f00e585f77839274c51b8099b623095c7932bfd1",
[
"workers/same-site-cookies/third-party.none.tentative.sub.https.window.html",
{
@@ -780895,6 +781644,10 @@
[
"script",
"/resources/testdriver-vendor.js"
+ ],
+ [
+ "script",
+ "/workers/same-site-cookies/resources/util.js"
]
]
}
@@ -806939,7 +807692,7 @@
},
"fragment_navigated": {
"fragment_navigated.py": [
- "a4bd012588d28af69af634b06b288274c63a35ff",
+ "fb690807f214632add89f1de98b90789fdb1117b",
[
null,
{}
@@ -807471,6 +808224,15 @@
]
}
},
+ "integration": {
+ "navigation.py": [
+ "23615040c78710d0810591983f183c5cc8954b40",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"log": {
"entry_added": {
"console.py": [
@@ -808221,6 +808983,29 @@
}
},
"storage": {
+ "get_cookies": {
+ "filter.py": [
+ "b244ef86ac24d22c619fcdbc73f32d3edee828cc",
+ [
+ null,
+ {}
+ ]
+ ],
+ "invalid.py": [
+ "fbd5647f30345387e0d63e4741d2f630f47a4e1c",
+ [
+ null,
+ {}
+ ]
+ ],
+ "partition.py": [
+ "a1c26503525034614a1861b3512b60144df9f2ca",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"set_cookie": {
"cookie_domain.py": [
"558d49c186c26361ec7f98e363abc34462a0e481",
@@ -808279,7 +809064,7 @@
]
],
"invalid.py": [
- "24f6153402d8cebee6f5c371e18020d2c485a6a2",
+ "53d2573575b645b76c2e101c833e28e87e7d86b4",
[
null,
{}
@@ -809067,7 +809852,7 @@
},
"get_element_text": {
"get.py": [
- "547152b2a72e3c9d27da81c010fd681378e6529d",
+ "924a4e8d79771d78de59e48f61bb6e88ab34a7b9",
[
null,
{}
diff --git a/tests/wpt/meta/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini b/tests/wpt/meta/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini
new file mode 100644
index 00000000000..fcc2d8205dd
--- /dev/null
+++ b/tests/wpt/meta/css/css-borders/border-image-width-interpolation-math-functions-tentative.html.ini
@@ -0,0 +1,144 @@
+[border-image-width-interpolation-math-functions-tentative.html]
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <border-image-width> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-color/parsing/color-computed-color-mix-function.html.ini b/tests/wpt/meta/css/css-color/parsing/color-computed-color-mix-function.html.ini
index 3f3a52b9d50..49dceb7d0a5 100644
--- a/tests/wpt/meta/css/css-color/parsing/color-computed-color-mix-function.html.ini
+++ b/tests/wpt/meta/css/css-color/parsing/color-computed-color-mix-function.html.ini
@@ -814,3 +814,27 @@
[Property color value 'color-mix(in oklch, oklab(0.5 0 0), black)']
expected: FAIL
+
+ [Property color value 'color-mix(in hsl, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hsl, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hwb, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in hwb, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in lch, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in lch, white 10%, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in oklch, white, blue)']
+ expected: FAIL
+
+ [Property color value 'color-mix(in oklch, white 10%, blue)']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-color/parsing/color-valid-hsl.html.ini b/tests/wpt/meta/css/css-color/parsing/color-valid-hsl.html.ini
index fb22c6bf352..a3d8c949834 100644
--- a/tests/wpt/meta/css/css-color/parsing/color-valid-hsl.html.ini
+++ b/tests/wpt/meta/css/css-color/parsing/color-valid-hsl.html.ini
@@ -49,3 +49,12 @@
[e.style['color'\] = "hsl(120 30 50 / none)" should set the property value]
expected: FAIL
+
+ [e.style['color'\] = "hsl(30 -50% 60)" should set the property value]
+ expected: FAIL
+
+ [e.style['color'\] = "hsl(0 -50 40%)" should set the property value]
+ expected: FAIL
+
+ [e.style['color'\] = "hsl(30 -50 60)" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini b/tests/wpt/meta/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini
new file mode 100644
index 00000000000..ac7fa1b4461
--- /dev/null
+++ b/tests/wpt/meta/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html.ini
@@ -0,0 +1,144 @@
+[font-size-adjust-interpolation-math-functions.tentative.html]
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [100\] to [calc(sign(20rem - 20px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (-1) should be [20\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0) should be [100\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.125) should be [110\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (0.875) should be [170\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (1) should be [180\]]
+ expected: FAIL
+
+ [Web Animations: property <font-size-adjust> from [calc(sign(20rem - 20px) * 100)\] to [calc(progress(10rem from 20px to 100px) * 180)\] at (2) should be [260\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini b/tests/wpt/meta/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini
new file mode 100644
index 00000000000..30f9f12ae64
--- /dev/null
+++ b/tests/wpt/meta/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html.ini
@@ -0,0 +1,144 @@
+[font-stretch-interpolation-math-functions.tentative.html]
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [100%\] to [calc(sign(20rem - 20px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Transitions with transition: all: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [CSS Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (-1) should be [20%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0) should be [100%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.125) should be [110%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (0.875) should be [170%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (1) should be [180%\]]
+ expected: FAIL
+
+ [Web Animations: property <font-stretch> from [calc(sign(20rem - 20px) * 100%)\] to [calc(progress(10rem from 20px to 100px) * 180%)\] at (2) should be [260%\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini b/tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini
index d62a72d17db..0a47945caf9 100644
--- a/tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini
+++ b/tests/wpt/meta/css/css-fonts/variations/at-font-face-font-matching.html.ini
@@ -313,3 +313,15 @@
[Matching font-style: 'oblique -10deg' should prefer 'oblique -50deg -40deg' over 'italic']
expected: FAIL
+
+ [Matching font-weight: '430' should prefer '450 460' over '500']
+ expected: FAIL
+
+ [Matching font-weight: '399' should prefer '400' over '450 460']
+ expected: FAIL
+
+ [Matching font-style: 'oblique 10deg' should prefer 'oblique 10deg' over 'oblique 5deg']
+ expected: FAIL
+
+ [Matching font-style: 'oblique -21deg' should prefer 'oblique -21deg' over 'oblique -60deg -40deg']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-transitions/starting-style-cascade.html.ini b/tests/wpt/meta/css/css-transitions/starting-style-cascade.html.ini
index b29e178ab54..4fcdc07a655 100644
--- a/tests/wpt/meta/css/css-transitions/starting-style-cascade.html.ini
+++ b/tests/wpt/meta/css/css-transitions/starting-style-cascade.html.ini
@@ -1,4 +1,5 @@
[starting-style-cascade.html]
+ expected: ERROR
[Overridden @starting-style - order of appearance]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-transitions/starting-style-rule-none.html.ini b/tests/wpt/meta/css/css-transitions/starting-style-rule-none.html.ini
index f01ead5128a..1ade9851ece 100644
--- a/tests/wpt/meta/css/css-transitions/starting-style-rule-none.html.ini
+++ b/tests/wpt/meta/css/css-transitions/starting-style-rule-none.html.ini
@@ -1,3 +1,4 @@
[starting-style-rule-none.html]
+ expected: ERROR
[@starting-style with display:none]
expected: FAIL
diff --git a/tests/wpt/meta/css/css-variables/variables-animation-math-functions-tentative.html.ini b/tests/wpt/meta/css/css-variables/variables-animation-math-functions-tentative.html.ini
new file mode 100644
index 00000000000..fc4c1ab570a
--- /dev/null
+++ b/tests/wpt/meta/css/css-variables/variables-animation-math-functions-tentative.html.ini
@@ -0,0 +1,108 @@
+[variables-animation-math-functions-tentative.html]
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [100deg\] to [calc(sign(20rem - 20px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Transitions: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [CSS Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (-1) should be [20deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0) should be [100deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.125) should be [110deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (0.875) should be [170deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (1) should be [180deg\]]
+ expected: FAIL
+
+ [Web Animations: property <--my-angle> from [calc(sign(20rem - 20px) * 100deg)\] to [calc(progress(10rem from 20px to 100px) * 180deg)\] at (2) should be [260deg\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/cssom/getComputedStyle-pseudo-with-argument.html.ini b/tests/wpt/meta/css/cssom/getComputedStyle-pseudo-with-argument.html.ini
new file mode 100644
index 00000000000..2507753f7ef
--- /dev/null
+++ b/tests/wpt/meta/css/cssom/getComputedStyle-pseudo-with-argument.html.ini
@@ -0,0 +1,15 @@
+[getComputedStyle-pseudo-with-argument.html]
+ [This pseudo-element should parse: ::highlight(name)]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight(\nname]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight(name\t]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight( name ]
+ expected: FAIL
+
+ [This pseudo-element should parse: ::highlight( n\\61me )]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/mediaqueries/display-mode.html.ini b/tests/wpt/meta/css/mediaqueries/display-mode.html.ini
index 5a1060ad0f6..69978c1538a 100644
--- a/tests/wpt/meta/css/mediaqueries/display-mode.html.ini
+++ b/tests/wpt/meta/css/mediaqueries/display-mode.html.ini
@@ -16,3 +16,6 @@
[Check that display-mode evaluates to true in the boolean context]
expected: FAIL
+
+ [Should be known: '(display-mode: picture-in-picture)']
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-001.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-001.html.ini
new file mode 100644
index 00000000000..af98ad1abe4
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-001.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-001.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-002.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-002.html.ini
new file mode 100644
index 00000000000..b161ef70a25
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-002.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-002.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-003.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-003.html.ini
new file mode 100644
index 00000000000..85c7b37aac7
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-003.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-003.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-004.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-004.html.ini
new file mode 100644
index 00000000000..81842b8f8cb
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-004.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-004.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-005.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-005.html.ini
new file mode 100644
index 00000000000..245fb34babc
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-005.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-005.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-006.html.ini b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-006.html.ini
new file mode 100644
index 00000000000..40739ba8a40
--- /dev/null
+++ b/tests/wpt/meta/css/selectors/has-style-sharing-pseudo-006.html.ini
@@ -0,0 +1,2 @@
+[has-style-sharing-pseudo-006.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini
new file mode 100644
index 00000000000..6c1cf88513e
--- /dev/null
+++ b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html.ini
@@ -0,0 +1,3 @@
+[dangling-markup-mitigation-allowed-apis.html]
+ [Does not block window.open(`resources/empty.html?\n<`,'_self')]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini
index 5af5dc2813d..429fb6d6f29 100644
--- a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html.ini
+++ b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html.ini
@@ -1,4 +1,4 @@
-[dangling-markup-mitigation-data-url.tentative.sub.html]
+[dangling-markup-mitigation-data-url.sub.html]
[<img id="dangling" src="data:image/svg+xml;utf8,\\n <svg width='1' height='1' xmlns='http://www.w3.org/2000/svg'>\\n <rect width='100%' height='100%' fill='rebeccapurple'/>\\n <rect x='10%' y='10%' width='80%' height='80%' fill='lightgreen'/>\\n </svg>">]
expected: FAIL
diff --git a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini
index 3b0a8472abf..c7893561e27 100644
--- a/tests/wpt/meta-legacy-layout/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html.ini
+++ b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.html.ini
@@ -1,4 +1,4 @@
-[dangling-markup-mitigation.tentative.html]
+[dangling-markup-mitigation.html]
[Fetch: /images/gre\\nen-1x1.png?img=<]
expected: FAIL
diff --git a/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini
new file mode 100644
index 00000000000..50ec2d74bb6
--- /dev/null
+++ b/tests/wpt/meta/fetch/security/dangling-markup/dangling-markup-mitigation.https.html.ini
@@ -0,0 +1,3 @@
+[dangling-markup-mitigation.https.html]
+ [Only blocks dangling markup requests]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
index b8fd22e2b81..149bcb4ff8c 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html.ini
@@ -10,6 +10,3 @@
[load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank']
expected: FAIL
-
- [load & pageshow events do not fire on contentWindow of <iframe> element created with src='']
- expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.js.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.js.ini
index d203e3d160a..5a245d61359 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.js.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-referrer.window.js.ini
@@ -1,10 +1,6 @@
[javascript-url-referrer.window.html]
- expected: TIMEOUT
[unsafe-url referrer policy used to create the starting page]
expected: FAIL
[origin referrer policy used to create the starting page]
- expected: TIMEOUT
-
- [no-referrer referrer policy used to create the starting page]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
new file mode 100644
index 00000000000..a03a8322165
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
@@ -0,0 +1,3 @@
+[traverse_the_history_3.html]
+ [Multiple history traversals, last would be aborted]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini
new file mode 100644
index 00000000000..e7c121bc3d8
--- /dev/null
+++ b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.html.ini
@@ -0,0 +1,2 @@
+[2d.layer.drawImage.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini
new file mode 100644
index 00000000000..bfd27f9b357
--- /dev/null
+++ b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.drawImage.w.html.ini
@@ -0,0 +1,2 @@
+[2d.layer.drawImage.w.html]
+ expected: TIMEOUT
diff --git a/tests/wpt/meta/html/dom/elements/global-attributes/dir-assorted.window.js.ini b/tests/wpt/meta/html/dom/elements/global-attributes/dir-assorted.window.js.ini
index 6d541106aee..64245a9ccfe 100644
--- a/tests/wpt/meta/html/dom/elements/global-attributes/dir-assorted.window.js.ini
+++ b/tests/wpt/meta/html/dom/elements/global-attributes/dir-assorted.window.js.ini
@@ -94,3 +94,9 @@
[directionality of bdi elements: no dir attribute empty in rtl parent]
expected: FAIL
+
+ [directionality of bdi elements: dir=auto numbers in ltr parent]
+ expected: FAIL
+
+ [directionality of bdi elements: dir=auto numbers in rtl parent]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/elements/global-attributes/dir-shadow-42.html.ini b/tests/wpt/meta/html/dom/elements/global-attributes/dir-shadow-42.html.ini
new file mode 100644
index 00000000000..1a4b5035cc0
--- /dev/null
+++ b/tests/wpt/meta/html/dom/elements/global-attributes/dir-shadow-42.html.ini
@@ -0,0 +1,2 @@
+[dir-shadow-42.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini
new file mode 100644
index 00000000000..346d7282c0a
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-001.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-001.tentative.html]
+ [blocking defers frames until full parsing]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini
new file mode 100644
index 00000000000..92a6b95f046
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-003.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-003.tentative.html]
+ [adding link in the head defers frames]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini
deleted file mode 100644
index b3fd8fa38aa..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-004.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-004.tentative.html]
- [removing link in the head makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini
deleted file mode 100644
index 42f9c7342db..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-005.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-005.tentative.html]
- [removing 'blocking' makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini
new file mode 100644
index 00000000000..a6e9373200b
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-006.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-006.tentative.html]
+ [adding 'blocking=render' in the head makes it blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini
deleted file mode 100644
index 6c63b2db412..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-007.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-007.tentative.html]
- [link with non-matching media has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini
new file mode 100644
index 00000000000..9561d696beb
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-008.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-008.tentative.html]
+ [changing media to matching causes link to have an effect]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini
deleted file mode 100644
index 3c105de1140..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-009.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-009.tentative.html]
- [changing media to non-matching makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini
deleted file mode 100644
index ef4e023dfa6..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-010.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-010.tentative.html]
- [changing rel to non-expect makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini
new file mode 100644
index 00000000000..0675b813616
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-011.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-011.tentative.html]
+ [changing rel to expect in the head causes it to be blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini
new file mode 100644
index 00000000000..1e31c3f000e
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-012.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-012.tentative.html]
+ [adding href in the head makes it blocking]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini
deleted file mode 100644
index 9ce1660b44c..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-013.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-013.tentative.html]
- [removing href makes it no longer blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini
deleted file mode 100644
index d338af1ff52..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-014.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-014.tentative.html]
- [link in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini
deleted file mode 100644
index 0dd5e871106..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-015.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-015.tentative.html]
- [removing link the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini
deleted file mode 100644
index 7718cf5bef3..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-016.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-016.tentative.html]
- [removing 'blocking' in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini
deleted file mode 100644
index 3c50d660460..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-017.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-017.tentative.html]
- [adding 'blocking=render' in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini
deleted file mode 100644
index 98fda576808..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-018.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-018.tentative.html]
- [changing media to matching in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini
deleted file mode 100644
index 55b1e8fcbc4..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-019.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-019.tentative.html]
- [changing media to non-matching in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini
deleted file mode 100644
index d9ca447f339..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-020.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-020.tentative.html]
- [changing rel to non-expect in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini
deleted file mode 100644
index 9944597e235..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-021.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-021.tentative.html]
- [changing rel to expect in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini
deleted file mode 100644
index 17d86d7881a..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-022.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-022.tentative.html]
- [adding href in the body has no effect]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini
deleted file mode 100644
index a0bd7e500ca..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-023.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-023.tentative.html]
- [removing href in the body makes it non blocking]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini
new file mode 100644
index 00000000000..3e821238f4e
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-024.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-024.tentative.html]
+ [unknown href causes the whole document to be blocked]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini
deleted file mode 100644
index 6d1a662295c..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-025.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-025.tentative.html]
- [adding an id in the body satisfies render block]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini
deleted file mode 100644
index 76fadb90c93..00000000000
--- a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-026.tentative.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[element-render-blocking-026.tentative.html]
- [removing id after it was renderer keeps render block satisfied]
- expected: FAIL
diff --git a/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini
new file mode 100644
index 00000000000..61f04ef7a4d
--- /dev/null
+++ b/tests/wpt/meta/html/dom/render-blocking/element-render-blocking-027.tentative.html.ini
@@ -0,0 +1,3 @@
+[element-render-blocking-027.tentative.html]
+ [unknown href causes the whole document to be blocked (with href changes!)]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/editing/editing-0/writing-suggestions/writingsuggestions.html.ini b/tests/wpt/meta/html/editing/editing-0/writing-suggestions/writingsuggestions.html.ini
new file mode 100644
index 00000000000..08e8213eeb3
--- /dev/null
+++ b/tests/wpt/meta/html/editing/editing-0/writing-suggestions/writingsuggestions.html.ini
@@ -0,0 +1,222 @@
+[writingsuggestions.html]
+ [Test that the writingsuggestions attribute is available on HTMLInputElement.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on HTMLTextAreaElement.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on HTMLDivElement.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on HTMLSpanElement.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on custom elements.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on an input type which the attribute doesn't apply. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test that the writingsuggestions attribute is available on a disabled element. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to `true` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `true` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to boolean `true` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to boolean `true` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to `TrUe` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `TrUe` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to `false` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `false` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to boolean `false` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to boolean `false` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to `FaLsE` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `FaLsE` directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to the empty string directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to the empty string directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` IDL attribute to an invalid value directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to an invalid value directly on the target element.]
+ expected: FAIL
+
+ [Test the writing suggestions state when the `writingsuggestions` attribute is missing.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `false` after the IDL attribute was set to `true`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `FaLsE` after the IDL attribute was set to `true`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to boolean `false` after the IDL attribute was set to `true`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `true` after the IDL attribute was set to `false`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to the empty string after the IDL attribute was set to `false`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to an invalid value after the IDL attribute was set to `false`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to `TrUe` after the IDL attribute was set to `false`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` content attribute to boolean `true` after the IDL attribute was set to `false`.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` attribute with a missing value directly on the target element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` attribute to "true" on a parent element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` attribute to an empty string on a parent element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` attribute to "false" on a parent element.]
+ expected: FAIL
+
+ [Test setting the `writingsuggestions` attribute to an invalid value on a parent element.]
+ expected: FAIL
+
+ [Test overriding the parent element's `writingsuggestions` attribute from "true" to "false".]
+ expected: FAIL
+
+ [Test overriding the parent element's `writingsuggestions` attribute from the empty string to "false".]
+ expected: FAIL
+
+ [Test overriding the parent element's `writingsuggestions` attribute from "false" to "true".]
+ expected: FAIL
+
+ [Test overriding the parent element's `writingsuggestions` attribute from "false" to an invalid value.]
+ expected: FAIL
+
+ [Test overriding the parent element's `writingsuggestions` attribute from "false" to the empty string.]
+ expected: FAIL
+
+ [Test turning off writing suggestions for an entire document.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input element from "false" to "true".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a textarea element from "false" to "true".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a div element from "false" to "true".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a span element from "false" to "true".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input type which the attribute doesn't apply from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a disabled textarea element from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input element from "false" to the empty string.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a textarea element from "false" to the empty string.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a div element from "false" to the empty string.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a span element from "false" to the empty string.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input type which the attribute doesn't apply from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a disabled textarea element from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input element from "false" to an invalid value.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a textarea element from "false" to an invalid value.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a div element from "false" to an invalid value.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a span element from "false" to an invalid value.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input type which the attribute doesn't apply from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a disabled textarea element from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input element from "true" to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a textarea element from "true" to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a div element from "true" to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a span element from "true" to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input type which the attribute doesn't apply from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a disabled textarea element from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input element from the empty string to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a textarea element from the empty string to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a div element from the empty string to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a span element from the empty string to "false".]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on an input type which the attribute doesn't apply from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test overriding a non-parent ancestor element's `writingsuggestions` attribute on a disabled textarea element from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.]
+ expected: FAIL
+
+ [Test that for continuous text on the screen, writing suggestions may be allowed in one part but not another.]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini b/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
index ddd65fdcec8..16db1ea9c58 100644
--- a/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
+++ b/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
@@ -1,15 +1,16 @@
[supported-elements.html]
+ expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Host element with delegatesFocus including no focusable descendants should be skipped]
- expected: FAIL
+ expected: TIMEOUT
[Element with tabindex should support autofocus]
expected: FAIL
[Area element should support autofocus]
- expected: FAIL
+ expected: NOTRUN
[Host element with delegatesFocus should support autofocus]
expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini
new file mode 100644
index 00000000000..891c20353ba
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html.ini
@@ -0,0 +1,3 @@
+[iframe-loading-lazy-in-scroller-far.html]
+ [Test that lazy-loaded iframes do not load when far from viewport.]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini
new file mode 100644
index 00000000000..ccd3db41d22
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html.ini
@@ -0,0 +1,2 @@
+[iframe-loading-lazy-in-scroller-horizontal-far.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
index c6f1e5d7d84..4034793cc72 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
@@ -1,4 +1,3 @@
[iframe_sandbox_popups_nonescaping-2.html]
- expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
- expected: NOTRUN
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini b/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini
deleted file mode 100644
index 7682a4830bf..00000000000
--- a/tests/wpt/meta/html/semantics/forms/form-submission-0/reparent-form-during-planned-navigation-task.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[reparent-form-during-planned-navigation-task.html]
- expected: TIMEOUT
- [reparent-form-during-planned-navigation-task]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini b/tests/wpt/meta/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini
new file mode 100644
index 00000000000..1dcebc9a5ff
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/forms/the-form-element/form-indexed-element-shadow.html.ini
@@ -0,0 +1,3 @@
+[form-indexed-element-shadow.html]
+ [form.elements: indexed access reflects DOM order, not flat tree]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini b/tests/wpt/meta/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
index 7f099cec1b0..dcd52d2fee8 100644
--- a/tests/wpt/meta/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
+++ b/tests/wpt/meta/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html.ini
@@ -7,3 +7,6 @@
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
+
+ [Check that rel=noopener with target=_self does a normal load]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/popovers/popover-open-overflow-display-2.html.ini b/tests/wpt/meta/html/semantics/popovers/popover-open-overflow-display-2.html.ini
new file mode 100644
index 00000000000..2d7a15adecb
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/popovers/popover-open-overflow-display-2.html.ini
@@ -0,0 +1,18 @@
+[popover-open-overflow-display-2.html]
+ [Absolute popover inside absolute element]
+ expected: FAIL
+
+ [Absolute element inside absolute popover]
+ expected: FAIL
+
+ [Fixed popover inside fixed element]
+ expected: FAIL
+
+ [Fixed element inside fixed popover]
+ expected: FAIL
+
+ [Absolute popover inside fixed element]
+ expected: FAIL
+
+ [Fixed element inside absolute popover]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/remove-initial-about-blankness.window.js.ini b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/remove-initial-about-blankness.window.js.ini
index 4d9d87b1a60..2bfc617ce40 100644
--- a/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/remove-initial-about-blankness.window.js.ini
+++ b/tests/wpt/meta/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/remove-initial-about-blankness.window.js.ini
@@ -1,4 +1,3 @@
[remove-initial-about-blankness.window.html]
- expected: TIMEOUT
[Double-check: without document.open(), Window reuse indeed happens]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini b/tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
index 8244944df44..1053fb90051 100644
--- a/tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
+++ b/tests/wpt/meta/html/webappapis/scripting/events/compile-event-handler-settings-objects.html.ini
@@ -4,4 +4,4 @@
expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta/resource-timing/content-type-parsing.html.ini b/tests/wpt/meta/resource-timing/content-type-parsing.html.ini
index 71ca4ed5411..49b17a921b5 100644
--- a/tests/wpt/meta/resource-timing/content-type-parsing.html.ini
+++ b/tests/wpt/meta/resource-timing/content-type-parsing.html.ini
@@ -94,10 +94,10 @@
expected: FAIL
[mime-type 16 : text/html;charset=\x0bgbk]
- expected: FAIL
+ expected: TIMEOUT
[mime-type 17 : text/html;charset=\x0cgbk]
- expected: TIMEOUT
+ expected: NOTRUN
[mime-type 18 : text/html;\x0bcharset=gbk]
expected: NOTRUN
diff --git a/tests/wpt/meta/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini b/tests/wpt/meta/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
index eddd0aa6c39..3280d281582 100644
--- a/tests/wpt/meta/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
+++ b/tests/wpt/meta/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js.ini
@@ -1,3 +1,4 @@
[third-party.default.tentative.sub.https.window.html]
+ expected: ERROR
[Check SharedWorker sameSiteCookies option default for third-party]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/meta/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini b/tests/wpt/meta/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
index 46f1697bd35..b9f12992e36 100644
--- a/tests/wpt/meta/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
+++ b/tests/wpt/meta/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js.ini
@@ -1,3 +1,4 @@
[third-party.none.tentative.sub.https.window.html]
+ expected: ERROR
[Check SharedWorker sameSiteCookies option none for third-party]
- expected: FAIL
+ expected: TIMEOUT
diff --git a/tests/wpt/mozilla/meta-legacy-layout/mozilla/service-workers/service-worker-registration.https.html.ini b/tests/wpt/mozilla/meta-legacy-layout/mozilla/service-workers/service-worker-registration.https.html.ini
index c7b4395d42b..ee7cf8c2475 100644
--- a/tests/wpt/mozilla/meta-legacy-layout/mozilla/service-workers/service-worker-registration.https.html.ini
+++ b/tests/wpt/mozilla/meta-legacy-layout/mozilla/service-workers/service-worker-registration.https.html.ini
@@ -1,6 +1,5 @@
[service-worker-registration.https.html]
type: testharness
- expected: CRASH
[Test: Asserts Active Service Worker and its Registration]
expected: FAIL
diff --git a/tests/wpt/tests/.taskcluster.yml b/tests/wpt/tests/.taskcluster.yml
index 53518a9498a..38af7fa10af 100644
--- a/tests/wpt/tests/.taskcluster.yml
+++ b/tests/wpt/tests/.taskcluster.yml
@@ -57,7 +57,7 @@ tasks:
owner: ${owner}
source: ${event.repository.clone_url}
payload:
- image: webplatformtests/wpt:0.56
+ image: webplatformtests/wpt:0.57
maxRunTime: 7200
artifacts:
public/results:
diff --git a/tests/wpt/tests/IndexedDB/back-forward-cache-open-connection.window.js b/tests/wpt/tests/IndexedDB/back-forward-cache-open-connection.window.js
index cee7287a0bb..db51daa121c 100644
--- a/tests/wpt/tests/IndexedDB/back-forward-cache-open-connection.window.js
+++ b/tests/wpt/tests/IndexedDB/back-forward-cache-open-connection.window.js
@@ -29,7 +29,7 @@ promise_test(async t => {
await rc2.historyBack();
// The previous page receiving versionchange event should be evicted with the
// correct reason.
- // `kIgnoreEventAndEvict` will be reported as "internal-error".
+ // `kIgnoreEventAndEvict` will be reported as "masked".
// See `NotRestoredReasonToReportString()`.
- await assertNotRestoredFromBFCache(rc1, ['internal-error']);
+ await assertNotRestoredFromBFCache(rc1, ['masked']);
});
diff --git a/tests/wpt/tests/clipboard-apis/clipboard-item.https.html b/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
index b50a1c97d74..7e148703a26 100644
--- a/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
+++ b/tests/wpt/tests/clipboard-apis/clipboard-item.https.html
@@ -100,13 +100,17 @@ promise_test(async () => {
assert_true(ClipboardItem.supports('text/plain'));
assert_true(ClipboardItem.supports('text/html'));
assert_true(ClipboardItem.supports('image/png'));
+ assert_true(ClipboardItem.supports('image/svg+xml'));
assert_false(ClipboardItem.supports('web '));
assert_false(ClipboardItem.supports('web')); // without space.
assert_false(ClipboardItem.supports('web foo'));
assert_false(ClipboardItem.supports('foo/bar'));
assert_true(ClipboardItem.supports('web foo/bar'));
assert_true(ClipboardItem.supports('web text/html'));
- assert_false(ClipboardItem.supports('image/svg+xml'));
+ assert_false(ClipboardItem.supports('weB text/html'));
+ assert_false(ClipboardItem.supports(' web text/html'));
assert_false(ClipboardItem.supports('not a/real type'));
+ assert_false(ClipboardItem.supports(''));
+ assert_false(ClipboardItem.supports(' '));
}, "supports(DOMString) returns true for types that are supported, false otherwise");
</script>
diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-001.html b/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-001.html
deleted file mode 100644
index b5e19522b00..00000000000
--- a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-001.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<title>Tests automatic anchor positioning without fallbacks</title>
-<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#anchor-auto">
-<link rel="auto" href="mailto:xiaochengh@chromium.org">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/check-layout-th.js"></script>
-<script src="support/test-common.js"></script>
-
-<style>
-body {
- margin: 0;
-}
-
-#cb {
- position: absolute;
- width: 500px;
- height: 500px;
-}
-
-#anchor {
- margin-left: 150px;
- margin-top: 250px;
- width: 100px;
- height: 100px;
- background: orange;
- anchor-name: --a;
-}
-
-.target {
- position: absolute;
- width: 100px;
- height: 100px;
- background: lime;
-}
-
-#target1 {
- top: anchor(--a auto); /* should evaluate to `bottom` */
- left: anchor(--a auto-same); /* should evaluate to `left` */
-}
-
-#target2 {
- bottom: anchor(--a auto); /* should evaluate to `top` */
- right: anchor(--a auto-same); /* should evaluate to `right` */
-}
-
-#target3 {
- top: anchor(--a auto-same); /* should evaluate to `top` */
- left: anchor(--a auto); /* should evaluate to `right` */
-}
-
-#target4 {
- bottom: anchor(--a auto-same); /* should evaluate to `bottom` */
- right: anchor(--a auto); /* should evaluate to `left` */
-}
-</style>
-
-<body onload="checkLayoutForAnchorPos('.target')">
- <div id="cb">
- <div id="anchor"></div>
-
- <div id="target1" class="target"
- data-offset-x="150" data-offset-y="350"></div>
- <div id="target2" class="target"
- data-offset-x="150" data-offset-y="150"></div>
- <div id="target3" class="target"
- data-offset-x="250" data-offset-y="250"></div>
- <div id="target4" class="target"
- data-offset-x="50" data-offset-y="250"></div>
- </div>
-</body>
diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-002.html b/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-002.html
deleted file mode 100644
index 1c86fe2e467..00000000000
--- a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-002.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!DOCTYPE html>
-<title>Tests automatic anchor fallbacks created from the base style</title>
-<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-automatic">
-<link rel="auto" href="mailto:xiaochengh@chromium.org">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/check-layout-th.js"></script>
-<script src="support/test-common.js"></script>
-
-<style>
-body {
- margin: 0;
-}
-
-.cb {
- position: absolute;
- width: 500px;
- height: 500px;
-}
-
-.anchor {
- position: absolute;
- width: 100px;
- height: 100px;
- background: orange;
-}
-
-.target {
- position: absolute;
- width: 100px;
- height: 100px;
- background: lime;
-}
-
-.flip-x {
- top: anchor(top);
- left: anchor(auto);
-}
-
-.flip-x-same {
- width: 200px;
- top: anchor(top);
- left: anchor(auto-same);
-}
-
-.flip-y {
- top: anchor(auto);
- left: anchor(left);
-}
-
-.flip-y-same {
- height: 200px;
- left: anchor(left);
- top: anchor(auto-same);
-}
-
-.flip-both {
- top: anchor(auto);
- left: anchor(auto);
-}
-
-#anchor1 {
- top: 50px;
- left:200px;
- anchor-name: --a1;
-}
-
-#anchor2 {
- bottom: 50px;
- left: 200px;
- anchor-name: --a2;
-}
-
-#anchor3 {
- left: 50px;
- top: 200px;
- anchor-name: --a3;
-}
-
-#anchor4 {
- right: 50px;
- top: 200px;
- anchor-name: --a4
-}
-
-#anchor5 {
- top: 50px;
- left: 50px;
- anchor-name: --a5;
-}
-
-#anchor6 {
- top: 50px;
- right: 50px;
- anchor-name: --a6;
-}
-
-#anchor7 {
- bottom: 50px;
- left: 50px;
- anchor-name: --a7;
-}
-
-#anchor8 {
- bottom: 50px;
- right: 50px;
- anchor-name: --a8;
-}
-
-#anchor9 {
- top: 200px;
- right: 50px;
- anchor-name: --a9;
-}
-
-#anchor10 {
- top: 200px;
- left: 50px;
- anchor-name: --a10;
-}
-
-#anchor11 {
- left: 200px;
- top: 50px;
- anchor-name: --a11;
-}
-
-#anchor12 {
- left: 200px;
- bottom: 50px;
- anchor-name: --a12;
-}
-
-#target1 { anchor-default: --a1; }
-#target2 { anchor-default: --a2; }
-#target3 { anchor-default: --a3; }
-#target4 { anchor-default: --a4; }
-#target5 { anchor-default: --a5; }
-#target6 { anchor-default: --a6; }
-#target7 { anchor-default: --a7; }
-#target8 { anchor-default: --a8; }
-#target9 { anchor-default: --a9; }
-#target10 { anchor-default: --a10; }
-#target11 { anchor-default: --a11; }
-#target12 { anchor-default: --a12; }
-
-</style>
-
-<body onload="checkLayoutForAnchorPos('.target')">
- <!-- Test cases creating flipped fallbacks in one axis -->
- <div class="cb">
- <div class="anchor" id="anchor1"></div>
- <div class="anchor" id="anchor2"></div>
- <div class="anchor" id="anchor3"></div>
- <div class="anchor" id="anchor4"></div>
-
- <div class="target flip-y" id="target1"
- data-offset-x="200" data-offset-y="150"></div>
- <div class="target flip-y" id="target2"
- data-offset-x="200" data-offset-y="250"></div>
- <div class="target flip-x" id="target3"
- data-offset-x="150" data-offset-y="200"></div>
- <div class="target flip-x" id="target4"
- data-offset-x="250" data-offset-y="200"></div>
- </div>
-
- <!-- Test cases creating flipped fallbacks in both axes -->
- <div class="cb" style="top: 500px">
- <div class="anchor" id="anchor5"></div>
- <div class="anchor" id="anchor6"></div>
- <div class="anchor" id="anchor7"></div>
- <div class="anchor" id="anchor8"></div>
-
- <div class="target flip-both" id="target5"
- data-offset-x="150" data-offset-y="150"></div>
- <div class="target flip-both" id="target6"
- data-offset-x="250" data-offset-y="150"></div>
- <div class="target flip-both" id="target7"
- data-offset-x="150" data-offset-y="250"></div>
- <div class="target flip-both" id="target8"
- data-offset-x="250" data-offset-y="250"></div>
- </div>
-
- <!-- Test cases for `auto-same` flipping -->
- <div class="cb" style="top: 1000px">
- <div class="anchor" id="anchor9"></div>
- <div class="anchor" id="anchor10"></div>
- <div class="anchor" id="anchor11"></div>
- <div class="anchor" id="anchor12"></div>
-
- <div class="target flip-x-same" id="target9"
- data-offset-x="250" data-offset-y="200"></div>
- <div class="target flip-x-same" id="target10"
- data-offset-x="50" data-offset-y="200"></div>
- <div class="target flip-y-same" id="target11"
- data-offset-x="200" data-offset-y="50"></div>
- <div class="target flip-y-same" id="target12"
- data-offset-x="200" data-offset-y="250"></div>
- </div>
-</body>
diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-003.html b/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-003.html
deleted file mode 100644
index 33ef58b2af4..00000000000
--- a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-003.html
+++ /dev/null
@@ -1,168 +0,0 @@
-<!DOCTYPE html>
-<title>Tests automatic anchor fallbacks created from an @try rule</title>
-<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#fallback-automatic">
-<link rel="auto" href="mailto:xiaochengh@chromium.org">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/check-layout-th.js"></script>
-<script src="support/test-common.js"></script>
-
-<style>
-body {
- margin: 0;
-}
-
-.cb {
- position: absolute;
- width: 500px;
- height: 500px;
-}
-
-.anchor {
- position: absolute;
- width: 100px;
- height: 100px;
- background: orange;
-}
-
-.target {
- position: absolute;
- width: 100px;
- height: 100px;
- background: lime;
- position-fallback: --pf;
-}
-
-@position-fallback --pf {
- @try {
- top: anchor(auto);
- left: anchor(auto);
- }
-}
-
-#anchor1 {
- top: 50px;
- left: 50px;
- anchor-name: --a1;
-}
-
-#anchor2 {
- top: 50px;
- right: 50px;
- anchor-name: --a2;
-}
-
-#anchor3 {
- bottom: 50px;
- left: 50px;
- anchor-name: --a3;
-}
-
-#anchor4 {
- bottom: 50px;
- right: 50px;
- anchor-name: --a4;
-}
-
-#target1 { anchor-default: --a1; }
-#target2 { anchor-default: --a2; }
-#target3 { anchor-default: --a3; }
-#target4 { anchor-default: --a4; }
-
-#anchor5 {
- top: 200px;
- right: 50px;
- anchor-name: --a5;
-}
-
-#anchor6 {
- bottom: 50px;
- left: 200px;
- anchor-name: --a6;
-}
-
-#target5 {
- top: anchor(top);
- left: anchor(auto);
- anchor-default: --a5;
- position-fallback: --pf-empty;
-}
-
-#target6 {
- top: anchor(auto);
- left: anchor(left);
- anchor-default: --a6;
- position-fallback: --pf-empty;
-}
-
-#anchor7 {
- bottom: 50px;
- right: 50px;
- anchor-name: --a7;
-}
-
-#target7 {
- top: anchor(auto);
- anchor-default: --a7;
- position-fallback: --pf-flip-x;
-}
-
-#target8 {
- left: anchor(auto);
- anchor-default: --a7;
- position-fallback: --pf-flip-y;
-}
-
-@position-fallback --pf-empty {
- @try {}
-}
-
-@position-fallback --pf-flip-x {
- @try { left: anchor(auto); }
-}
-
-@position-fallback --pf-flip-y {
- @try { top: anchor(auto); }
-}
-</style>
-
-<body onload="checkLayoutForAnchorPos('.target')">
- <!-- Test cases creating auto fallbacks from an @try rule -->
- <div class="cb">
- <div class="anchor" id="anchor1"></div>
- <div class="anchor" id="anchor2"></div>
- <div class="anchor" id="anchor3"></div>
- <div class="anchor" id="anchor4"></div>
-
- <div class="target" id="target1"
- data-offset-x="150" data-offset-y="150"></div>
- <div class="target" id="target2"
- data-offset-x="250" data-offset-y="150"></div>
- <div class="target" id="target3"
- data-offset-x="150" data-offset-y="250"></div>
- <div class="target" id="target4"
- data-offset-x="250" data-offset-y="250"></div>
- </div>
-
- <div class="cb" style="top: 500px">
- <div class="anchor" id="anchor5"></div>
- <div class="anchor" id="anchor6"></div>
- <div class="anchor" id="anchor7"></div>
-
- <!-- Test cases where `anchor(auto)` is in base style, so no auto fallbacks
- are created from @try rules, and targets end up overflowing the
- containing block. -->
- <div class="target" id="target5"
- data-offset-x="450" data-offset-y="200"></div>
- <div class="target" id="target6"
- data-offset-x="200" data-offset-y="450"></div>
-
- <!-- Test cases where `anchor(auto)` is used in both axes, but the `@try`
- rule affects only one axis, so we only flip in one axis, and the
- targets end up overflowing the containing block. -->
- <div class="target" id="target7"
- data-offset-x="250" data-offset-y="450"></div>
- <div class="target" id="target8"
- data-offset-x="450" data-offset-y="250"></div>
- </div>
-</body>
diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-004.html b/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-004.html
deleted file mode 100644
index befd5fcff06..00000000000
--- a/tests/wpt/tests/css/css-anchor-position/anchor-position-auto-004.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE html>
-<title>Tests auto fallbacks with scrolling</title>
-<link rel="author" href="mailto:xiaochengh@chromium.org">
-<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#scroll">
-<link rel="help" href="https://drafts.csswg.org/css-anchor-1/#fallback-automatic">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="support/test-common.js"></script>
-
-<style>
-#container {
- position: relative;
- width: 200px;
- height: 300px;
-}
-
-#scroller {
- height: 300px;
- overflow-y: scroll;
-}
-
-#anchor {
- width: 100px;
- height: 100px;
- margin-top: 200px;
- margin-bottom: 200px;
- background: orange;
- anchor-name: --a;
-}
-
-#target {
- position: absolute;
- width: 100px;
- height: 100px;
- anchor-default: --a;
- left: anchor(left);
- top: anchor(auto);
- background: lime;
-}
-</style>
-
-<div id="container">
- <div id="scroller">
- <div id="anchor"></div>
- </div>
- <div id="target"></div>
-</div>
-
-<script>
-promise_test(async () => {
- await waitUntilNextAnimationFrame();
- assert_fallback_position(target, anchor, 'top');
-}, 'Should be above the anchor when at initial scroll position');
-
-promise_test(async () => {
- scroller.scrollTop = 100;
- await waitUntilNextAnimationFrame();
- assert_fallback_position(target, anchor, 'bottom');
-}, 'Scroll down to allow enough space below the anchor, should move target below');
-</script>
diff --git a/tests/wpt/tests/css/css-anchor-position/parsing/position-try-parsing.html b/tests/wpt/tests/css/css-anchor-position/parsing/position-try-parsing.html
new file mode 100644
index 00000000000..7f504597106
--- /dev/null
+++ b/tests/wpt/tests/css/css-anchor-position/parsing/position-try-parsing.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Anchor Positioning Test: Parsing of position-try shorthand</title>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#position-try-prop">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+<script src="/css/support/shorthand-testcommon.js"></script>
+<script>
+ test_valid_value("position-try", "flip-inline");
+ test_valid_value("position-try", "most-height none");
+ test_valid_value("position-try", "--bar, --baz");
+ test_valid_value("position-try", "most-inline-size --baz, flip-inline");
+ test_valid_value("position-try", "most-block-size flip-inline flip-block, --bar, --baz");
+ test_valid_value("position-try", "normal none", "none");
+ test_valid_value("position-try", "most-width none");
+ test_valid_value("position-try", "normal --foo", "--foo");
+
+ test_invalid_value("position-try", "normal --foo, most-width --bar");
+ test_invalid_value("position-try", "none normal");
+ test_invalid_value("position-try", "flip-block most-height");
+ test_invalid_value("position-try", "most-height, flip-start");
+
+ test_shorthand_value("position-try", "flip-inline", {
+ "position-try-order": "normal",
+ "position-try-options": "flip-inline",
+ });
+ test_shorthand_value("position-try", "most-width none", {
+ "position-try-order": "most-width",
+ "position-try-options": "none",
+ });
+ test_shorthand_value("position-try", "--foo, --bar", {
+ "position-try-order": "normal",
+ "position-try-options": "--foo, --bar",
+ });
+ test_shorthand_value("position-try", "most-inline-size --foo, flip-inline", {
+ "position-try-order": "most-inline-size",
+ "position-try-options": "--foo, flip-inline",
+ });
+ test_shorthand_value("position-try", "most-inline-size flip-inline flip-block, --foo, --bar", {
+ "position-try-order": "most-inline-size",
+ "position-try-options": "flip-inline flip-block, --foo, --bar",
+ });
+</script>
diff --git a/tests/wpt/tests/css/css-borders/border-image-width-interpolation-math-functions-tentative.html b/tests/wpt/tests/css/css-borders/border-image-width-interpolation-math-functions-tentative.html
new file mode 100644
index 00000000000..70539beb263
--- /dev/null
+++ b/tests/wpt/tests/css/css-borders/border-image-width-interpolation-math-functions-tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>border-image-width interpolation with css math functions</title>
+ <link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org">
+ <link rel="help" href="https://drafts.csswg.org/css-backgrounds/#the-border-image-width">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/interpolation-testcommon.js"></script>
+ </head>
+ <style>
+ :root {
+ font-size: 10px;
+ }
+ </style>
+ <body>
+ <script>
+ test_interpolation({
+ property: 'border-image-width',
+ from: '100',
+ to: 'calc(sign(20rem - 20px) * 180)',
+ }, [
+ {at: -1, expect: '20'},
+ {at: 0, expect: '100'},
+ {at: 0.125, expect: '110'},
+ {at: 0.875, expect: '170'},
+ {at: 1, expect: '180'},
+ {at: 2, expect: '260'}
+ ]);
+
+ test_interpolation({
+ property: 'border-image-width',
+ from: 'calc(sign(20rem - 20px) * 100)',
+ to: 'calc(progress(10rem from 20px to 100px) * 180)',
+ }, [
+ {at: -1, expect: '20'},
+ {at: 0, expect: '100'},
+ {at: 0.125, expect: '110'},
+ {at: 0.875, expect: '170'},
+ {at: 1, expect: '180'},
+ {at: 2, expect: '260'}
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-break/out-of-flow-in-multicolumn-117.html b/tests/wpt/tests/css/css-break/out-of-flow-in-multicolumn-117.html
new file mode 100644
index 00000000000..886a12acaba
--- /dev/null
+++ b/tests/wpt/tests/css/css-break/out-of-flow-in-multicolumn-117.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://issues.chromium.org/issues/40775119">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="columns:2; column-fill:auto; gap:0; width:200px; height:100px;">
+ <div style="height:40px; background:green;"></div>
+ <div style="columns:2; column-fill:auto; gap:0; height:40px; background:red;">
+ <div style="position:relative; height:20px; background:red;">
+ <div style="position:absolute; top:0; width:50px; height:40px; background:green;"></div>
+ </div>
+ <div style="column-span:all; height:40px; background:green;"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html b/tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html
index f0e2f6cce02..b54aa0da12a 100644
--- a/tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html
+++ b/tests/wpt/tests/css/css-color/parsing/color-computed-color-mix-function.html
@@ -42,6 +42,9 @@
fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 10% 20% / 0), hsl(30deg 30% 40%))`, `color(srgb 0.46 0.52 0.28 / 0.5)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(120deg 10% 20% / 0) 10%, hsl(30deg 30% 40%))`, `color(srgb 0.52 0.436 0.28 / 0.9)`);
+ fuzzy_test_computed_color(`color-mix(in hsl, white, blue)`, `color(srgb 0.62 0.62 0.87)`);
+ fuzzy_test_computed_color(`color-mix(in hsl, white 10%, blue)`, `color(srgb 0.15 0.15 0.96)`);
+
fuzzy_test_computed_color(`color-mix(in hsl, hsl(40deg 50% 50%), hsl(60deg 50% 50%))`, `color(srgb 0.75 0.666667 0.25)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(60deg 50% 50%), hsl(40deg 50% 50%))`, `color(srgb 0.75 0.666667 0.25)`);
fuzzy_test_computed_color(`color-mix(in hsl, hsl(50deg 50% 50%), hsl(330deg 50% 50%))`, `color(srgb 0.75 0.333333 0.25)`);
@@ -125,6 +128,9 @@
fuzzy_test_computed_color(`color-mix(in hwb, hwb(120deg 10% 20% / 0), hwb(30deg 30% 40%))`, `color(srgb 0.525 0.6 0.3 / 0.5)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(120deg 10% 20% / 0) 10%, hwb(30deg 30% 40%))`, `color(srgb 0.6 0.495 0.3 / 0.9)`);
+ fuzzy_test_computed_color(`color-mix(in hwb, white, blue)`, `color(srgb 0.5 0.5 1)`);
+ fuzzy_test_computed_color(`color-mix(in hwb, white 10%, blue)`, `color(srgb 0.1 0.1 1)`);
+
fuzzy_test_computed_color(`color-mix(in hwb, hwb(40deg 30% 40%), hwb(60deg 30% 40%))`, `color(srgb 0.6 0.55 0.3)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(60deg 30% 40%), hwb(40deg 30% 40%))`, `color(srgb 0.6 0.55 0.3)`);
fuzzy_test_computed_color(`color-mix(in hwb, hwb(50deg 30% 40%), hwb(330deg 30% 40%))`, `color(srgb 0.6 0.35 0.3)`);
@@ -203,6 +209,9 @@
fuzzy_test_computed_color(`color-mix(in lch, lch(0.1 0.2 120deg / 0), lch(0.3 0.4 30deg))`, `lch(0.3 0.4 75 / 0.5)`);
fuzzy_test_computed_color(`color-mix(in lch, lch(0.1 0.2 120deg / 0) 10%, lch(0.3 0.4 30deg))`, `lch(0.3 0.4 39 / 0.9)`);
+ fuzzy_test_computed_color(`color-mix(in lch, white, blue)`, `lch(64.78 65.6 301.37)`, 0.1);
+ fuzzy_test_computed_color(`color-mix(in lch, white 10%, blue)`, `lch(36.61 118.09 301.37)`, 0.1);
+
fuzzy_test_computed_color(`color-mix(in lch, lch(100 0 40deg), lch(100 0 60deg))`, `lch(100 0 50)`);
fuzzy_test_computed_color(`color-mix(in lch, lch(100 0 60deg), lch(100 0 40deg))`, `lch(100 0 50)`);
fuzzy_test_computed_color(`color-mix(in lch, lch(100 0 50deg), lch(100 0 330deg))`, `lch(100 0 10)`);
@@ -283,6 +292,9 @@
fuzzy_test_computed_color(`color-mix(in oklch, oklch(0.1 20 120deg / 0), oklch(0.3 40 30deg))`, `oklch(0.3 40 75 / 0.5)`);
fuzzy_test_computed_color(`color-mix(in oklch, oklch(0.1 20 120deg / 0) 10%, oklch(0.3 40 30deg))`, `oklch(0.3 40 39 / 0.9)`);
+ fuzzy_test_computed_color(`color-mix(in oklch, white, blue)`, `oklch(0.726 0.156 264.052)`);
+ fuzzy_test_computed_color(`color-mix(in oklch, white 10%, blue)`, `oklch(0.506 0.281 264.052)`);
+
fuzzy_test_computed_color(`color-mix(in oklch, oklch(1 0 40deg), oklch(1 0 60deg))`, `oklch(1 0 50)`);
fuzzy_test_computed_color(`color-mix(in oklch, oklch(1 0 60deg), oklch(1 0 40deg))`, `oklch(1 0 50)`);
fuzzy_test_computed_color(`color-mix(in oklch, oklch(1 0 50deg), oklch(1 0 330deg))`, `oklch(1 0 10)`);
@@ -363,6 +375,9 @@
fuzzy_test_computed_color(`color-mix(in lab, lab(10 20 30 / 0), lab(30 40 50))`, 'lab(30 40 50 / 0.5)');
fuzzy_test_computed_color(`color-mix(in lab, lab(10 20 30 / 0) 10%, lab(30 40 50))`, 'lab(30 40 50 / 0.9)');
+ fuzzy_test_computed_color(`color-mix(in lab, white, blue)`, `lab(64.78 34.15 -56.02)`, 0.1);
+ fuzzy_test_computed_color(`color-mix(in lab, white 10%, blue)`, `lab(36.61 61.45 -100.82)`, 0.1);
+
fuzzy_test_computed_color(`color-mix(in lab, lab(none none none), lab(none none none))`, `lab(none none none)`);
fuzzy_test_computed_color(`color-mix(in lab, lab(none none none), lab(50 60 70))`, `lab(50 60 70)`);
fuzzy_test_computed_color(`color-mix(in lab, lab(10 20 30), lab(none none none))`, `lab(10 20 30)`);
@@ -406,6 +421,9 @@
fuzzy_test_computed_color(`color-mix(in oklab, oklab(0.1 0.2 0.3 / 0), oklab(0.3 0.4 0.5))`, 'oklab(0.3 0.4 0.5 / 0.5)');
fuzzy_test_computed_color(`color-mix(in oklab, oklab(0.1 0.2 0.3 / 0) 10%, oklab(0.3 0.4 0.5))`, 'oklab(0.3 0.4 0.5 / 0.9)');
+ fuzzy_test_computed_color(`color-mix(in oklab, white, blue)`, `oklab(0.73 -0.02 -0.16)`);
+ fuzzy_test_computed_color(`color-mix(in oklab, white 10%, blue)`, `oklab(0.51 -0.03 -0.28)`);
+
fuzzy_test_computed_color(`color-mix(in oklab, oklab(none none none), oklab(none none none))`, `oklab(none none none)`);
fuzzy_test_computed_color(`color-mix(in oklab, oklab(none none none), oklab(0.5 0.6 0.7))`, `oklab(0.5 0.6 0.7)`);
fuzzy_test_computed_color(`color-mix(in oklab, oklab(0.1 0.2 0.3), oklab(none none none))`, `oklab(0.1 0.2 0.3)`);
@@ -451,6 +469,9 @@
fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} 0.1 0.2 0.3 / 0), color(${colorSpace} 0.3 0.4 0.5))`, `color(${resultColorSpace} 0.3 0.4 0.5 / 0.5)`);
fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} 0.1 0.2 0.3 / 0) 10%, color(${colorSpace} 0.3 0.4 0.5))`, `color(${resultColorSpace} 0.3 0.4 0.5 / 0.9)`);
+ fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} 1 1 1), color(${colorSpace} 0 0 1))`, `color(${resultColorSpace} 0.5 0.5 1)`);
+ fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} 1 1 1) 10%, color(${colorSpace} 0 0 1))`, `color(${resultColorSpace} 0.1 0.1 1)`);
+
fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} 2 3 4 / 5), color(${colorSpace} 4 6 8 / 10))`, `color(${resultColorSpace} 3 4.5 6)`);
fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4), color(${colorSpace} -4 -6 -8))`, `color(${resultColorSpace} -3 -4.5 -6)`);
fuzzy_test_computed_color(`color-mix(in ${colorSpace}, color(${colorSpace} -2 -3 -4 / -5), color(${colorSpace} -4 -6 -8 / -10))`, `color(${resultColorSpace} 0 0 0 / 0)`);
diff --git a/tests/wpt/tests/css/css-color/parsing/color-valid-hsl.html b/tests/wpt/tests/css/css-color/parsing/color-valid-hsl.html
index 7ab1274176f..b3a9d7944e8 100644
--- a/tests/wpt/tests/css/css-color/parsing/color-valid-hsl.html
+++ b/tests/wpt/tests/css/css-color/parsing/color-valid-hsl.html
@@ -46,6 +46,12 @@ test_valid_value("color", "hsl(120 30 none)", "rgb(0, 0, 0)");
test_valid_value("color", "hsl(120 30 none / 0.5)", "rgba(0, 0, 0, 0.5)");
test_valid_value("color", "hsl(120 30 50 / none)", "rgba(89, 166, 89, 0)");
+// Test parse-time clamp of negative saturation to zero
+test_valid_value("color", "hsl(0 -50% 40%)", "rgb(102, 102, 102)");
+test_valid_value("color", "hsl(30 -50% 60)", "rgb(153, 153, 153)");
+test_valid_value("color", "hsl(0 -50 40%)", "rgb(102, 102, 102)");
+test_valid_value("color", "hsl(30 -50 60)", "rgb(153, 153, 153)");
+
// Test non-finite values. calc(infinity) goes to upper bound while calc(-infinity) and NaN go to the lower bound.
// See: https://github.com/w3c/csswg-drafts/issues/8629
test_valid_value("color", "hsl(calc(infinity) 100% 50%)", "rgb(255, 0, 0)"); // hsl(360 100% 50%)
diff --git a/tests/wpt/tests/css/css-flexbox/negative-overflow-002.html b/tests/wpt/tests/css/css-flexbox/negative-overflow-002.html
index 171095d2b55..7c8d6337b90 100644
--- a/tests/wpt/tests/css/css-flexbox/negative-overflow-002.html
+++ b/tests/wpt/tests/css/css-flexbox/negative-overflow-002.html
@@ -17,6 +17,16 @@
min-width: 110px; min-height: 110px;
background: cyan;
}
+
+.container:hover::before {
+ position: fixed;
+ top: 0; left: 0;
+ font-size: 10px;
+ content: attr(style);
+ background: yellow;
+ direction: ltr;
+ writing-mode: horizontal-tb;
+}
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
diff --git a/tests/wpt/tests/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html b/tests/wpt/tests/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html
new file mode 100644
index 00000000000..d173fb03bbb
--- /dev/null
+++ b/tests/wpt/tests/css/css-fonts/font-size-adjust-interpolation-math-functions.tentative.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>font-size-adjust interpolation with css math functions</title>
+ <link rel="help" href="https://drafts.csswg.org/css-fonts-5/#font-size-adjust-prop">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/interpolation-testcommon.js"></script>
+ </head>
+
+ <style>
+ :root {
+ font-size: 10px;
+ }
+ </style>
+ <body>
+ <script>
+ test_interpolation({
+ property: 'font-size-adjust',
+ from: '100',
+ to: 'calc(sign(20rem - 20px) * 180)',
+ }, [
+ {at: -1, expect: '20'},
+ {at: 0, expect: '100'},
+ {at: 0.125, expect: '110'},
+ {at: 0.875, expect: '170'},
+ {at: 1, expect: '180'},
+ {at: 2, expect: '260'}
+ ]);
+
+ test_interpolation({
+ property: 'font-size-adjust',
+ from: 'calc(sign(20rem - 20px) * 100)',
+ to: 'calc(progress(10rem from 20px to 100px) * 180)',
+ }, [
+ {at: -1, expect: '20'},
+ {at: 0, expect: '100'},
+ {at: 0.125, expect: '110'},
+ {at: 0.875, expect: '170'},
+ {at: 1, expect: '180'},
+ {at: 2, expect: '260'}
+ ]);
+ </script>
+ </body>
+</html>
+
diff --git a/tests/wpt/tests/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html b/tests/wpt/tests/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html
new file mode 100644
index 00000000000..9029eefcb44
--- /dev/null
+++ b/tests/wpt/tests/css/css-fonts/font-stretch-interpolation-math-functions.tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>font-size-adjust interpolation with css math functions</title>
+ <link rel="help" href="https://drafts.csswg.org/css-fonts-5/#font-size-adjust-prop">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/interpolation-testcommon.js"></script>
+ </head>
+
+ <style>
+ :root {
+ font-size: 10px;
+ }
+ </style>
+ <body>
+ <script>
+ test_interpolation({
+ property: 'font-stretch',
+ from: '100%',
+ to: 'calc(sign(20rem - 20px) * 180%)',
+ }, [
+ {at: -1, expect: '20%'},
+ {at: 0, expect: '100%'},
+ {at: 0.125, expect: '110%'},
+ {at: 0.875, expect: '170%'},
+ {at: 1, expect: '180%'},
+ {at: 2, expect: '260%'}
+ ]);
+
+ test_interpolation({
+ property: 'font-stretch',
+ from: 'calc(sign(20rem - 20px) * 100%)',
+ to: 'calc(progress(10rem from 20px to 100px) * 180%)',
+ }, [
+ {at: -1, expect: '20%'},
+ {at: 0, expect: '100%'},
+ {at: 0.125, expect: '110%'},
+ {at: 0.875, expect: '170%'},
+ {at: 1, expect: '180%'},
+ {at: 2, expect: '260%'}
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html b/tests/wpt/tests/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html
index 8e322fe38e1..db466b82cd8 100644
--- a/tests/wpt/tests/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html
+++ b/tests/wpt/tests/css/css-grid/grid-model/grid-container-ignores-first-letter-001.html
@@ -50,7 +50,7 @@
<div class="item" data-expected-height=20>The first item.</div>
<div class="item" data-expected-height=20>The second item.</div>
</div>
- <div data-expected-height=200>Out of grid.</div>
+ <div data-expected-height=20>Out of grid.</div>
</div>
<div class="container container-first-letter">
@@ -65,7 +65,7 @@
<div class="grid grid-first-letter" data-expected-height=20>
Anonymous item.
</div>
- <div data-expected-height=200>Out of grid.</div>
+ <div data-expected-height=20>Out of grid.</div>
</div>
<div class="container container-first-letter">
@@ -80,7 +80,7 @@
<div class="item" data-expected-height=20>The first item.</div>
<div class="item" data-expected-height=20>The second item.</div>
</div>
- <div data-expected-height=200>Out of grid.</div>
+ <div data-expected-height=20>Out of grid.</div>
</div>
<div class="container container-first-letter">
@@ -95,7 +95,7 @@
<div class="grid" data-expected-height=20>
Anonymous item.
</div>
- <div data-expected-height=200>Out of grid.</div>
+ <div data-expected-height=20>Out of grid.</div>
</div>
<div class="container container-first-letter">
diff --git a/tests/wpt/tests/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length1.html b/tests/wpt/tests/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length1.html
index f647c1af590..5f6bb7299fc 100644
--- a/tests/wpt/tests/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length1.html
+++ b/tests/wpt/tests/css/css-masking/clip-path/animations/two-clip-path-animation-diff-length1.html
@@ -3,21 +3,11 @@
<link rel="help" href="https://drafts.csswg.org/css-shapes-1/#basic-shape-interpolation">
<link rel="match" href="two-clip-path-animation-diff-length1-ref.html">
<style>
- .container {
+ #container {
width: 100px;
height: 100px;
background-color: green;
- animation: clippath2 10s step-end, clippath1 0.001s;
- }
-
- @keyframes clippath1 {
- 0% {
- clip-path: circle(10% at 50% 50%);
- }
-
- 100% {
- clip-path: circle(50% at 50% 50%);
- }
+ animation: clippath2 10s step-end;
}
@keyframes clippath2 {
@@ -34,15 +24,20 @@
<script src="../../../../web-animations/testcommon.js"></script>
<body>
- <div class="container"></div>
+ <div id="container"></div>
<script>
// This test ensures that if we have two different-length animations, when
// the one with higher compositing order finishes, the other one would still
// run normally.
- const animations = document.getAnimations();
- animations[1].finished.then(() => {
- takeScreenshot();
+ document.getAnimations()[0].ready.then(() => {
+ document.getElementById("container").animate(
+ [
+ { clipPath: "circle(10% at 50% 50%)" },
+ { clipPath: "circle(50% at 50% 50%)" },
+ ],
+ 100,
+ ).finished.then(takeScreenshot);
});
</script>
</body>
diff --git a/tests/wpt/tests/css/css-multicol/multicol-fill-balance-029.html b/tests/wpt/tests/css/css-multicol/multicol-fill-balance-029.html
new file mode 100644
index 00000000000..837141bd059
--- /dev/null
+++ b/tests/wpt/tests/css/css-multicol/multicol-fill-balance-029.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel="help" href="https://issues.chromium.org/issues/324314465">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="display: flex; width: 100px; height: 100px; background: red;">
+ <div style="columns: 1; width: 50px; gap: 0;">
+ <div style="break-inside: avoid; background: green; height: 100px;"></div>
+ <div style="break-inside: avoid; background: green; height: 100px;"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/scroller-covered-by-empty-svg.html b/tests/wpt/tests/css/css-overflow/scroller-covered-by-empty-svg.html
new file mode 100644
index 00000000000..f877b6b281d
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/scroller-covered-by-empty-svg.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<link rel="help" href="https://crbug.com/41490395">
+<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>
+ #scroller {
+ overflow: auto;
+ width: 600px;
+ height: 300px;
+ border: 2px solid blue;
+ will-change: scroll-position;
+ }
+
+ #svg {
+ position: relative;
+ top: -300px;
+ width: 300px;
+ height: 300px;
+ }
+
+ .spacer {
+ height: 200vh;
+ }
+</style>
+
+<div id="scroller">
+ <div class="spacer"></div>
+</div>
+<svg id="svg"></svg>
+<div class="spacer"></div>
+
+<script>
+ promise_test(async (t) => {
+ let scrolled = new Promise((resolve) => {
+ let scrollers = [window, document.getElementById("scroller")];
+ let onscroll = (evt) => {
+ for (const scroller of scrollers) {
+ scroller.removeEventListener("scroll", onscroll);
+ }
+ resolve(evt.target.id || "root");
+ }
+ for (const scroller of scrollers) {
+ scroller.addEventListener("scroll", onscroll);
+ }
+ });
+ // Scroll in SVG. Should scroll the window.
+ new test_driver.Actions().scroll(100, 100, 0, 50, { duration: 50 }).send();
+ assert_equals(await scrolled, "root", "Scroll in SVG should scroll the window");
+ }, "Wheel-scroll in empty SVG covering scroller should not scroll the scroller");
+</script>
diff --git a/tests/wpt/tests/css/css-page/cssom/page-001.html b/tests/wpt/tests/css/css-page/cssom/page-001.html
new file mode 100644
index 00000000000..2f6b4dde050
--- /dev/null
+++ b/tests/wpt/tests/css/css-page/cssom/page-001.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/cssom/#the-csspagerule-interface">
+<title>Basic CSSPageRule CSSOM test</title>
+<style id="sheet">
+ @page {}
+ @page :left {}
+ @page named { margin: 10px 20px; }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ var sheet = document.getElementById("sheet").sheet;
+ test(()=> {
+ assert_not_equals(sheet, null);
+ assert_equals(sheet.rules.length, 3);
+ }, "There should be 3 @page rules.");
+
+ test(()=> {
+ assert_equals(sheet.rules[0].constructor.name, "CSSPageRule");
+ assert_equals(sheet.rules[0].selectorText, "");
+ assert_equals(sheet.rules[0].style.length, 0);
+ }, "Rule #0");
+
+ test(()=> {
+ assert_equals(sheet.rules[1].constructor.name, "CSSPageRule");
+ assert_equals(sheet.rules[1].selectorText, ":left");
+ assert_equals(sheet.rules[1].style.length, 0);
+ }, "Rule #1");
+
+ test(()=> {
+ assert_equals(sheet.rules[2].constructor.name, "CSSPageRule");
+ assert_equals(sheet.rules[2].selectorText, "named");
+ var style = sheet.rules[2].style;
+ assert_equals(style.length, 4);
+ assert_equals(style.marginTop, "10px");
+ assert_equals(style.marginRight, "20px");
+ assert_equals(style.marginBottom, "10px");
+ assert_equals(style.marginLeft, "20px");
+ }, "Rule #2");
+</script>
diff --git a/tests/wpt/tests/css/css-page/cssom/page-002.html b/tests/wpt/tests/css/css-page/cssom/page-002.html
new file mode 100644
index 00000000000..0060d295b4a
--- /dev/null
+++ b/tests/wpt/tests/css/css-page/cssom/page-002.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/cssom/#the-csspagerule-interface">
+<title>Add / remove declarations inside CSSPageRule</title>
+<style id="sheet">
+ @page {}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ var sheet = document.getElementById("sheet").sheet;
+ var pageRule = sheet.rules[0];
+ var style = pageRule.style;
+ test(()=> {
+ assert_equals(style.length, 0);
+ style.setProperty("widows", "7");
+ assert_equals(style.length, 1);
+ assert_equals(style.widows, "7");
+ style.setProperty("margin-left", "50%");
+ assert_equals(style.length, 2);
+ assert_equals(style.marginLeft, "50%");
+ style.setProperty("margin-left", "100px");
+ assert_equals(style.length, 2);
+ assert_equals(style.marginLeft, "100px");
+ style.setProperty("margin", "auto");
+ assert_equals(style.length, 5);
+ assert_equals(style.marginLeft, "auto");
+ }, "Add declarations");
+
+ test(()=> {
+ assert_equals(style.length, 5);
+ style.removeProperty("widows");
+ assert_equals(style.length, 4);
+ style.removeProperty("margin");
+ assert_equals(style.length, 0);
+ }, "Remove declarations");
+</script>
diff --git a/tests/wpt/tests/css/css-pseudo/chrome-first-letter-container-query-crash.html b/tests/wpt/tests/css/css-pseudo/chrome-first-letter-container-query-crash.html
new file mode 100644
index 00000000000..6647e387315
--- /dev/null
+++ b/tests/wpt/tests/css/css-pseudo/chrome-first-letter-container-query-crash.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<head>
+ <title>Chrome crash issue 41492455</title>
+ <link rel="help" href="https://issues.chromium.org/issues/41492455">
+</head>
+<span id="sp"></span>
+<style>
+ head, html, body, span { display: inline-block; }
+ html::first-letter, span::first-letter {
+ color: pink;
+ }
+ span {
+ container-type: inline-size;
+ float: right;
+ }
+ body {
+ writing-mode: vertical-rl;
+ }
+</style>
+<script>
+ document.body.offsetHeight;
+ document.documentElement.style.display = "block";
+ document.head.style.display = "none";
+ document.body.style.display = "block";
+ sp.style.display = "inline";
+ document.body.offsetHeight;
+</script>
diff --git a/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after-ref.html b/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after-ref.html
new file mode 100644
index 00000000000..89bab0829ab
--- /dev/null
+++ b/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<title>CSS Test Reference</title>
+<p>Both 'F's below should be green.</p>
+<div><span style="color:green">F</span>irst-letter</div>
+<div><span style="color:green">F</span>irst-letter</div>
diff --git a/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after.html b/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after.html
new file mode 100644
index 00000000000..95150a0e962
--- /dev/null
+++ b/tests/wpt/tests/css/css-pseudo/first-letter-with-before-after.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>CSS Pseudo Test: ::first-letter text from ::before and ::after</title>
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#generated-content">
+<link rel="match" href="first-letter-with-before-after-ref.html">
+<style>
+ #t1::before { content: "F" }
+ #t2::before { content: "First-letter" }
+ div::first-letter { color: green; }
+</style>
+<p>Both 'F's below should be green.</p>
+<div id="t1">irst-letter</div>
+<div id="t2"></div>
diff --git a/tests/wpt/tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/prefer-inner-target.html b/tests/wpt/tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/prefer-inner-target.html
new file mode 100644
index 00000000000..053b6a1d7e6
--- /dev/null
+++ b/tests/wpt/tests/css/css-scroll-snap/snap-after-relayout/multiple-aligned-targets/prefer-inner-target.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <link rel="help" href="https://drafts.csswg.org/css-scroll-snap" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/dom/events/scrolling/scroll_support.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-actions.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="resources/common.js" ></script>
+ </head>
+ <body>
+ <style>
+ .scroller {
+ overflow: scroll;
+ position: relative;
+ height: 400px;
+ width: 400px;
+ border:solid 1px black;
+ scroll-snap-type: y mandatory;
+ }
+ .no-snap { scroll-snap-align: none }
+ .scroller div:focus {
+ border: solid 1px red;
+ }
+ .large-space {
+ height: 300vh;
+ width: 300vw;
+ position: absolute;
+ }
+ .target {
+ scroll-snap-align: start;
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ border: solid 1px black;
+ }
+ .top {
+ top: 0px;
+ }
+ .left {
+ left: 0px;
+ }
+ .right {
+ left: 200px;
+ }
+ .bottom {
+ top: 200px;
+ }
+ .inner {
+ text-align: right;
+ }
+ .inner1 {
+ height: 150px;
+ width: 150px;
+ top: 150px;
+ left: 100px;
+ background-color: blue;
+ }
+ .inner2 {
+ height: 100px;
+ width: 100px;
+ top: 150px;
+ left: 100px;
+ background-color: pink;
+ }
+ .inner3 {
+ height: 75px;
+ width: 75px;
+ top: 150px;
+ left: 100px;
+ background-color: green;
+ }
+ .inner4 {
+ height: 50px;
+ width: 50px;
+ top: 150px;
+ left: 100px;
+ background-color: grey;
+ }
+ .outer {
+ height: 200px;
+ width: 200px;
+ top: 150px;
+ left: 50px;
+ left: 50px;
+ background-color: yellow;
+ }
+ </style>
+ <div id="scroller" class="scroller">
+ <div class="large-space"></div>
+ <div class="top left target">Top Left</div>
+ <div class="top right target">Top Right</div>
+ <div class="outer target" id="outer">Outer</div>
+ <div class="inner inner1 target" id="inner1">I1</div>
+ <div class="inner inner2 target" id="inner2">I2</div>
+ <div class="inner inner3 target" id="inner3">I3</div>
+ <div class="inner inner4 target" id="inner4">I4</div>
+ </div>
+ <script>
+ function cleanup() {
+ inner.style.top = 100;
+ outer.style.top = 100;
+ }
+ window.onload = (async () => {
+ const inner1 = document.getElementById("inner1");
+ const inner2 = document.getElementById("inner2");
+ const inner3 = document.getElementById("inner3");
+ const inner4 = document.getElementById("inner4");
+ const outer = document.getElementById("outer");
+ const scroller = document.getElementById("scroller");
+
+ promise_test(async (t) => {
+ await waitForCompositorCommit();
+
+ await runScrollSnapSelectionVerificationTest(t, scroller,
+ [inner1, inner2, inner3, inner4, outer], inner4, "y");
+
+ // Push inner4 outside the snapport. It should no longer be considered
+ // the snap target; inner3 is next in line.
+ inner4.style.left = "500px";
+ await runScrollSnapSelectionVerificationTest(t, scroller,
+ [inner1, inner2, inner3, inner4, outer], inner3, "y");
+ inner4.style.left = "100px";
+ }, "snap container selects innermost area as snap target");
+
+ promise_test(async (t) => {
+ t.add_cleanup(() => {
+ outer.style.top = "150px";
+ });
+ await waitForCompositorCommit();
+
+ // Move outer target below inner targets.
+ outer.style.top = "400px";
+
+ // Snap to now-below outer target.
+ scroller.scrollTop = outer.offsetTop;
+
+ runLayoutSnapSeletionVerificationTest(t, scroller,
+ [inner1, inner2, inner3, inner4], outer, "y");
+ }, "snap container follows selected snap target after layout change " +
+ "(the pre-existing snap target should not be overriden because of " +
+ "the innermost area)");
+ });
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-text/crashtests/eol-spaces-bidi-min-content-crash.html b/tests/wpt/tests/css/css-text/crashtests/eol-spaces-bidi-min-content-crash.html
new file mode 100644
index 00000000000..d8c3ec337b3
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/crashtests/eol-spaces-bidi-min-content-crash.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://issues.chromium.org/issues/324684931">
+
+<style>
+ div {
+ width: min-content;
+ }
+</style>
+
+<div dir="rtl">X&#x3000;&#x3000; X</div>
diff --git a/tests/wpt/tests/css/css-transitions/starting-style-cascade.html b/tests/wpt/tests/css/css-transitions/starting-style-cascade.html
index 263e4721742..cef3e88b656 100644
--- a/tests/wpt/tests/css/css-transitions/starting-style-cascade.html
+++ b/tests/wpt/tests/css/css-transitions/starting-style-cascade.html
@@ -53,6 +53,10 @@
<div class="color-transition"></div>
</div>
<script>
+ setup(() => {
+ assert_true(supportsStartingStyle(), "Prerequisite: @starting-style parses");
+ });
+
promise_test(async t => {
await waitForAnimationFrames(2);
t1.removeAttribute("hidden");
diff --git a/tests/wpt/tests/css/css-transitions/starting-style-rule-none.html b/tests/wpt/tests/css/css-transitions/starting-style-rule-none.html
index fd6879b5ee4..91e4fe35340 100644
--- a/tests/wpt/tests/css/css-transitions/starting-style-rule-none.html
+++ b/tests/wpt/tests/css/css-transitions/starting-style-rule-none.html
@@ -20,6 +20,10 @@
}
</style>
<script>
+ setup(() => {
+ assert_true(supportsStartingStyle(), "Prerequisite: @starting-style parses");
+ });
+
promise_test(async t => {
await waitForAnimationFrames(2);
assert_equals(getComputedStyle(target).backgroundColor, "rgb(0, 128, 0)",
diff --git a/tests/wpt/tests/css/css-transitions/support/helper.js b/tests/wpt/tests/css/css-transitions/support/helper.js
index d5fa61b15ef..a37aae91830 100644
--- a/tests/wpt/tests/css/css-transitions/support/helper.js
+++ b/tests/wpt/tests/css/css-transitions/support/helper.js
@@ -317,4 +317,10 @@ root.frameTimeout = (promiseToWaitOn, framesToWait, message) => {
return Promise.race([timeoutPromise, wrappedPromiseToWaitOn]);
};
+root.supportsStartingStyle = () => {
+ let sheet = new CSSStyleSheet();
+ sheet.replaceSync("@starting-style{}");
+ return sheet.cssRules.length == 1;
+};
+
})(window);
diff --git a/tests/wpt/tests/css/css-variables/variables-animation-math-functions-tentative.html b/tests/wpt/tests/css/css-variables/variables-animation-math-functions-tentative.html
new file mode 100644
index 00000000000..7c33d6cfa36
--- /dev/null
+++ b/tests/wpt/tests/css/css-variables/variables-animation-math-functions-tentative.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>angle custom properties interpolation with progress-*() functions</title>
+ <link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org">
+ <link rel="help" href="https://drafts.csswg.org/css-values-5/#progress">
+ <meta name="assert" content="angle custom properties support interpolation with progress-*() functions.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/interpolation-testcommon.js"></script>
+ </head>
+ <style>
+ :root {
+ font-size: 10px;
+ }
+ @property --my-angle {
+ syntax: "<angle>";
+ initial-value: 0deg;
+ inherits: false;
+ }
+ </style>
+ <body>
+ <script>
+ test_interpolation({
+ property: '--my-angle',
+ from: '100deg',
+ to: 'calc(sign(20rem - 20px) * 180deg)',
+ }, [
+ {at: -1, expect: '20deg'},
+ {at: 0, expect: '100deg'},
+ {at: 0.125, expect: '110deg'},
+ {at: 0.875, expect: '170deg'},
+ {at: 1, expect: '180deg'},
+ {at: 2, expect: '260deg'}
+ ]);
+
+ test_interpolation({
+ property: '--my-angle',
+ from: 'calc(sign(20rem - 20px) * 100deg)',
+ to: 'calc(progress(10rem from 20px to 100px) * 180deg)',
+ }, [
+ {at: -1, expect: '20deg'},
+ {at: 0, expect: '100deg'},
+ {at: 0.125, expect: '110deg'},
+ {at: 0.875, expect: '170deg'},
+ {at: 1, expect: '180deg'},
+ {at: 2, expect: '260deg'}
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/class-specificity-ref.html b/tests/wpt/tests/css/css-view-transitions/class-specificity-ref.html
new file mode 100644
index 00000000000..5c882ada040
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/class-specificity-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>View transitions: class specificity (ref)</title>
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<style>
+body {
+ background: pink;
+}
+div {
+ contain: paint;
+ width: 100px;
+ height: 100px;
+ background: blue;
+ border: 10px solid green;
+}
+</style>
+<div></div>
diff --git a/tests/wpt/tests/css/css-view-transitions/class-specificity.html b/tests/wpt/tests/css/css-view-transitions/class-specificity.html
new file mode 100644
index 00000000000..55de2ec3884
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/class-specificity.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>View transitions: class specificity</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="class-specificity-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<style>
+#shared {
+ contain: paint;
+ width: 100px;
+ height: 100px;
+ background: blue;
+ view-transition-name: shared;
+ view-transition-class: sharedclass1 sharedclass2;
+}
+
+/* We're verifying what we capture, so just display the old contents for 5 minutes. */
+html::view-transition { background: pink; }
+html::view-transition-group(shared) { animation-duration: 300s; }
+
+html::view-transition-old(shared) {
+ animation: unset;
+ opacity: 1;
+ border: 10px solid red;
+}
+html::view-transition-old(*.sharedclass1.sharedclass2) {
+ border: 10px solid yellow;
+}
+
+html::view-transition-old(*.sharedclass1) {
+ border: 10px solid green;
+}
+
+html::view-transition-old(*) {
+ border: 10px solid orange;
+}
+
+html::view-transition-new(shared) { animation: unset; opacity: 0; }
+
+html::view-transition-old(root) { animation: unset; opacity: 0; }
+html::view-transition-new(root) { animation: unset; opacity: 0 }
+</style>
+<div id=shared></div>
+<script>
+failIfNot(document.startViewTransition, "Missing document.startViewTransition");
+
+async function runTest() {
+ document.startViewTransition(() => {
+ requestAnimationFrame(() => requestAnimationFrame(takeScreenshot));
+ });
+}
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/pseudo-element-animations.html b/tests/wpt/tests/css/css-view-transitions/pseudo-element-animations.html
new file mode 100644
index 00000000000..a7c3247479d
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/pseudo-element-animations.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>CSS Animations on view transition pseudos run more than once</title>
+<link rel="help" href="https://drafts.csswg.org/css-animations-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../css-animations/support/testcommon.js"></script>
+<style>
+:root::view-transition,
+:root::view-transition-group(root),
+:root::view-transition-image-pair(root),
+:root::view-transition-old(root),
+:root::view-transition-new(root) {
+ animation: view-transition-animation 1ms;
+}
+@keyframes view-transition-animation {
+ to { opacity: 0 }
+}
+</style>
+<div id="log"></div>
+<script>
+"use strict";
+promise_test(async t => {
+ let viewTransition = document.startViewTransition(() => {});
+ await viewTransition.ready;
+ assert_equals(document.documentElement.getAnimations({ subtree: true }).length, 5, "Starting a view transition should start related animations.");
+
+ await viewTransition.finished;
+ assert_equals(document.documentElement.getAnimations({ subtree: true }).length, 0, "Stopping a view transition should stop related animations.");
+
+ await waitForNextFrame();
+ viewTransition = document.startViewTransition(() => {});
+ await viewTransition.ready;
+ assert_equals(document.documentElement.getAnimations({ subtree: true }).length, 5, "Re-starting a view-transition should restart related animations.");
+}, "CSS Animations on view transitions are canceled and restarted when the view transition starts and ends.");
+</script>
diff --git a/tests/wpt/tests/css/cssom/getComputedStyle-pseudo-with-argument.html b/tests/wpt/tests/css/cssom/getComputedStyle-pseudo-with-argument.html
new file mode 100644
index 00000000000..452f2bb2c63
--- /dev/null
+++ b/tests/wpt/tests/css/cssom/getComputedStyle-pseudo-with-argument.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSSOM: Handling pseudo-elements with arguments</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<link rel=help href=https://drafts.csswg.org/cssom/#dom-window-getcomputedstyle>
+<style>
+#pseudo-invalid::highlight(name) {
+ color: rgb(0, 128, 0);
+}
+#pseudo-invalid::view-transition-image-pair(name) {
+ color: rgb(0, 128, 0);
+}
+#pseudo-invalid::view-transition-group(name) {
+ color: rgb(0, 128, 0);
+}
+#pseudo-invalid::view-transition-old(name) {
+ color: rgb(0, 128, 0);
+}
+#pseudo-invalid::view-transition-new(name) {
+ color: rgb(0, 128, 0);
+}
+</style>
+<ul><li id="pseudo-invalid">Item</li></ul>
+<script>
+[
+ "::before(test)",
+ "::highlight",
+ "::highlight(",
+ "::highlight()",
+ "::highlight(1)",
+ "::highlight($)",
+ "::highlight (name)",
+ "::highlight(name)a",
+ "::view-transition-group(*)",
+].forEach(nonParsablePseudoIdentifier => {
+ test(() => {
+ const li = document.querySelector('li');
+ assert_equals(getComputedStyle(li, nonParsablePseudoIdentifier).length, 0);
+ }, `This pseudo-element should not parse: ${nonParsablePseudoIdentifier}`)
+});
+
+[
+ "::highlight(name)",
+ "::highlight(\nname",
+ "::highlight(name\t",
+ "::highlight( name ",
+ "::highlight( n\\61me )"
+].forEach(parsablePseudoIdentifier => {
+ test(() => {
+ const li = document.querySelector('li');
+ assert_true(getComputedStyle(li, parsablePseudoIdentifier).length != 0);
+ assert_equals(getComputedStyle(li, parsablePseudoIdentifier).color, "rgb(0, 128, 0)");
+ }, `This pseudo-element should parse: ${parsablePseudoIdentifier}`);
+});
+</script>
diff --git a/tests/wpt/tests/css/mediaqueries/display-mode.html b/tests/wpt/tests/css/mediaqueries/display-mode.html
index e6633de856c..4ade16799f9 100644
--- a/tests/wpt/tests/css/mediaqueries/display-mode.html
+++ b/tests/wpt/tests/css/mediaqueries/display-mode.html
@@ -9,6 +9,7 @@
query_should_be_known("(display-mode: browser)");
query_should_be_known("(display-mode: minimal-ui)");
query_should_be_known("(display-mode: fullscreen)");
+ query_should_be_known("(display-mode: picture-in-picture)");
query_should_be_unknown("(display-mode: 0)");
query_should_be_unknown("(display-mode: none)");
diff --git a/tests/wpt/tests/css/motion/animation/offset-rotate-interpolation-math-functions-tentative.html b/tests/wpt/tests/css/motion/animation/offset-rotate-interpolation-math-functions-tentative.html
new file mode 100644
index 00000000000..34e0abf2b0d
--- /dev/null
+++ b/tests/wpt/tests/css/motion/animation/offset-rotate-interpolation-math-functions-tentative.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>offset-rotate interpolation with css math functions</title>
+ <link rel="author" title="Daniil Sakhapov" href="mailto:sakhapov@chromium.org">
+ <link rel="help" href="https://drafts.fxtf.org/motion-1/#offset-rotate-property">
+ <link rel="help" href="https://drafts.csswg.org/css-values-5/#progress">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/css/support/interpolation-testcommon.js"></script>
+ </head>
+ <style>
+ :root {
+ font-size: 10px;
+ }
+ </style>
+ <body>
+ <script>
+ test_interpolation({
+ property: 'offset-rotate',
+ from: '100deg',
+ to: 'calc(sign(20rem - 20px) * 180deg)',
+ }, [
+ {at: -1, expect: '20deg'},
+ {at: 0, expect: '100deg'},
+ {at: 0.125, expect: '110deg'},
+ {at: 0.875, expect: '170deg'},
+ {at: 1, expect: '180deg'},
+ {at: 2, expect: '260deg'}
+ ]);
+
+ test_interpolation({
+ property: 'offset-rotate',
+ from: 'calc(sign(20rem - 20px) * 100deg)',
+ to: 'calc(progress(10rem from 20px to 100px) * 180deg)',
+ }, [
+ {at: -1, expect: '20deg'},
+ {at: 0, expect: '100deg'},
+ {at: 0.125, expect: '110deg'},
+ {at: 0.875, expect: '170deg'},
+ {at: 1, expect: '180deg'},
+ {at: 2, expect: '260deg'}
+ ]);
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001-ref.html
new file mode 100644
index 00000000000..c45db87fa32
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div class="after"></div>
+<div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001.html
new file mode 100644
index 00000000000..6edb3da03ee
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-001.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-001-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+:has(> span)::after {
+ font: 15px/1 Ahem;
+ content: 'x';
+}
+</style>
+<div><span></span></div>
+<div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002-ref.html
new file mode 100644
index 00000000000..a8138c25726
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div></div>
+<div class="after"></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002.html
new file mode 100644
index 00000000000..59dd2a9a1b5
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-002.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-002-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+:has(> span)::after {
+ font: 15px/1 Ahem;
+ content: 'x';
+}
+</style>
+<div></div>
+<div><span></span></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003-ref.html
new file mode 100644
index 00000000000..a9b8e248d69
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div><span class="after"></span><span></span></div>
+<div><span></span><span></span></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003.html
new file mode 100644
index 00000000000..f94636f5dcc
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-003.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-003-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+:has(> .a) .b::after {
+ font: 15px/1 ahem;
+ content: 'x';
+}
+</style>
+<div><span class="b"></span><span class="a"></span><span></span></div>
+<div><span class="b"></span></div>
+
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004-ref.html
new file mode 100644
index 00000000000..0d97e1d1c2f
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div><span></span><span></span></div>
+<div><span class="after"></span><span></span></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004.html
new file mode 100644
index 00000000000..82e42005d06
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-004.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-004-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+:has(> .a) .b::after {
+ font: 15px/1 ahem;
+ content: 'x';
+}
+</style>
+<div><span class="b"></span></div>
+<div><span class="b"></span><span class="a"></span><span></span></div>
+
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005-ref.html
new file mode 100644
index 00000000000..97c2bf2ade1
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div><div class="after"><span></span></div></div>
+<div><div></div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005.html
new file mode 100644
index 00000000000..9e7cbe96fcf
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-005.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-005-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.cousin:has(> span)::after {
+ font: 15px/1 Ahem;
+ content: 'x';
+}
+</style>
+<div><div class="cousin"><span></span></div></div>
+<div><div class="cousin"></div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006-ref.html
new file mode 100644
index 00000000000..d052141d8ed
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.after::after {
+ font: 15px/1 Ahem;
+ content: "x";
+}
+</style>
+<div><div></div></div>
+<div><div class="after"><span></span></div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006.html
new file mode 100644
index 00000000000..d8747abd4a4
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-006.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-006-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+div {
+ width: 20px;
+ height: 20px;
+}
+
+.cousin:has(> span)::after {
+ font: 15px/1 Ahem;
+ content: 'x';
+}
+</style>
+<div><div class="cousin"></div></div>
+<div><div class="cousin"><span></span></div></div>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007-ref.html
new file mode 100644
index 00000000000..24f4502b786
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+::marker {
+ font: 15px/1 Ahem;
+}
+
+.no-marker::marker {
+ content: '';
+}
+</style>
+<ul>
+ <li class="no-marker"><span></span></li>
+ <li></li>
+</ul>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007.html
new file mode 100644
index 00000000000..0e245f5aaff
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-007.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-007-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+::marker {
+ font: 15px/1 Ahem;
+}
+
+:has(> span)::marker {
+ content: '';
+}
+</style>
+<ul>
+ <li><span></span></li>
+ <li></li>
+</ul>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008-ref.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008-ref.html
new file mode 100644
index 00000000000..ad293bab59e
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+::marker {
+ font: 15px/1 Ahem;
+}
+
+.no-marker::marker {
+ content: '';
+}
+</style>
+<ul>
+ <li><span></span></li>
+ <li class="no-marker"></li>
+</ul>
diff --git a/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008.html b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008.html
new file mode 100644
index 00000000000..59844419ffa
--- /dev/null
+++ b/tests/wpt/tests/css/selectors/has-style-sharing-pseudo-008.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="David Shin" href="mailto:dshin@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#relational">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1876962">
+<link rel="match" href="has-style-sharing-pseudo-008-ref.html">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<meta name="assert" content="Ensure that style sharing optimizations do not interfere with :has() selector matching.">
+<style>
+::marker {
+ font: 15px/1 Ahem;
+}
+
+:has(> span)::marker {
+ content: '';
+}
+</style>
+<ul>
+ <li></li>
+ <li><span></span></li>
+</ul>
diff --git a/tests/wpt/tests/document-picture-in-picture/display-mode.https.html b/tests/wpt/tests/document-picture-in-picture/display-mode.https.html
new file mode 100644
index 00000000000..48885353576
--- /dev/null
+++ b/tests/wpt/tests/document-picture-in-picture/display-mode.https.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>Test picture-in-picture display mode</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>
+<body>
+<script>
+async_test((t) => {
+ test_driver.bless('request PiP window').then(t.step_func(_ => {
+ documentPictureInPicture.requestWindow().then(t.step_func_done(async (pipWindow) => {
+ await new Promise(requestAnimationFrame);
+ assert_true(pipWindow.matchMedia('(display-mode: picture-in-picture)'.matches));
+ }));
+ }));
+});
+</script>
+</body>
diff --git a/tests/wpt/tests/document-picture-in-picture/focus-opener.https.html b/tests/wpt/tests/document-picture-in-picture/focus-opener.https.html
new file mode 100644
index 00000000000..880e9d915ef
--- /dev/null
+++ b/tests/wpt/tests/document-picture-in-picture/focus-opener.https.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Test that a document picture-in-picture window can use Window's focus()
+ API to focus its opener window</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>
+<body>
+ <iframe></iframe>
+<script>
+promise_test(async (t) => {
+ await test_driver.bless('request PiP window from top window');
+ const pipWindow = await documentPictureInPicture.requestWindow();
+
+ // Blur this window by focusing the iframe. This will allow us to detect that
+ // the document picture-in-picture window has focused us.
+ const blurPromise = new Promise(async (resolve) => {
+ window.addEventListener('blur', resolve, { once: true });
+ await test_driver.bless('focus inner iframe to blur window');
+ document.getElementsByTagName('iframe')[0].focus();
+ });
+ await blurPromise;
+
+ // Now focus this window from the document picture-in-picture window's
+ // context.
+ const focusPromise = new Promise(async (resolve) => {
+ window.addEventListener('focus', resolve, { once: true });
+ await test_driver.bless('focus opener window', pipWindow);
+ const focusScript = pipWindow.document.createElement('script');
+ focusScript.setAttribute('src', 'support/focus-opener.js');
+ pipWindow.document.body.append(focusScript);
+ });
+ return focusPromise;
+});
+</script>
+</body>
diff --git a/tests/wpt/tests/document-picture-in-picture/support/focus-opener.js b/tests/wpt/tests/document-picture-in-picture/support/focus-opener.js
new file mode 100644
index 00000000000..679eef3b22e
--- /dev/null
+++ b/tests/wpt/tests/document-picture-in-picture/support/focus-opener.js
@@ -0,0 +1,3 @@
+// This script runs in the document picture-in-picture window to focus its
+// opener window.
+opener.focus();
diff --git a/tests/wpt/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html b/tests/wpt/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html
index cfc782a809a..be4176df59d 100644
--- a/tests/wpt/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html
+++ b/tests/wpt/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html
@@ -10,11 +10,14 @@
width: 200px;
height: 200px;
overflow: scroll;
+ position: absolute;
+ left: 150px;
+ top: 150px;
}
#innerDiv {
- width: 400px;
- height: 400px;
+ width: 250px;
+ height: 250px;
}
</style>
@@ -45,7 +48,7 @@ function runTest() {
await waitForCompositorCommit();
// Do a horizontal scroll and wait for overscroll event.
- await touchScrollInTarget(300, scrolling_div , 'right');
+ await touchScrollInTarget(100, scrolling_div , 'right');
await waitFor(() => { return overscrolled_x_delta > 0; },
'Scroller did not receive overscroll event after horizontal scroll.');
assert_equals(scrolling_div.scrollWidth - scrolling_div.scrollLeft,
@@ -55,7 +58,7 @@ function runTest() {
overscrolled_y_delta = 0;
// Do a vertical scroll and wait for overscroll event.
- await touchScrollInTarget(300, scrolling_div, 'down');
+ await touchScrollInTarget(100, scrolling_div, 'down');
await waitFor(() => { return overscrolled_y_delta > 0; },
'Scroller did not receive overscroll event after vertical scroll.');
assert_equals(scrolling_div.scrollHeight - scrolling_div.scrollTop,
diff --git a/tests/wpt/tests/editing/edit-context/edit-context-basics.tentative.html b/tests/wpt/tests/editing/edit-context/edit-context-basics.tentative.html
index 78b6824921a..0011270c812 100644
--- a/tests/wpt/tests/editing/edit-context/edit-context-basics.tentative.html
+++ b/tests/wpt/tests/editing/edit-context/edit-context-basics.tentative.html
@@ -191,6 +191,19 @@
assert_equals(editContext.selectionStart, 3);
assert_equals(editContext.selectionEnd, 0);
}, 'EditContext should allow a backwards selection');
+
+ test(function() {
+ const editContext = new EditContext();
+ assert_not_equals(editContext, null);
+ editContext.updateText(6, 0, "abcdef");
+ assert_equals(editContext.text, "abcdef");
+
+ editContext.updateText(2, 5, "ghi");
+ assert_equals(editContext.text, "abghif");
+
+ editContext.updateText(5, 2, "jkl");
+ assert_equals(editContext.text, "abjklf");
+ }, 'updateText can replace substrings including with backwards parameters');
</script>
</body>
</html>
diff --git a/tests/wpt/tests/editing/other/paste-in-list-with-inline-style.tentative.html b/tests/wpt/tests/editing/other/paste-in-list-with-inline-style.tentative.html
new file mode 100644
index 00000000000..97710e805dd
--- /dev/null
+++ b/tests/wpt/tests/editing/other/paste-in-list-with-inline-style.tentative.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>This tests for a bug in ReplaceSelectionCommand where styles are lost during paste.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<span id="copy" style="font-weight: bold;">copy this</span>
+<div id="paste" contenteditable="true"> <ul><li id="list1"></li></ul></div>
+<div id="log"></div>
+<script>
+"use strict";
+
+setup({explicit_done: true});
+
+function runTests() {
+ test(function() {
+ var selection = window.getSelection();
+ selection.selectAllChildren(document.getElementById('copy'));
+ document.execCommand('Copy');
+ var sample = document.getElementById('list1');
+ selection.collapse(sample);
+ document.execCommand('Paste');
+
+ assert_equals(sample.innerHTML, '<span style="font-weight: 700;">copy this</span>');
+ assert_true(selection.isCollapsed);
+ }, "");
+ done();
+}
+
+window.addEventListener("load", runTests, {once: true});
+</script>
diff --git a/tests/wpt/tests/event-timing/interactionid-composition-manual.html b/tests/wpt/tests/event-timing/interactionid-composition-manual.html
new file mode 100644
index 00000000000..2b4f2aab094
--- /dev/null
+++ b/tests/wpt/tests/event-timing/interactionid-composition-manual.html
@@ -0,0 +1,162 @@
+<!doctype html>
+<html>
+
+<head>
+ <style>
+ table,
+ td {
+ padding: 8px;
+ border: 1px solid black;
+ }
+ </style>
+</head>
+
+<body>
+ <title>Event Timing: interactionId composition events.</title>
+ <form>
+ <b> Select your Operating System from the list</b>
+ <select id="option" onchange="dropdownMenu()">
+ <option> ---Choose OS--- </option>
+ <option> Linux </option>
+ <option> Windows </option>
+ </select>
+ <p> Your selected OS is:
+ <input type="text" id="os" size="20">
+ </p>
+ </form>
+ <pre>
+ Steps:
+ 1) Open <b id = "IMEtype"></b> IME and select Hiragana input method.
+ 2) Click at the above textbox and then type 'a' using keyboard.
+ 3) Press the '{Enter}' key to complete the IME composition.
+ 4) <a href="interactionid-composition-manual.html">Click here</a> to test again if not following the steps exactly.
+
+ <textarea id='test' placeholder="enter 'a'"></textarea>
+
+Expected Result:
+ The test is successful when the sentence "PASS Event Timing: interactionId composition events" is displayed
+ at the bottom of the page after completing all the steps. If there is an indicated Harness Error next to the sentence, the test failed.
+ Moreover, the event log table below provides a summary of the keyboard events processed throughout the test.
+ Here is a breakdown of the columns in the table:
+
+ 1. <strong>InteractionId</strong>: Identifies the specific interaction to which an event belongs.
+ 2. <strong>EventType</strong>: Specifies the type of event that occurred during a particular interaction. There are
+ seven possible event types:
+ - 'keydown'
+ - 'keypress'
+ - 'input'
+ - 'keyup'
+ - 'compositionupdate'
+ - 'compositionstart'
+ - 'compositionend'
+ 3. <strong>NumberOfEvents</strong>: Indicates the number of times a particular type of event was recorded in a single interaction.
+
+</pre>
+
+ <table id="eventLogTable">
+ <tr>
+ <td>InteractionId</td>
+ <td>Event Type</td>
+ <td>Number of Events</td>
+ </tr>
+ </table>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src=resources/event-timing-test-utils.js></script>
+ <script>
+ setup({ explicit_timeout: true, explicit_done: true });
+
+ function dropdownMenu() {
+ var list = document.getElementById("option");
+ document.getElementById("os").value = list.options[list.selectedIndex].text;
+ if (document.getElementById("os").value == "Linux") {
+ document.getElementById("IMEtype").textContent = "Japanese - Mozc";
+ }
+ else if (document.getElementById("os").value == "Windows") {
+ document.getElementById("IMEtype").textContent = "Japanese Microsoft";
+ }
+ }
+
+ function logEventSummary(interactionId, eventType, nrOfEvents) {
+
+ var table = document.getElementById("eventLogTable");
+ var row = table.insertRow();
+
+ // Add values to the table
+ var cell = row.insertCell();
+ cell.innerHTML = interactionId;
+ cell = row.insertCell();
+ cell.innerHTML = eventType;
+ cell = row.insertCell();
+ cell.innerHTML = nrOfEvents;
+ }
+
+ let observedEntries = [];
+ let map = new Map();
+ const events = ['keydown', 'keypress', 'input', 'keyup', 'compositionupdate', 'compositionstart', 'compositionend'];
+
+
+ function eventsForCheck(entry) {
+ if (events.includes(entry.name)) {
+ if (map.has(entry.name)) {
+ map.get(entry.name).push({ interactionId: entry.interactionId, startTime: entry.startTime });
+ return true;
+ } else {
+ map.set(entry.name, [{ interactionId: entry.interactionId, startTime: entry.startTime }]);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ test(function () {
+ assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.');
+ new PerformanceObserver(entryList => {
+ observedEntries = observedEntries.concat(entryList.getEntries().filter(eventsForCheck));
+
+ if (!observedEntries.find(entry => entry.name === "compositionend"))
+ return;
+
+ assert_equals(map.get('compositionstart')[0].interactionId, 0, 'Compositionstart should not have an interactionId');
+ logEventSummary(map.get('compositionstart')[0].interactionId, "compositionstart", 1);
+ assert_equals(map.get("input").length, map.get("compositionupdate").length, "For every input there should be exactly one compositionupdate");
+
+ // Create a Set to track seen input values
+ const seenInteractionIds = new Set();
+
+ map.get("input").forEach(value => {
+ assert_false(seenInteractionIds.has(value.interactionId), "All Inputs shall have unique InteractionIds.");
+ seenInteractionIds.add(value);
+ assert_greater_than(value.interactionId, 0, 'Input should have an interactionId greater than 0');
+ const filteredArrayKeydowns = map.get('keydown').filter(interactionId => interactionId === value.interactionId);
+ const countKeydowns = filteredArrayKeydowns.length;
+ logEventSummary(value.interactionId, "keydown", countKeydowns);
+ assert_true((countKeydowns <= 1), "For each input there should be no more than 1 keydown.");
+
+ logEventSummary(value.interactionId, "compositionupdate", 1);
+ logEventSummary(value.interactionId, "input", 1);
+
+ const filteredArrayKeyups = map.get('keyup').filter(interactionId => interactionId === value.interactionId);
+ const countKeyups = filteredArrayKeyups.length;
+ logEventSummary(value.interactionId, "keyup", countKeyups);
+
+ filteredArrayKeyups.forEach(keyupEntry => {
+ assert_true(keyupEntry.startTime > value.startTime, 'Keyup start time should be greater than input start time');
+ });
+
+ });
+
+ assert_equals(map.get('compositionend')[0].interactionId, 0, 'Compositionend should not have an interactionId');
+ logEventSummary(map.get('compositionstart')[0].interactionId, "compositionend", 1);
+ done();
+ observedEntries = [];
+ }).observe({ type: "event" });
+
+ addListeners(document.getElementById('test'), events);
+ });
+
+ </script>
+</body>
+
+</html> \ No newline at end of file
diff --git a/tests/wpt/tests/event-timing/interactionid-keypress.html b/tests/wpt/tests/event-timing/interactionid-keypress.html
new file mode 100644
index 00000000000..a6f20099671
--- /dev/null
+++ b/tests/wpt/tests/event-timing/interactionid-keypress.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<meta name="timeout" content="long">
+<title>Event Timing: interactionId-keypress.</title>
+<textarea id='test'></textarea>
+<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>
+<script src=resources/event-timing-test-utils.js></script>
+
+<script>
+ let observedEntries = [];
+ let map = new Map();
+ const events = ['keydown','keypress','keyup'];
+
+ async_test(function (t) {
+ assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.');
+
+ new PerformanceObserver(t.step_func(entryList => {
+ observedEntries = observedEntries.concat(entryList.getEntries().filter(filterAndAddToMap(events, map)));
+ if (observedEntries.length < 3)
+ return;
+ assert_greater_than(map.get('keypress'), 0, 'Should have a non-trivial interactionId');
+ assert_equals(map.get('keydown'), map.get('keypress'), 'The keydown and the keypress should have the same interactionId');
+ assert_equals(map.get('keyup'), map.get('keypress'), 'The keyup and the keypress should have the same interactionId');
+ assert_equals('t', document.getElementById('test').value);
+ t.done();
+ })).observe({ type: "event" });
+
+ addListenersAndPress(document.getElementById('test'), 't', events);
+ }, "Event Timing: compare event timing interactionId for keypress.");
+
+
+</script>
+
+</html> \ No newline at end of file
diff --git a/tests/wpt/tests/event-timing/modal-dialog-interrupt-paint.html b/tests/wpt/tests/event-timing/modal-dialog-interrupt-paint.html
new file mode 100644
index 00000000000..011311a03a3
--- /dev/null
+++ b/tests/wpt/tests/event-timing/modal-dialog-interrupt-paint.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<meta charset=utf-8 />
+<title>Event Timing: Modal Dialog Interrupt Paint</title>
+<button id='testButtonId'>Click me.</button>
+<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>
+<script src=resources/event-timing-test-utils.js></script>
+
+<script>
+ let observedEntries = [];
+ const map = new Map();
+ const events = ['click'];
+ const showModalDialog = () => {
+ alert();
+ };
+ document.getElementById('testButtonId').addEventListener("click", showModalDialog);
+
+ promise_test(async t => {
+ assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.');
+
+ const callback = (entryList) => { observedEntries = observedEntries.concat(entryList.getEntries().filter(filterAndAddToMap(events, map))); };
+ const readyToResolve = () => { return observedEntries.length >= 1; };
+ const observerPromise = createPerformanceObserverPromise(['event'], callback, readyToResolve);
+
+ await interactAndObserve('click', document.getElementById('testButtonId'), observerPromise);
+
+ const clickEntry = observedEntries[0];
+ assert_less_than(clickEntry.startTime + clickEntry.duration, clickEntry.processingEnd, 'Event duration measurement should stop at the modal dialog showing time, which should be before processingEnd.');
+ assert_greater_than(clickEntry.interactionId, 0, 'Should have a non-trivial interactionId for click event');
+ }, "Event Timing: showing modal dialogs is an alternative end point.");
+
+</script>
+
+</html>
diff --git a/tests/wpt/tests/fenced-frame/resources/unreached.https.html b/tests/wpt/tests/fenced-frame/resources/unreached.https.html
new file mode 100644
index 00000000000..bd389ec4fbd
--- /dev/null
+++ b/tests/wpt/tests/fenced-frame/resources/unreached.https.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>File used to assert that navigations do not succeed.</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+
+<body>
+<script>
+ promise_test(async(t) => {
+ assert_unreached('This navigation should not have succeeded.');
+ });
+</script>
+</body>
diff --git a/tests/wpt/tests/fenced-frame/resources/utils.js b/tests/wpt/tests/fenced-frame/resources/utils.js
index cbea173f17a..77af9449b29 100644
--- a/tests/wpt/tests/fenced-frame/resources/utils.js
+++ b/tests/wpt/tests/fenced-frame/resources/utils.js
@@ -250,6 +250,11 @@ function buildRemoteContextForObject(object, uuid, html) {
}
};
+ // If `object` is null (e.g. a window created with noopener), set it to a
+ // dummy value so that the Proxy constructor won't fail.
+ if (object == null) {
+ object = {};
+ }
const proxy = new Proxy(object, handler);
return proxy;
}
diff --git a/tests/wpt/tests/fenced-frame/revoke-popup.https.html b/tests/wpt/tests/fenced-frame/revoke-popup.https.html
new file mode 100644
index 00000000000..e4a2bb26ad2
--- /dev/null
+++ b/tests/wpt/tests/fenced-frame/revoke-popup.https.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<title>Test that window.fence.disableUntrustedNetwork disables
+ popup navigations.</title>
+<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="resources/utils.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+<script>
+
+promise_test(async(t) => {
+ const fencedframe = await attachFencedFrameContext({generator_api: 'fledge'});
+ await fencedframe.execute(() => {});
+
+ const actions = new test_driver.Actions();
+ await actions.setContext(window)
+ .pointerMove(0, 0, {origin: fencedframe.element})
+ .pointerDown()
+ .pointerUp()
+ .send();
+
+ await fencedframe.execute(async () => {
+ await window.fence.disableUntrustedNetwork();
+ // After disabling network, popup navigations should not work.
+ assert_true(navigator.userActivation.isActive,
+ 'The frame should have user activation.');
+ window.popup = attachWindowContext();
+ });
+
+ const result = await Promise.race([
+ fencedframe.execute(async () => {
+ return await window.popup.execute(() => { return 'popup_loaded'; });
+ }),
+ new Promise((resolve) => t.step_timeout(
+ () => resolve('timeout'), 2000))
+ ]);
+ assert_equals(result, 'timeout');
+}, 'window.fence.disableUntrustedNetwork disables popup navigations');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/fenced-frame/revoke-unfenced-top-navigation.https.html b/tests/wpt/tests/fenced-frame/revoke-unfenced-top-navigation.https.html
new file mode 100644
index 00000000000..873404768f0
--- /dev/null
+++ b/tests/wpt/tests/fenced-frame/revoke-unfenced-top-navigation.https.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<title>Test that window.fence.disableUntrustedNetwork disables
+ _unfencedTop navigations.</title>
+<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="resources/utils.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+<script>
+
+promise_test(async(t) => {
+ const fencedframe = await attachFencedFrameContext({generator_api: 'fledge'});
+ await fencedframe.execute(() => {});
+
+ const actions = new test_driver.Actions();
+ await actions.setContext(window)
+ .pointerMove(0, 0, {origin: fencedframe.element})
+ .pointerDown()
+ .pointerUp()
+ .send();
+
+ const destination_url = new URL('resources/unreached.https.html', location.href);
+ fencedframe.execute(async (url) => {
+ await window.fence.disableUntrustedNetwork();
+ // After disabling network, _unfencedTop navigations should not work.
+ assert_true(navigator.userActivation.isActive,
+ 'The frame should have user activation.')
+ const result = window.open(url, '_unfencedTop');
+ assert_equals(result, null, '_unfencedTop did not return a window.');
+ }, [destination_url]);
+
+ // Wait a few seconds.
+ await new Promise((resolve, reject) =>
+ t.step_timeout(() => resolve('timeout'), 3000));
+
+ // Confirm that the fenced frame is still there.
+ await fencedframe.execute(() => {});
+}, 'window.fence.disableUntrustedNetwork disables _unfencedTop navigations');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html
new file mode 100644
index 00000000000..66456a8876b
--- /dev/null
+++ b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-allowed-apis.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+ const blank = 'about:blank';
+ const dangling_url = 'resources/empty.html?\n<';
+ const api_calls = [
+ `window.open(\`${dangling_url}\`,'_self')`,
+ `location.replace(\`${dangling_url}\`)`,
+ ];
+
+ api_calls.forEach(call => {
+ async_test(t => {
+ const iframe =
+ document.body.appendChild(document.createElement('iframe'));
+ t.step(() => {
+ iframe.contentWindow.eval(call)
+ t.step_timeout(()=>{
+ assert_false(iframe.contentWindow.location.href.endsWith(blank));
+ t.done();
+ }, 500);
+ });
+ }, `Does not block ${call}`);
+ });
+</script>
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html
index f27735daa1d..f27735daa1d 100644
--- a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.tentative.sub.html
+++ b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation-data-url.sub.html
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.html
index 61a931608ba..61a931608ba 100644
--- a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.tentative.html
+++ b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.html
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.https.html b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.https.html
new file mode 100644
index 00000000000..3f038cbb7be
--- /dev/null
+++ b/tests/wpt/tests/fetch/security/dangling-markup/dangling-markup-mitigation.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+ function get_requests(worker, expected) {
+ return new Promise(resolve => {
+ navigator.serviceWorker.addEventListener('message', function onMsg(evt) {
+ if (evt.data.size >= expected) {
+ navigator.serviceWorker.removeEventListener('message', onMsg);
+ resolve(evt.data);
+ } else {
+ worker.postMessage("");
+ }
+ });
+ worker.postMessage("");
+ });
+ }
+
+ const resources = [
+ x=>`<link rel="stylesheet" href="404/style?${x}">`,
+ x=>`<link rel="prefetch" as="style" href="404/prefetch?${x}">`,
+ x=>`<script src="404/script?${x}"><\/script>`,
+ x=>`<iframe src="404/iframe?${x}"></iframe>`,
+ x=>`<meta http-equiv="refresh" content="0;url=404/meta?${x}">`,
+ x=>`<a href="404/a?${x}">click</a><script>document.querySelector('a').click()<\/script>`,
+ x=>`<base href="404/base?${x}"><a href>me</a><script>document.querySelector('a').click()<\/script>`,
+ x=>`<video controls poster="404/poster?${x}"></video>`,
+ x=>`<input type="image" src="404/input?${x}">`,
+ x=>`<form method="GET" action="404/form?${x}"></form><script>document.querySelector('form').submit()<\/script>`,
+ x=>`<body background="404/body?${x}"></body>`,
+ ];
+
+ async_test(t => {
+ const script = 'service-worker.js';
+ const paths = [];
+ navigator.serviceWorker.register(script);
+ t.step(async () => {
+ const registration = await navigator.serviceWorker.ready;
+ for (const html of resources) {
+ const iframe1 =
+ document.body.appendChild(document.createElement('iframe'));
+ iframe1.src = 'resources.html?html=' + html`%0A<`;
+ const iframe2 =
+ document.body.appendChild(document.createElement('iframe'));
+ iframe2.src = 'resources.html?html=' + html``;
+ const path = html`EOP`;
+ paths.push(path.substring(path.search('404\\/')+4, path.search('EOP')));
+ }
+
+ const requests = await get_requests(registration.active, resources.length);
+ paths.forEach(path => {
+ assert_true(requests.has(path),
+ `${path} should appear in requests sent`);
+ });
+ await registration.unregister();
+ t.done();
+ });
+ }, 'Only blocks dangling markup requests');
+</script>
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/resources/empty.html b/tests/wpt/tests/fetch/security/dangling-markup/resources/empty.html
new file mode 100644
index 00000000000..0e76edd65b7
--- /dev/null
+++ b/tests/wpt/tests/fetch/security/dangling-markup/resources/empty.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
diff --git a/tests/wpt/tests/fetch/security/dangling-markup/service-worker.js b/tests/wpt/tests/fetch/security/dangling-markup/service-worker.js
new file mode 100644
index 00000000000..837e216a013
--- /dev/null
+++ b/tests/wpt/tests/fetch/security/dangling-markup/service-worker.js
@@ -0,0 +1,35 @@
+const requests = new Set();
+
+addEventListener('install', evt => {
+ evt.waitUntil(self.skipWaiting());
+});
+
+addEventListener('activate', evt => {
+ evt.waitUntil(self.clients.claim());
+});
+
+addEventListener('message', evt => {
+ evt.source.postMessage(requests);
+});
+
+addEventListener('fetch', evt => {
+ const url = new URL(evt.request.url);
+ const path = url.pathname;
+ const search = url.search || "?";
+ if (path.includes('404')) {
+ const dir = path.split('/');
+ const request = dir[dir.length-1] + search;
+ if (!requests.has(request)) {
+ requests.add(request);
+ }
+ evt.respondWith(new Response(""));
+ } else if (path.endsWith('resources.html')) {
+ const html = (new URLSearchParams(search)).get('html');
+ evt.respondWith(new Response(html, {
+ headers: {
+ "Content-Type": "text/html"
+ }
+ }));
+ }
+ return;
+});
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 3b5814b5d4a..8fbdc95dfc5 100644
--- a/tests/wpt/tests/fledge/tentative/auction-config.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/auction-config.https.window.js
@@ -390,3 +390,80 @@ makeTest({
[{width: '100', height: '100'},
{width: '200furlongs', height: '200'}]}
});
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ // The renderURL / report URLs for the first/second iterations of the auction.
+ let renderURL = createRenderURL(uuid);
+ let bidderReportURL1 = createBidderReportURL(uuid, /*id=*/ 1);
+ let bidderReportURL2 = createBidderReportURL(uuid, /*id=*/ 2);
+ let bidderDebugReportURL =
+ createBidderReportURL(uuid, /*id=*/ 'forDebuggingOnly');
+ let sellerReportURL1 = createSellerReportURL(uuid, /*id=*/ 1);
+ let sellerReportURL2 = createSellerReportURL(uuid, /*id=*/ 2);
+ let sellerDebugReportURL =
+ createSellerReportURL(uuid, /*id=*/ 'forDebuggingOnly');
+
+ // reportWin() sends "bidderReportURL1" if
+ // browserSignals.forDebuggingOnlyInCooldownOrLockout is true,
+ // "bidderReportURL2" otherwise.
+ await joinInterestGroup(test, uuid, {
+ ads: [{renderURL: renderURL}],
+ biddingLogicURL: createBiddingScriptURL({
+ generateBid: `
+ forDebuggingOnly.reportAdAuctionWin('${bidderDebugReportURL}');
+ if (!browserSignals.hasOwnProperty(
+ 'forDebuggingOnlyInCooldownOrLockout')) {
+ throw "Missing forDebuggingOnlyInCooldownOrLockout in browserSignals";
+ }
+ let bid = browserSignals.forDebuggingOnlyInCooldownOrLockout ? 1 : 2;
+ return {bid: bid, render: '${renderURL}'};`,
+ reportWin: `
+ if (browserSignals.bid == 1)
+ sendReportTo('${bidderReportURL1}');
+ if (browserSignals.bid == 2)
+ sendReportTo('${bidderReportURL2}');`
+
+ })
+ });
+
+ // reportResult() sends "sellerReportURL1" if
+ // browserSignals.forDebuggingOnlyInCooldownOrLockout in scoreAd() is true,
+ // "sellerReportURL2" otherwise.
+ const auctionConfigOverrides = {
+ decisionLogicURL: createDecisionScriptURL(uuid, {
+ scoreAd: `
+ forDebuggingOnly.reportAdAuctionWin('${sellerDebugReportURL}');
+ if (!browserSignals.hasOwnProperty(
+ 'forDebuggingOnlyInCooldownOrLockout')) {
+ throw "Missing forDebuggingOnlyInCooldownOrLockout in browserSignals";
+ }
+ let desirability =
+ browserSignals.forDebuggingOnlyInCooldownOrLockout ? 1 : 2;
+ return {desirability: desirability};`,
+ reportResult: `
+ if (browserSignals.desirability == 1)
+ sendReportTo('${sellerReportURL1}');
+ if (browserSignals.desirability == 2)
+ sendReportTo('${sellerReportURL2}');`
+ })
+ };
+
+ // In the first auction, browserSignals.forDebuggingOnlyInCooldownOrLockout in
+ // generateBid() and scoreAd() should both be false. After the auction,
+ // lockout and cooldowns should be updated.
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
+ await waitForObservedRequestsIgnoreDebugOnlyReports(
+ uuid, [bidderReportURL2, sellerReportURL2]);
+
+ // In the second auction, browserSignals.forDebuggingOnlyInCooldownOrLockout
+ // in generateBid() and scoreAd() should both be true, since both the buyer
+ // and seller called forDebuggingOnly API in the first auction, so they are in
+ // cooldowns at least (and also in lockout if a debug report is allowed to be
+ // sent).
+ await runBasicFledgeAuctionAndNavigate(test, uuid, auctionConfigOverrides);
+ await waitForObservedRequestsIgnoreDebugOnlyReports(
+ uuid,
+ [bidderReportURL2, sellerReportURL2, bidderReportURL1, sellerReportURL1]);
+}, `forDebuggingOnly lockout and cooldowns updating in one auction, read in another's.`);
diff --git a/tests/wpt/tests/fledge/tentative/component-auction.https.window.js b/tests/wpt/tests/fledge/tentative/component-auction.https.window.js
index 63771d42b86..c70532024ce 100644
--- a/tests/wpt/tests/fledge/tentative/component-auction.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/component-auction.https.window.js
@@ -671,7 +671,7 @@ subsetTest(promise_test, async test => {
browserSignals.prevWinsMs[0][1].renderURL === "${renderURL1}") {
return {bid: 1, allowComponentAuction: true, render: "${renderURL2}"};
}
- throw "Unexpected biddingSignals: " + JSON.stringify(browserSignals);`,
+ throw "Unexpected browserSignals: " + JSON.stringify(browserSignals);`,
reportWin:
`if (browserSignals.renderURL === "${renderURL1}")
sendReportTo("${bidderReportURL1}");
diff --git a/tests/wpt/tests/fledge/tentative/cross-origin.https.window.js b/tests/wpt/tests/fledge/tentative/cross-origin.https.window.js
index 788558e5cf3..a8cf93049fa 100644
--- a/tests/wpt/tests/fledge/tentative/cross-origin.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/cross-origin.https.window.js
@@ -356,8 +356,8 @@ subsetTest(promise_test, async test => {
throw "Wrong origin: " + interestGroup.owner;
if (!interestGroup.biddingLogicURL.startsWith("${bidderOrigin}"))
throw "Wrong origin: " + interestGroup.biddingLogicURL;
- if (interestGroup.ads[0].renderUrl != "${renderURL}")
- throw "Wrong renderURL: " + interestGroup.ads[0].renderUrl;
+ if (interestGroup.ads[0].renderURL != "${renderURL}")
+ throw "Wrong renderURL: " + interestGroup.ads[0].renderURL;
if (browserSignals.seller !== "${sellerOrigin}")
throw "Wrong origin: " + browserSignals.seller;`,
reportWin: `if (browserSignals.topWindowHostname !== "${document.location.hostname}")
diff --git a/tests/wpt/tests/fledge/tentative/direct-from-seller-signals.https.window.js b/tests/wpt/tests/fledge/tentative/direct-from-seller-signals.https.window.js
index 339bc32ee56..d0c0e550c42 100644
--- a/tests/wpt/tests/fledge/tentative/direct-from-seller-signals.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/direct-from-seller-signals.https.window.js
@@ -22,7 +22,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/ null,
/*expectedAuctionSignals=*/ null, /*expectedPerBuyerSignals=*/ null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -38,7 +38,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/1',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -55,7 +55,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
'auctionSignals/2', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -72,7 +72,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
/*expectedAuctionSignals=*/null, 'perBuyerSignals/3'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -89,7 +89,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -106,7 +106,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/1',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -119,7 +119,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
'auctionSignals/2', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -137,7 +137,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -216,7 +216,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/5',
'auctionSignals/5', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -233,7 +233,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/5',
'auctionSignals/5', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -250,7 +250,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -295,7 +295,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -312,7 +312,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -329,7 +329,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -347,7 +347,7 @@ subsetTest(promise_test, async test => {
await fetchDirectFromSellerSignals({ 'Buyer-Origin': window.location.origin });
await runReportTest(
test, uuid, codeToInsert,
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -366,7 +366,7 @@ subsetTest(promise_test, async test => {
await fetchDirectFromSellerSignals({ 'Buyer-Origin': window.location.origin }, OTHER_ORIGIN1);
await runReportTest(
test, uuid, codeToInsert,
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -386,7 +386,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid, '1', OTHER_ORIGIN1)],
// renderURLOverride
null,
@@ -406,7 +406,7 @@ subsetTest(promise_test, async test => {
test_instance, "${uuid}",
directFromSellerSignalsValidatorCode(
"${uuid}", 'sellerSignals/4', 'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL("${uuid}"), createBidderReportURL("${uuid}")],
// renderURLOverride
null,
@@ -425,7 +425,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
"${uuid}", 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL("${uuid}"), createBidderReportURL("${uuid}")],
// renderURLOverride
null,
@@ -447,7 +447,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
"${uuid}", 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL("${uuid}"), createBidderReportURL("${uuid}")],
// renderURLOverride
null,
@@ -467,7 +467,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals/4',
'auctionSignals/4', 'perBuyerSignals/4'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -484,7 +484,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sellerSignals',
'auctionSignals', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -511,7 +511,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'altSellerSignals/1',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -532,7 +532,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'altV2SellerSignals/1',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -551,7 +551,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, /*expectedSellerSignals=*/null,
'auctionSignals/2', /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -569,7 +569,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'firstSellerSignals/1',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -587,7 +587,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'nonDupSellerSignals/2',
/*expectedAuctionSignals=*/null, /*expectedPerBuyerSignals=*/null),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
@@ -606,7 +606,7 @@ subsetTest(promise_test, async test => {
directFromSellerSignalsValidatorCode(
uuid, 'sameSellerSignals',
'sameAuctionSignals', 'samePerBuyerSignals'),
- // expectedReportUrls
+ // expectedReportURLs
[createSellerReportURL(uuid), createBidderReportURL(uuid)],
// renderURLOverride
null,
diff --git a/tests/wpt/tests/fledge/tentative/generate-bid-browser-signals.https.window.js b/tests/wpt/tests/fledge/tentative/generate-bid-browser-signals.https.window.js
new file mode 100644
index 00000000000..3ab8bbf51f6
--- /dev/null
+++ b/tests/wpt/tests/fledge/tentative/generate-bid-browser-signals.https.window.js
@@ -0,0 +1,147 @@
+// META: script=/resources/testdriver.js
+// META: script=/common/utils.js
+// META: script=resources/fledge-util.sub.js
+// META: script=/common/subset-tests.js
+// META: timeout=long
+// META: variant=?1-last
+
+"use strict;"
+
+// These tests focus on the browserSignals argument passed to generateBid().
+// Note that "topLevelSeller" is covered by component auction tests,
+// "dataVersion" by trusted signals tests, and cross-origin
+// "topWindowHostname" and "seller" are covered by cross origin tests.
+//
+// Some of these tests use the "uuid" for interest group name, to avoid
+// joins/bids from previous tests that failed to clean up after themselves
+// from affecting results.
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ let expectedBrowserSignals = {
+ "topWindowHostname": window.location.hostname,
+ "seller": window.location.origin,
+ "adComponentsLimit": 40,
+ "joinCount": 1,
+ "bidCount": 0,
+ "prevWinsMs": []
+ }
+ let biddingLogicURL = createBiddingScriptURL(
+ { generateBid:
+ `let expectedBrowserSignals = ${JSON.stringify(expectedBrowserSignals)};
+
+ // Can't check this value exactly.
+ expectedBrowserSignals.recency = browserSignals.recency;
+
+ // This value may be affected by other recently run tests.
+ expectedBrowserSignals.forDebuggingOnlyInCooldownOrLockout =
+ browserSignals.forDebuggingOnlyInCooldownOrLockout;
+
+ // Remove deprecated field, if present.
+ delete browserSignals.prevWins;
+
+ if (!deepEquals(browserSignals, expectedBrowserSignals))
+ throw "Unexpected browserSignals: " + JSON.stringify(browserSignals);`
+ });
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: biddingLogicURL}});
+}, 'Only expected fields present.');
+
+// Creates a bidding script URL that expects the "joinCount" to be
+// "expectedJoinCount".
+function createJoinCountBiddingScriptURL(expectedJoinCount) {
+ return createBiddingScriptURL(
+ { generateBid:
+ `if (browserSignals.joinCount !== ${expectedJoinCount})
+ throw "Unexpected joinCount: " + browserSignals.joinCount;`
+ });
+}
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(1)}});
+
+ // Joining again, even with a different script URL, should increase the join count.
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(2)}});
+}, 'browserSignals.joinCount same joining page.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(1)}});
+
+ // Attempt to re-join the same interest group from a different top-level origin.
+ // The join count should still be persisted.
+ await joinCrossOriginInterestGroupInTopLevelWindow(
+ test, uuid, OTHER_ORIGIN1, window.location.origin,
+ { name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(2)});
+
+ await runBasicFledgeTestExpectingWinner(test, uuid);
+}, 'browserSignals.joinCount different top-level joining origin.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(1)}});
+
+ // Leaving interest group should clear join count.
+ await leaveInterestGroup({name: uuid});
+
+ // Check that join count was cleared.
+ await joinGroupAndRunBasicFledgeTestExpectingWinner(
+ test,
+ { uuid: uuid,
+ interestGroupOverrides: {name: uuid,
+ biddingLogicURL: createJoinCountBiddingScriptURL(1)}});
+}, 'browserSignals.joinCount leave and rejoin.');
+
+subsetTest(promise_test, async test => {
+ const uuid = generateUuid(test);
+ await runReportTest(
+ test, uuid,
+ { generateBid:
+ `if (browserSignals.recency === undefined)
+ throw new Error("Missing recency in browserSignals.")
+
+ if (browserSignals.recency < 0)
+ throw new Error("Recency is a negative value.")
+
+ if (browserSignals.recency > 30000)
+ throw new Error("Recency is over 30 seconds threshold.")
+
+ if (browserSignals.recency % 100 !== 0)
+ throw new Error("Recency is not rounded to multiple of 100 milliseconds.")
+
+ return {'bid': 9,
+ 'render': interestGroup.ads[0].renderURL};`,
+ reportWin:
+ `sendReportTo('${createBidderReportURL(uuid)}');`
+ },
+ // expectedReportURLs
+ [createBidderReportURL(uuid)]
+ );
+}, 'Check recency in generateBid() is below a certain threshold and rounded ' +
+ 'to multiple of 100 milliseconds.');
diff --git a/tests/wpt/tests/fledge/tentative/generate-bid-recency.https.window.js b/tests/wpt/tests/fledge/tentative/generate-bid-recency.https.window.js
deleted file mode 100644
index 07da463a2dc..00000000000
--- a/tests/wpt/tests/fledge/tentative/generate-bid-recency.https.window.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// META: script=/resources/testdriver.js
-// META: script=/common/utils.js
-// META: script=resources/fledge-util.sub.js
-// META: timeout=long
-
-"use strict;"
-
-promise_test(async test => {
- const uuid = generateUuid(test);
- await runReportTest(
- test, uuid,
- { generateBid:
- `if (browserSignals.recency === undefined)
- throw new Error("Missing recency in browserSignals.")
-
- if (browserSignals.recency < 0)
- throw new Error("Recency is a negative value.")
-
- if (browserSignals.recency > 30000)
- throw new Error("Recency is over 30 seconds threshold.")
-
- if (browserSignals.recency % 100 !== 0)
- throw new Error("Recency is not rounded to multiple of 100 milliseconds.")
-
- return {'bid': 9,
- 'render': interestGroup.ads[0].renderURL};`,
- reportWin:
- `sendReportTo('${createBidderReportURL(uuid)}');`
- },
- // expectedReportUrls
- [createBidderReportURL(uuid)]
- );
-}, 'Check recency in generateBid() is below a certain threshold and rounded ' +
- 'to multiple of 100 milliseconds.');
diff --git a/tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js b/tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js
index b5dfe025bf2..02148ef36b7 100644
--- a/tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/join-leave-ad-interest-group.https.window.js
@@ -231,31 +231,31 @@ const SIMPLE_JOIN_LEAVE_TEST_CASES = [
biddingWasmHelperURL: 'relative/path' }
},
- // "dailyUpdateUrl" tests
+ // "updateURL" tests
{ expectJoinSucces: true,
expectLeaveSucces: true,
interestGroup: { ...BASE_INTEREST_GROUP,
- dailyUpdateUrl: null }
+ updateURL: null }
},
{ expectJoinSucces: false,
expectLeaveSucces: true,
interestGroup: { ...BASE_INTEREST_GROUP,
- dailyUpdateUrl: 'https://{{hosts[][www]}}/foo.js' }
+ updateURL: 'https://{{hosts[][www]}}/foo.js' }
},
{ expectJoinSucces: false,
expectLeaveSucces: true,
interestGroup: { ...BASE_INTEREST_GROUP,
- dailyUpdateUrl: 'data:application/wasm,Foo' }
+ updateURL: 'data:application/wasm,Foo' }
},
{ expectJoinSucces: true,
expectLeaveSucces: true,
interestGroup: { ...BASE_INTEREST_GROUP,
- dailyUpdateUrl: `${window.location.origin}/foo.js`}
+ updateURL: `${window.location.origin}/foo.js`}
},
{ expectJoinSucces: true,
expectLeaveSucces: true,
interestGroup: { ...BASE_INTEREST_GROUP,
- dailyUpdateUrl: 'relative/path' }
+ updateURL: 'relative/path' }
},
// "executionMode" tests
diff --git a/tests/wpt/tests/fledge/tentative/kanon-status-below-threshold.https.window.js b/tests/wpt/tests/fledge/tentative/kanon-status-below-threshold.https.window.js
index 4eac4a8e917..787283d687f 100644
--- a/tests/wpt/tests/fledge/tentative/kanon-status-below-threshold.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/kanon-status-below-threshold.https.window.js
@@ -13,7 +13,7 @@ subsetTest(promise_test, async test => {
`browserSignals.kAnonStatus === "belowThreshold"`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]);
},
'Check kAnonStatus is "belowThreshold" when FledgeConsiderKAnonymity' +
diff --git a/tests/wpt/tests/fledge/tentative/kanon-status-not-calculated.https.window.js b/tests/wpt/tests/fledge/tentative/kanon-status-not-calculated.https.window.js
index a3ac19bd85e..4a750cd3529 100644
--- a/tests/wpt/tests/fledge/tentative/kanon-status-not-calculated.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/kanon-status-not-calculated.https.window.js
@@ -13,7 +13,7 @@ subsetTest(promise_test, async test => {
`browserSignals.kAnonStatus === "notCalculated"`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]);
},
'Check kAnonStatus is "notCalculated" when FledgeConsiderKAnonymity' +
diff --git a/tests/wpt/tests/fledge/tentative/register-ad-beacon.https.window.js b/tests/wpt/tests/fledge/tentative/register-ad-beacon.https.window.js
index 19fab2ac1b1..3643e446627 100644
--- a/tests/wpt/tests/fledge/tentative/register-ad-beacon.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/register-ad-beacon.https.window.js
@@ -17,9 +17,9 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon: '${createSellerBeaconURL(uuid)}'});`,
reportWin:
'' },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: `],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -39,9 +39,9 @@ subsetTest(promise_test, async test => {
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});`
},
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createBidderBeaconURL(uuid)}, body: `],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -60,9 +60,9 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon: '${createSellerBeaconURL(uuid)}'});`,
reportWin:
'' },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: body`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -81,9 +81,9 @@ subsetTest(promise_test, async test => {
'',
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createBidderBeaconURL(uuid)}, body: body`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -102,10 +102,10 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon: '${createSellerBeaconURL(uuid)}'});`,
reportWin:
'' },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: body1`,
`${createSellerBeaconURL(uuid)}, body: body2`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -129,10 +129,10 @@ subsetTest(promise_test, async test => {
'',
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createBidderBeaconURL(uuid)}, body: body1`,
`${createBidderBeaconURL(uuid)}, body: body2`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -157,10 +157,10 @@ subsetTest(promise_test, async test => {
beacon2: '${createSellerBeaconURL(uuid, '2')}'});`,
reportWin:
'' },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid, '1')}, body: body1`,
`${createSellerBeaconURL(uuid, '2')}, body: body2`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -186,10 +186,10 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon1: '${createBidderBeaconURL(uuid, '1')}',
beacon2: '${createBidderBeaconURL(uuid, '2')}'});`
},
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createBidderBeaconURL(uuid, '1')}, body: body1`,
`${createBidderBeaconURL(uuid, '2')}, body: body2`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -213,10 +213,10 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon: '${createSellerBeaconURL(uuid)}'});`,
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: body`,
`${createBidderBeaconURL(uuid)}, body: body`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -235,10 +235,10 @@ subsetTest(promise_test, async test => {
`registerAdBeacon({beacon: '${createSellerBeaconURL(uuid)}'});`,
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: body1`,
`${createBidderBeaconURL(uuid)}, body: body2`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -268,9 +268,9 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createBidderBeaconURL(uuid)}, body: body`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
@@ -293,9 +293,9 @@ subsetTest(promise_test, async test => {
`sendReportTo('${createBidderReportURL(uuid)}');
registerAdBeacon({beacon: '${createBidderBeaconURL(uuid)}'});
registerAdBeacon({beacon1: '${createBidderBeaconURL(uuid)}'});` },
- // expectedReportUrls:
+ // expectedReportURLs:
[`${createSellerBeaconURL(uuid)}, body: body`],
- // renderUrlOverride:
+ // renderURLOverride:
createRenderURL(
uuid,
`window.fence.reportEvent({
diff --git a/tests/wpt/tests/fledge/tentative/reporting-arguments.https.window.js b/tests/wpt/tests/fledge/tentative/reporting-arguments.https.window.js
index f26a969328f..c7c71202403 100644
--- a/tests/wpt/tests/fledge/tentative/reporting-arguments.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/reporting-arguments.https.window.js
@@ -46,7 +46,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === 45',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid), createBidderReportURL(uuid)]
);
}, 'Seller passes number to bidder.');
@@ -62,7 +62,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === "foo"',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid), createBidderReportURL(uuid)]
);
}, 'Seller passes string to bidder.');
@@ -78,7 +78,7 @@ subsetTest(promise_test, async test => {
'JSON.stringify(sellerSignals) === "[3,1,2]"',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid), createBidderReportURL(uuid)]
);
}, 'Seller passes array to bidder.');
@@ -94,7 +94,7 @@ subsetTest(promise_test, async test => {
`JSON.stringify(sellerSignals) === '{"a":4,"b":["c",null,{}]}'`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid), createBidderReportURL(uuid)]
);
}, 'Seller passes object to bidder.');
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 78d459e3f9d..3a23f981620 100644
--- a/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py
+++ b/tests/wpt/tests/fledge/tentative/resources/decision-logic.sub.py
@@ -43,8 +43,8 @@ def main(request, response):
// 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.
- if (!browserSignals.renderUrl.endsWith('uuid={{GET[uuid]}}') &&
- !browserSignals.renderUrl.includes('uuid={{GET[uuid]}}&')) {
+ if (!browserSignals.renderURL.endsWith('uuid={{GET[uuid]}}') &&
+ !browserSignals.renderURL.includes('uuid={{GET[uuid]}}&')) {
return 0;
}
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 69573d49983..4fc77933634 100644
--- a/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js
+++ b/tests/wpt/tests/fledge/tentative/resources/fledge-util.sub.js
@@ -148,6 +148,35 @@ async function waitForObservedRequests(uuid, expectedRequests) {
}
}
+
+// Similar to waitForObservedRequests, but ignore forDebuggingOnly reports.
+async function waitForObservedRequestsIgnoreDebugOnlyReports(
+ uuid, expectedRequests) {
+ // Sort array for easier comparison, as observed request order does not
+ // matter, and replace UUID to print consistent errors on failure.
+ expectedRequests =
+ expectedRequests.sort().map((url) => url.replace(uuid, '<uuid>'));
+
+ while (true) {
+ let numTrackedRequest = 0;
+ let trackedData = await fetchTrackedData(uuid);
+
+ // Clean up "trackedRequests" in same manner as "expectedRequests".
+ let trackedRequests = trackedData.trackedRequests.sort().map(
+ (url) => url.replace(uuid, '<uuid>'));
+
+ for (const trackedRequest of trackedRequests) {
+ // Ignore forDebuggingOnly reports, since their appearance is random.
+ if (!trackedRequest.includes('forDebuggingOnly')) {
+ assert_in_array(trackedRequest, expectedRequests);
+ numTrackedRequest++;
+ }
+ }
+
+ if (numTrackedRequest == expectedRequests.length) break;
+ }
+}
+
// Creates a bidding script with the provided code in the method bodies. The
// bidding script's generateBid() method will return a bid of 9 for the first
// ad, after the passed in code in the "generateBid" input argument has been
@@ -504,7 +533,7 @@ async function runInFrame(test, child_window, script, param) {
// iframe or closes the window.
async function createFrame(test, origin, is_iframe = true, permissions = null) {
const frameUuid = generateUuid(test);
- const frameUrl =
+ const frameURL =
`${origin}${RESOURCE_PATH}subordinate-frame.sub.html?uuid=${frameUuid}`;
let promise = new Promise(function(resolve, reject) {
function WaitForMessage(event) {
@@ -523,7 +552,7 @@ async function createFrame(test, origin, is_iframe = true, permissions = null) {
let iframe = document.createElement('iframe');
if (permissions)
iframe.allow = permissions;
- iframe.src = frameUrl;
+ iframe.src = frameURL;
document.body.appendChild(iframe);
test.add_cleanup(async () => {
@@ -535,7 +564,7 @@ async function createFrame(test, origin, is_iframe = true, permissions = null) {
return iframe.contentWindow;
}
- let child_window = window.open(frameUrl);
+ let child_window = window.open(frameURL);
test.add_cleanup(async () => {
await runInFrame(test, child_window, "await test_instance.do_cleanup();");
child_window.close();
@@ -576,11 +605,23 @@ async function joinInterestGroupInTopLevelWindow(
let interestGroup = JSON.stringify(
createInterestGroupForOrigin(uuid, origin, interestGroupOverrides));
- let topLeveWindow = await createTopLevelWindow(test, origin);
- await runInFrame(test, topLeveWindow,
+ let topLevelWindow = await createTopLevelWindow(test, origin);
+ await runInFrame(test, topLevelWindow,
`await joinInterestGroup(test_instance, "${uuid}", ${interestGroup})`);
}
+// Opens a top-level window and calls joinCrossOriginInterestGroup() in it.
+async function joinCrossOriginInterestGroupInTopLevelWindow(
+ test, uuid, windowOrigin, interestGroupOrigin, interestGroupOverrides = {}) {
+ let interestGroup = JSON.stringify(
+ createInterestGroupForOrigin(uuid, interestGroupOrigin, interestGroupOverrides));
+
+ let topLevelWindow = await createTopLevelWindow(test, windowOrigin);
+ await runInFrame(test, topLevelWindow,
+ `await joinCrossOriginInterestGroup(
+ test_instance, "${uuid}", "${interestGroupOrigin}", ${interestGroup})`);
+}
+
// Fetch directFromSellerSignals from seller and check header
// 'Ad-Auction-Signals' is hidden from documents.
async function fetchDirectFromSellerSignals(headers_content, origin) {
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 80488a5d6af..eccef5e7628 100644
--- a/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py
+++ b/tests/wpt/tests/fledge/tentative/resources/trusted-scoring-signals.py
@@ -15,7 +15,7 @@ def main(request, response):
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
+ # 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 = []
@@ -36,7 +36,7 @@ def main(request, response):
continue
if pair[0] == "renderUrls" and renderUrls == None:
renderUrls = list(map(unquote_plus, pair[1].split(",")))
- urlLists.append({"type":"renderUrls", "urls":renderUrls})
+ urlLists.append({"type":"renderURLs", "urls":renderUrls})
continue
if pair[0] == "adComponentRenderUrls" and adComponentRenderURLs == None:
adComponentRenderURLs = list(map(unquote_plus, pair[1].split(",")))
diff --git a/tests/wpt/tests/fledge/tentative/round-a-value.https.window.js b/tests/wpt/tests/fledge/tentative/round-a-value.https.window.js
index 5bccd4ab078..90523e2256c 100644
--- a/tests/wpt/tests/fledge/tentative/round-a-value.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/round-a-value.https.window.js
@@ -18,7 +18,7 @@ promise_test(async test => {
`browserSignals.adCost === 1.9921875 || browserSignals.adCost === 1.984375`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Check adCost is stochastically rounded with 8 bit mantissa and exponent.');
@@ -35,7 +35,7 @@ promise_test(async test => {
`browserSignals.bid === 1.9921875 || browserSignals.bid === 1.984375`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Check bid is stochastically rounded with 8 bit mantissa and exponent.');
@@ -52,7 +52,7 @@ promise_test(async test => {
`browserSignals.desirability === 1.9921875 || browserSignals.desirability === 1.984375`,
reportResult:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Check desirability is stochastically rounded with 8 bit mantissa and exponent.');
@@ -70,7 +70,7 @@ promise_test(async test => {
`browserSignals.highestScoringOtherBid === 1.9921875 || browserSignals.highestScoringOtherBid === 1.984375`,
reportResult:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Check highestScoringOtherBid is stochastically rounded with 8 bit mantissa and exponent.');
@@ -87,7 +87,7 @@ promise_test(async test => {
`browserSignals.adCost === 2`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Value is ignored as a non-valid floating-point number.');
@@ -104,7 +104,7 @@ promise_test(async test => {
`browserSignals.adCost === 0`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Value is rounded to 0 if value is greater than 0 and its exponent is less than -128.');
@@ -121,7 +121,7 @@ promise_test(async test => {
`browserSignals.adCost === -0`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Value is rounded to -0 if value is greater than 0 and its exponent is less than -128.');
@@ -138,7 +138,7 @@ promise_test(async test => {
`browserSignals.adCost === Infinity`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Value is rounded to Infinity if value is greater than 0 and its exponent is greater than 127.');
@@ -155,7 +155,7 @@ promise_test(async test => {
`browserSignals.adCost === -Infinity`,
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls
+ // expectedReportURLs
[createBidderReportURL(uuid)]
);
}, 'Value is rounded to -Infinity if value is less than 0 and its exponent is greater than 127.');
diff --git a/tests/wpt/tests/fledge/tentative/send-report-to.https.window.js b/tests/wpt/tests/fledge/tentative/send-report-to.https.window.js
index 65a25204206..e3cf0a95f17 100644
--- a/tests/wpt/tests/fledge/tentative/send-report-to.https.window.js
+++ b/tests/wpt/tests/fledge/tentative/send-report-to.https.window.js
@@ -18,7 +18,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid), createBidderReportURL(uuid)]
);
}, 'Both send reports, seller passes nothing to bidder.');
@@ -31,7 +31,7 @@ subsetTest(promise_test, async test => {
`sendReportTo('${createSellerReportURL(uuid)}');`,
reportWin:
'' },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid)]
);
}, 'Only seller sends a report');
@@ -44,7 +44,7 @@ subsetTest(promise_test, async test => {
`sendReportTo('${createSellerReportURL(uuid)}');`,
reportWin:
'throw new Error("Very serious exception")' },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid)]
);
}, 'Only seller sends a report, bidder throws an exception');
@@ -55,7 +55,7 @@ subsetTest(promise_test, async test => {
test, uuid,
{ reportResult:
`sendReportTo('${createSellerReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid)]
);
}, 'Only seller sends a report, bidder has no reportWin() method');
@@ -70,7 +70,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]
);
}, 'Only bidder sends a report');
@@ -85,7 +85,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === "foo"',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]
);
}, 'Only bidder sends a report, seller passes a message to bidder');
@@ -100,7 +100,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]
);
}, 'Only bidder sends a report, seller throws an exception');
@@ -113,7 +113,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]
);
}, 'Only bidder sends a report, seller has no reportResult() method');
@@ -130,7 +130,7 @@ subsetTest(promise_test, async test => {
'sellerSignals === null',
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createBidderReportURL(uuid)]
);
}, 'Seller calls sendReportTo() twice, which throws an exception.');
@@ -144,7 +144,7 @@ subsetTest(promise_test, async test => {
reportWin:
`sendReportTo('${createBidderReportURL(uuid)}');
sendReportTo('${createBidderReportURL(uuid)}');` },
- // expectedReportUrls:
+ // expectedReportURLs:
[createSellerReportURL(uuid)]
);
// Seller reports may be sent before bidder reports, since reportWin()
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 67ae3577e4f..4de5cfc0f39 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
@@ -82,7 +82,7 @@ async function runTrustedScoringSignalsDataVersionTest(
// Creates a render URL that, when sent to the trusted-scoring-signals.py,
// results in a trusted scoring signals response with the provided response
// body.
-function createScoringSignalsRenderUrlWithBody(uuid, responseBody) {
+function createScoringSignalsRenderURLWithBody(uuid, responseBody) {
return createRenderURL(uuid, /*script=*/null,
/*signalsParam=*/`replace-body:${responseBody}`);
}
@@ -93,13 +93,13 @@ function createScoringSignalsRenderUrlWithBody(uuid, responseBody) {
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const decisionLogicScriptUrl = createDecisionScriptURL(
+ const decisionLogicScriptURL = createDecisionScriptURL(
uuid,
{ scoreAd: 'if (trustedScoringSignals !== null) throw "error";' });
await joinGroupAndRunBasicFledgeTestExpectingWinner(
test,
{ uuid: uuid,
- auctionConfigOverrides: { decisionLogicURL: decisionLogicScriptUrl }
+ auctionConfigOverrides: { decisionLogicURL: decisionLogicScriptURL }
});
}, 'No trustedScoringSignalsURL.');
@@ -149,35 +149,35 @@ subsetTest(promise_test, async test => {
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'');
await runTrustedScoringSignalsTest(test, uuid, renderURL, 'trustedScoringSignals === null');
}, 'Trusted scoring signals response has no body.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'Not JSON');
await runTrustedScoringSignalsTest(test, uuid, renderURL, 'trustedScoringSignals === null');
}, 'Trusted scoring signals response is not JSON.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'[]');
await runTrustedScoringSignalsTest(test, uuid, renderURL, 'trustedScoringSignals === null');
}, 'Trusted scoring signals response is a JSON array.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'{JSON_keys_need_quotes: 1}');
await runTrustedScoringSignalsTest(test, uuid, renderURL, 'trustedScoringSignals === null');
}, 'Trusted scoring signals response is invalid JSON object.');
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'{}');
await runTrustedScoringSignalsTest(
test, uuid, renderURL,
@@ -444,7 +444,7 @@ subsetTest(promise_test, async test => {
const renderURL = createRenderURL(uuid, /*script=*/null, /*signalsParam=*/'num-value');
// This should not be sent. If it is, it will take precedence over the "num-value" parameter
// from "renderURL", resulting in the "renderURL" having a null "trustedScoringSignals" value.
- const componentURL = createScoringSignalsRenderUrlWithBody(
+ const componentURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'{}');
await runTrustedScoringSignalsTest(
test, uuid, renderURL,
@@ -456,7 +456,7 @@ subsetTest(promise_test, async test => {
subsetTest(promise_test, async test => {
const uuid = generateUuid(test);
- const renderURL = createScoringSignalsRenderUrlWithBody(
+ const renderURL = createScoringSignalsRenderURLWithBody(
uuid, /*responseBody=*/'{}');
const componentURL = createRenderURL(uuid, /*script=*/null);
await runTrustedScoringSignalsTest(
diff --git a/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html b/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html
new file mode 100644
index 00000000000..26f6e752149
--- /dev/null
+++ b/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage-expected.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.drawImage</title>
+<h1>2d.layer.drawImage</h1>
+<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // Should xor only with the layer content, not the parents'.
+ ctx.fillStyle = 'pink';
+ ctx.fillRect(40, 40, 50, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage.html b/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage.html
new file mode 100644
index 00000000000..58206c3eb87
--- /dev/null
+++ b/tests/wpt/tests/html/canvas/element/layers/2d.layer.drawImage.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.drawImage-expected.html">
+<title>Canvas test: 2d.layer.drawImage</title>
+<h1>2d.layer.drawImage</h1>
+<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // The image should xor only with the layer content, not the parents'.
+ const canvas_image = new OffscreenCanvas(200,200);
+ const ctx_image = canvas_image.getContext("2d");
+ ctx_image.fillStyle = 'pink';
+ ctx_image.fillRect(40, 40, 50, 50);
+ ctx.drawImage(canvas_image, 0, 0);
+
+ ctx.endLayer();
+</script>
diff --git a/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html
new file mode 100644
index 00000000000..26f6e752149
--- /dev/null
+++ b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage-expected.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<title>Canvas test: 2d.layer.drawImage</title>
+<h1>2d.layer.drawImage</h1>
+<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = document.getElementById("canvas");
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // Should xor only with the layer content, not the parents'.
+ ctx.fillStyle = 'pink';
+ ctx.fillRect(40, 40, 50, 50);
+
+ ctx.endLayer();
+</script>
diff --git a/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html
new file mode 100644
index 00000000000..37718f6f2c5
--- /dev/null
+++ b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<link rel="match" href="2d.layer.drawImage-expected.html">
+<title>Canvas test: 2d.layer.drawImage</title>
+<h1>2d.layer.drawImage</h1>
+<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script>
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // The image should xor only with the layer content, not the parents'.
+ const canvas_image = new OffscreenCanvas(200,200);
+ const ctx_image = canvas_image.getContext("2d");
+ ctx_image.fillStyle = 'pink';
+ ctx_image.fillRect(40, 40, 50, 50);
+ ctx.drawImage(canvas_image, 0, 0);
+
+ ctx.endLayer();
+
+ const outputCanvas = document.getElementById("canvas");
+ outputCanvas.getContext('2d').drawImage(canvas, 0, 0);
+</script>
diff --git a/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html
new file mode 100644
index 00000000000..78a235597d5
--- /dev/null
+++ b/tests/wpt/tests/html/canvas/offscreen/layers/2d.layer.drawImage.w.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
+<html class="reftest-wait">
+<link rel="match" href="2d.layer.drawImage-expected.html">
+<title>Canvas test: 2d.layer.drawImage</title>
+<h1>2d.layer.drawImage</h1>
+<p class="desc">Checks that drawImage writes the image to the layer and not the parent directly.</p>
+<canvas id="canvas" width="200" height="200">
+ <p class="fallback">FAIL (fallback content)</p>
+</canvas>
+<script id='myWorker' type='text/worker'>
+ self.onmessage = function(e) {
+ const canvas = new OffscreenCanvas(200, 200);
+ const ctx = canvas.getContext('2d');
+
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // The image should xor only with the layer content, not the parents'.
+ const canvas_image = new OffscreenCanvas(200,200);
+ const ctx_image = canvas_image.getContext("2d");
+ ctx_image.fillStyle = 'pink';
+ ctx_image.fillRect(40, 40, 50, 50);
+ ctx.drawImage(canvas_image, 0, 0);
+
+ ctx.endLayer();
+
+ const bitmap = canvas.transferToImageBitmap();
+ self.postMessage(bitmap, bitmap);
+ };
+</script>
+<script>
+ const blob = new Blob([document.getElementById('myWorker').textContent]);
+ const worker = new Worker(URL.createObjectURL(blob));
+ worker.addEventListener('message', msg => {
+ const outputCtx = document.getElementById("canvas").getContext('2d');
+ outputCtx.drawImage(msg.data, 0, 0);
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ worker.postMessage(null);
+</script>
+</html>
diff --git a/tests/wpt/tests/html/canvas/tools/yaml-new/layers.yaml b/tests/wpt/tests/html/canvas/tools/yaml-new/layers.yaml
index a44cb2ea2c1..dfef55d081b 100644
--- a/tests/wpt/tests/html/canvas/tools/yaml-new/layers.yaml
+++ b/tests/wpt/tests/html/canvas/tools/yaml-new/layers.yaml
@@ -627,6 +627,49 @@
ctx.fillStyle = 'blue';
ctx.fillRect(10, 10, 80, 50);
+- name: 2d.layer.drawImage
+ size: [200, 200]
+ desc: >-
+ Checks that drawImage writes the image to the layer and not the parent
+ directly.
+ code: |
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // The image should xor only with the layer content, not the parents'.
+ const canvas_image = new OffscreenCanvas(200,200);
+ const ctx_image = canvas_image.getContext("2d");
+ ctx_image.fillStyle = 'pink';
+ ctx_image.fillRect(40, 40, 50, 50);
+ ctx.drawImage(canvas_image, 0, 0);
+
+ ctx.endLayer();
+ reference: |
+ ctx.fillStyle = 'skyblue';
+ ctx.fillRect(0, 0, 100, 100);
+
+ ctx.beginLayer({filter: {name: 'dropShadow', dx: -10, dy: -10,
+ stdDeviation: 0, floodColor: 'navy'}});
+
+ ctx.fillStyle = 'maroon';
+ ctx.fillRect(20, 20, 50, 50);
+
+ ctx.globalCompositeOperation = 'xor';
+
+ // Should xor only with the layer content, not the parents'.
+ ctx.fillStyle = 'pink';
+ ctx.fillRect(40, 40, 50, 50);
+
+ ctx.endLayer();
+
- name: 2d.layer.valid-calls
desc: No exception raised on {{ variant_desc }}.
variants:
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir-assorted.window.js b/tests/wpt/tests/html/dom/elements/global-attributes/dir-assorted.window.js
index 0d4e4b82d9b..2017269f0bd 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/dir-assorted.window.js
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir-assorted.window.js
@@ -90,10 +90,11 @@ for (const bdi_test of [
{ markup: "<bdi dir=rtl></bdi>", expected: "rtl", desc: "dir=rtl empty" },
{ markup: "<bdi dir=auto>A</bdi>", expected: "ltr", desc: "dir=auto with LTR contents" },
{ markup: "<bdi dir=auto>\u05d0</bdi>", expected: "rtl", desc: "dir=auto with RTL contents" },
- { markup: "<bdi dir=auto></bdi>", expected: "parent", desc: "dir=auto empty" },
+ { markup: "<bdi dir=auto></bdi>", expected: "ltr", desc: "dir=auto empty" },
+ { markup: "<bdi dir=auto>123</bdi>", expected: "ltr", desc: "dir=auto numbers" },
{ markup: "<bdi>A</bdi>", expected: "ltr", desc: "no dir attribute with LTR contents" },
{ markup: "<bdi>\u05d0</bdi>", expected: "rtl", desc: "no dir attribute with RTL contents" },
- { markup: "<bdi></bdi>", expected: "parent", desc: "no dir attribute empty" },
+ { markup: "<bdi></bdi>", expected: "ltr", desc: "no dir attribute empty" },
]) {
for (const parent_dir of [ "ltr", "rtl" ]) {
test(() => {
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html
index b52e08df20e..79b844edbe5 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html
@@ -18,7 +18,7 @@ span {border: 1px solid silver;}
<p>`dir=rtl` on a div in the shadow tree, `dir=ltr` on the shadow host, no slotted text in the light or dark trees</p>
<div id="host" dir="ltr"><div dir="rtl"><span></span></div></div>
-<p id="result">The HTML direction / computed CSS `direction` value is: rtl / rtl (on the slot).</p>
+<p id="result">The HTML direction / computed CSS `direction` value is: ltr / ltr (on the slot).</p>
</body>
</html>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html
new file mode 100644
index 00000000000..8ea11002460
--- /dev/null
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="author" title="L. David Baron" href="mailto:dbaron@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+#host {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on a div in the shadow tree, `dir=rtl` on the shadow host, no slotted text in the light or dark trees</p>
+<div id="host" dir="rtl"><div dir="ltr"><span></span></div></div>
+<p id="result">The HTML direction / computed CSS `direction` value is: ltr / ltr (on the slot).</p>
+
+</body>
+</html>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42.html b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42.html
new file mode 100644
index 00000000000..b9697678cbc
--- /dev/null
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir-shadow-42.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="author" title="L. David Baron" href="mailto:dbaron@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-42-ref.html">
+<style type="text/css">
+body {width: 600px;}
+#host {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on a div in the shadow tree, `dir=rtl` on the shadow host, no slotted text in the light or dark trees</p>
+<div id="host" dir="rtl"><span slot="x1"></span></div>
+<p id="result">The HTML direction / computed CSS `direction` value is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<div dir="ltr"><slot dir="auto" name="x1"></slot></div>`;
+ result.innerHTML += html_direction(root.querySelector("div[dir=ltr]").firstChild) + " / " + getComputedStyle(root.querySelector("div[dir=ltr]").firstChild).direction + " (on the " + root.querySelector("div[dir=ltr]").firstChild.localName + ').';
+</script>
+
+</body>
+</html>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html b/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html
index 0d938b2e168..496d699d73c 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html
@@ -10,7 +10,7 @@
<meta name="assert" content="
When dir='auto', the direction is set according to the first strong character
of the text, ignoring neutrals and numbers.
- If there is no strong character, as in this test, the direction defaults to the parent." />
+ If there is no strong character, as in this test, the direction defaults to LTR." />
<style>
input, textarea {
font-size:1em;
@@ -35,7 +35,7 @@
<p dir="ltr">@123!</p>
</div>
<div dir="rtl">
- <p dir="rtl">@123!</p>
+ <p dir="ltr">@123!</p>
</div>
</div>
<div class="ref">
@@ -43,7 +43,7 @@
<p dir="ltr">@123!</p>
</div>
<div dir="rtl">
- <p dir="rtl">@123!</p>
+ <p dir="ltr">@123!</p>
</div>
</div>
</body>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html b/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html
index 467b4d09394..5d948d34568 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html
@@ -11,7 +11,7 @@
<meta name="assert" content="
When dir='auto', the direction is set according to the first strong character
of the text, ignoring neutrals and numbers.
- If there is no strong character, as in this test, the direction defaults to the parent." />
+ If there is no strong character, as in this test, the direction defaults to LTR." />
<style>
input, textarea {
font-size:1em;
@@ -44,7 +44,7 @@
<p dir="ltr">@123!</p>
</div>
<div dir="rtl">
- <p dir="rtl">@123!</p>
+ <p dir="ltr">@123!</p>
</div>
</div>
</body>
diff --git a/tests/wpt/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html b/tests/wpt/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html
index fe4657aabb3..ec2d8d5ead9 100644
--- a/tests/wpt/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html
+++ b/tests/wpt/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html
@@ -35,7 +35,10 @@ body {
}
dialog::backdrop {
- inset: calc(anchor(auto-same) - 10px);
+ top: calc(anchor(top) - 10px);
+ right: calc(anchor(right) - 10px);
+ bottom: calc(anchor(bottom) - 10px);
+ left: calc(anchor(left) - 10px);
background: lime;
}
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html
index 9624b41a194..36567f9d54a 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html
@@ -18,11 +18,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html
index ab0fd511156..3c907597f7a 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html
@@ -19,19 +19,19 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html
index eb3a347a6eb..2858798a35f 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html
@@ -23,11 +23,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html
index 2c50f2d362a..f45f5587204 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html
index 04cdab467de..098a3c57676 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html
index 1c9da255a62..223e42109e5 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html
index df8f9ae3d12..9aa0aeea798 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html
@@ -18,11 +18,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html
index c2458a0bab3..e671dda19c4 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html
index d765ac8a5d3..8498816ea5c 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html
index 7ef6a1baf35..ef6f709012e 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html
index 31df9b068c0..dee82d8c595 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html
index 8f2594d2590..4110e54c5f2 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html
index 9d65bd96b73..ecd97be86a6 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html
@@ -20,11 +20,11 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html
index d042b96b643..ea8948de42d 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html
@@ -26,11 +26,11 @@ document.head.appendChild(link);
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html
index f7ac0b1015d..a775ee41740 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html
@@ -22,11 +22,11 @@ link.remove();
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html
index d32a0468e79..8968c5dacd3 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html
@@ -22,11 +22,11 @@ link.blocking = "";
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html
index d3a6046cbb3..2d3b5747216 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html
@@ -21,11 +21,11 @@ link.blocking = "render"
</script>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html
index 0d7402201ac..76e6394b5b1 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html
@@ -22,11 +22,11 @@ link.media = "(min-width: 10px)";
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html
index fea9e3a2b21..80a7019edc4 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html
@@ -22,11 +22,11 @@ link.media = "(max-width: 10px)";
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html
index 7fc0fe19bba..10019c943f4 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html
@@ -21,11 +21,11 @@ link.rel = "stylesheet";
</script>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html
index 29430349f04..1ca2114689a 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html
@@ -21,15 +21,15 @@ link.rel = "expect";
</script>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html
index 6548c9ec4df..5dfbcac30a4 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html
@@ -22,11 +22,11 @@ link.href = "#last";
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html
index c3661bcaa6a..8fe8b6a8c8e 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html
@@ -21,11 +21,11 @@ link.href = "";
</script>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html
index c98022cfeab..19e4020fb76 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html
@@ -18,19 +18,19 @@ async_test((t) => {
<body>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html
index 29868b92cbc..689ae69f452 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html
@@ -20,19 +20,19 @@ async_test((t) => {
<div id="willbefirst"></div>
<script>
willbefirst.id = "first";
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html
index dc23211b8b0..6abfc43b8b2 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html
@@ -20,19 +20,19 @@ async_test((t) => {
<div id="first"></div>
<script>
first.id = "wasfirst";
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html
index 5b8a5eb24d5..56f88e0fc2b 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html
@@ -20,19 +20,19 @@ async_test((t) => {
<body>
<div id="notfirst"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html
index 57ba3d60260..a64d542c4ac 100644
--- a/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html
+++ b/tests/wpt/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html
@@ -30,19 +30,19 @@ four.remove();
</script>
<div id="first"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="second"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="third"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="fourth"></div>
<script>
- jankMany(100, 10);
+ generateParserDelay();
</script>
<div id="last"></div>
</body>
diff --git a/tests/wpt/tests/html/dom/render-blocking/support/utils.js b/tests/wpt/tests/html/dom/render-blocking/support/utils.js
index 9a890ab685c..8a9a537e96d 100644
--- a/tests/wpt/tests/html/dom/render-blocking/support/utils.js
+++ b/tests/wpt/tests/html/dom/render-blocking/support/utils.js
@@ -1,10 +1,5 @@
-function jank(ms) {
- let start = performance.now();
- while (performance.now() < start + ms);
-}
-
-function jankMany(ms, times) {
- for (let i = 0; i < times; i++) {
- jank(ms);
- }
+function generateParserDelay(seconds = 1) {
+ document.write(`
+ <script src="/loading/resources/dummy.js?pipe=trickle(d${seconds})"></script>
+ `);
}
diff --git a/tests/wpt/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html b/tests/wpt/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html
new file mode 100644
index 00000000000..664659d90ab
--- /dev/null
+++ b/tests/wpt/tests/html/editing/editing-0/writing-suggestions/writingsuggestions.html
@@ -0,0 +1,599 @@
+<!DOCTYPE html>
+<title>Tests for the writingsuggestions attribute</title>
+<link rel='author' title='Sanket Joshi' href='mailto:sajos@microsoft.com'>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#writingsuggestions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+'use strict';
+
+customElements.define('test-custom-element', class extends HTMLElement {});
+
+test(function() {
+ assert_true('writingSuggestions' in document.createElement('input'));
+}, 'Test that the writingsuggestions attribute is available on HTMLInputElement.');
+
+test(function() {
+ assert_true('writingSuggestions' in document.createElement('textarea'));
+}, 'Test that the writingsuggestions attribute is available on HTMLTextAreaElement.');
+
+test(function() {
+ assert_true('writingSuggestions' in document.createElement('div'));
+}, 'Test that the writingsuggestions attribute is available on HTMLDivElement.');
+
+test(function() {
+ assert_true('writingSuggestions' in document.createElement('span'));
+}, 'Test that the writingsuggestions attribute is available on HTMLSpanElement.');
+
+test(function() {
+ assert_true('writingSuggestions' in document.createElement('test-custom-element'));
+}, 'Test that the writingsuggestions attribute is available on custom elements.');
+
+test(function() {
+ let input = document.createElement('input');
+ input.type = 'color';
+ assert_true('writingSuggestions' in input);
+}, 'Test that the writingsuggestions attribute is available on an input type which the attribute doesn\'t apply. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ let textarea = document.createElement('textarea');
+ textarea.disabled = true;
+ assert_true('writingSuggestions' in textarea);
+}, 'Test that the writingsuggestions attribute is available on a disabled element. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+function testSetAttributeDirectly(IDLValue, contentValue, expectedIDLValue, expectedContentValue, testDescription) {
+ test(function() {
+ let input_color = document.createElement('input');
+ input_color.type = 'color';
+
+ let disabled_textarea = document.createElement('textarea');
+ disabled_textarea.disabled = true;
+
+ const elements = [document.createElement('input'),
+ document.createElement('textarea'),
+ document.createElement('div'),
+ document.createElement('span'),
+ document.createElement('test-custom-element'),
+ disabled_textarea,
+ input_color ];
+
+ elements.forEach(function(element) {
+ if (IDLValue != undefined) {
+ element.writingSuggestions = IDLValue;
+ }
+ if (contentValue != undefined) {
+ element.setAttribute('writingsuggestions', contentValue);
+ }
+ assert_equals(element.writingSuggestions, expectedIDLValue);
+ assert_equals(element.getAttribute('writingsuggestions'), expectedContentValue);
+ });
+ }, testDescription);
+}
+
+// Test setting either the `writingsuggestions` IDL or content attribute to some variation of 'true' directly on the target element.
+testSetAttributeDirectly('true', undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to `true` directly on the target element.');
+testSetAttributeDirectly(undefined, 'true', 'true', 'true', 'Test setting the `writingsuggestions` content attribute to `true` directly on the target element.');
+testSetAttributeDirectly(true, undefined, 'true', 'true', 'Test setting the `writingsuggestions` IDL attribute to boolean `true` directly on the target element.');
+testSetAttributeDirectly(undefined, true, 'true', 'true', 'Test setting the `writingsuggestions` content attribute to boolean `true` directly on the target element.');
+testSetAttributeDirectly('TrUe', undefined, 'true', 'TrUe', 'Test setting the `writingsuggestions` IDL attribute to `TrUe` directly on the target element.');
+testSetAttributeDirectly(undefined, 'TrUe', 'true', 'TrUe', 'Test setting the `writingsuggestions` content attribute to `TrUe` directly on the target element.');
+
+// Test setting either the `writingsuggestions` IDL or content attribute to some variation of 'false' directly on the target element.
+testSetAttributeDirectly('false', undefined, 'false', 'false', 'Test setting the `writingsuggestions` IDL attribute to `false` directly on the target element.');
+testSetAttributeDirectly(undefined, 'false', 'false', 'false', 'Test setting the `writingsuggestions` content attribute to `false` directly on the target element.');
+testSetAttributeDirectly(false, undefined, 'false', 'false', 'Test setting the `writingsuggestions` IDL attribute to boolean `false` directly on the target element.');
+testSetAttributeDirectly(undefined, false, 'false', 'false', 'Test setting the `writingsuggestions` content attribute to boolean `false` directly on the target element.');
+testSetAttributeDirectly('FaLsE', undefined, 'false', 'FaLsE', 'Test setting the `writingsuggestions` IDL attribute to `FaLsE` directly on the target element.');
+testSetAttributeDirectly(undefined, 'FaLsE', 'false', 'FaLsE', 'Test setting the `writingsuggestions` content attribute to `FaLsE` directly on the target element.');
+
+// Test setting either the `writingsuggestions` IDL or content attribute to the empty string directly on the target element.
+testSetAttributeDirectly('', undefined, 'true', '', 'Test setting the `writingsuggestions` IDL attribute to the empty string directly on the target element.');
+testSetAttributeDirectly(undefined, '', 'true', '', 'Test setting the `writingsuggestions` content attribute to the empty string directly on the target element.');
+
+// Test setting either the `writingsuggestions` IDL or content attribute to an invalid value directly on the target element.
+testSetAttributeDirectly('foo', undefined, 'true', 'foo', 'Test setting the `writingsuggestions` IDL attribute to an invalid value directly on the target element.');
+testSetAttributeDirectly(undefined, 'foo', 'true', 'foo', 'Test setting the `writingsuggestions` content attribute to an invalid value directly on the target element.');
+
+// Test setting neither the `writingsuggestions` IDL nor content attribute directly on the target element.
+testSetAttributeDirectly(undefined, undefined, 'true', null, 'Test the writing suggestions state when the `writingsuggestions` attribute is missing.');
+
+// Test setting the content attribute after the IDL attribute and making sure the IDL and content attributes are properly reflected.
+testSetAttributeDirectly('true', 'false', 'false', 'false', 'Test setting the `writingsuggestions` content attribute to `false` after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', '', 'true', '', 'Test setting the `writingsuggestions` content attribute to the empty string after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', 'foo', 'true', 'foo', 'Test setting the `writingsuggestions` content attribute to an invalid value after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', 'TrUe', 'true', 'TrUe', 'Test setting the `writingsuggestions` content attribute to `TrUe` after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', 'FaLsE', 'false', 'FaLsE', 'Test setting the `writingsuggestions` content attribute to `FaLsE` after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', true, 'true', 'true', 'Test setting the `writingsuggestions` content attribute to boolean `true` after the IDL attribute was set to `true`.');
+testSetAttributeDirectly('true', false, 'false', 'false', 'Test setting the `writingsuggestions` content attribute to boolean `false` after the IDL attribute was set to `true`.');
+
+testSetAttributeDirectly('false', 'true', 'true', 'true', 'Test setting the `writingsuggestions` content attribute to `true` after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', '', 'true', '', 'Test setting the `writingsuggestions` content attribute to the empty string after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', 'foo', 'true', 'foo', 'Test setting the `writingsuggestions` content attribute to an invalid value after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', 'TrUe', 'true', 'TrUe', 'Test setting the `writingsuggestions` content attribute to `TrUe` after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', 'FaLsE', 'false', 'FaLsE', 'Test setting the `writingsuggestions` content attribute to `FaLsE` after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', true, 'true', 'true', 'Test setting the `writingsuggestions` content attribute to boolean `true` after the IDL attribute was set to `false`.');
+testSetAttributeDirectly('false', false, 'false', 'false', 'Test setting the `writingsuggestions` content attribute to boolean `false` after the IDL attribute was set to `false`.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<input writingsuggestions />', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<textarea writingsuggestions></textarea>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<div writingsuggestions></div>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<span writingsuggestions></span>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<input type="color" writingsuggestions />', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<textarea disabled writingsuggestions></textarea>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), '');
+ });
+}, 'Test setting the `writingsuggestions` attribute with a missing value directly on the target element.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><div></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><span></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input type="color"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'true');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'true');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), null);
+ });
+}, 'Test setting the `writingsuggestions` attribute to "true" on a parent element.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions=""><input /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><div></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><span></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><input type="color"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'true');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), '');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), null);
+ });
+}, 'Test setting the `writingsuggestions` attribute to an empty string on a parent element.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><div></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><span></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'false');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'false');
+ assert_equals(element.writingSuggestions, 'false');
+ assert_equals(element.getAttribute('writingsuggestions'), null);
+ });
+}, 'Test setting the `writingsuggestions` attribute to "false" on a parent element.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><input /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><textarea></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><div></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><span></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><input type="color"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="foo"><textarea disabled></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'true');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'foo');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), null);
+ });
+}, 'Test setting the `writingsuggestions` attribute to an invalid value on a parent element.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><div writingsuggestions="false"></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><input type="color" writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="true"><textarea disabled writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'true');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'true');
+ assert_equals(element.writingSuggestions, 'false');
+ assert_equals(element.getAttribute('writingsuggestions'), 'false');
+ });
+}, 'Test overriding the parent element\'s `writingsuggestions` attribute from "true" to "false".');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions=""><input writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><div writingsuggestions="false"></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><span writingsuggestions="false"></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><input type="color" writingsuggestions="false"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions=""><textarea disabled writingsuggestions="false"></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'true');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), '');
+ assert_equals(element.writingSuggestions, 'false');
+ assert_equals(element.getAttribute('writingsuggestions'), 'false');
+ });
+}, 'Test overriding the parent element\'s `writingsuggestions` attribute from the empty string to "false".');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="true" /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions="true"></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions="true"></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="true"></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions="true"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions="true"></textarea></body></html>', 'text/html').body.firstElementChild, ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'false');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'false');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), 'true');
+ });
+}, 'Test overriding the parent element\'s `writingsuggestions` attribute from "false" to "true".');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="foo" /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions="foo"></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions="foo"></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions="foo"></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions="foo"/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions="foo"></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'false');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'false');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), 'foo');
+ });
+}, 'Test overriding the parent element\'s `writingsuggestions` attribute from "false" to an invalid value.');
+
+test(function() {
+ const elements = [ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input writingsuggestions="" /></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea writingsuggestions=""></textarea></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><div writingsuggestions=""></div></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><span writingsuggestions=""></span></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><input type="color" writingsuggestions=""/></body></html>', 'text/html').body.firstElementChild,
+ new DOMParser().parseFromString('<html><body writingsuggestions="false"><textarea disabled writingsuggestions=""></textarea></body></html>', 'text/html').body.firstElementChild ];
+
+ elements.forEach(function(element) {
+ assert_equals(element.parentElement.writingSuggestions, 'false');
+ assert_equals(element.parentElement.getAttribute('writingsuggestions'), 'false');
+ assert_equals(element.writingSuggestions, 'true');
+ assert_equals(element.getAttribute('writingsuggestions'), '');
+ });
+}, 'Test overriding the parent element\'s `writingsuggestions` attribute from "false" to the empty string.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea></textarea><div></div><span></span><input type="color"/><textarea disabled></textarea></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelectorAll('input')[0].writingSuggestions, 'false');
+ assert_equals(doc.querySelectorAll('textarea')[0].writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+ assert_equals(doc.querySelectorAll('input')[1].writingSuggestions, 'false');
+ assert_equals(doc.querySelectorAll('textarea')[1].writingSuggestions, 'false');
+}, 'Test turning off writing suggestions for an entire document.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input writingsuggestions="true" /><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input element from "false" to "true".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea writingsuggestions="true"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a textarea element from "false" to "true".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea></textarea><div writingsuggestions="true"></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a div element from "false" to "true".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input /><textarea></textarea><div></div><span writingsuggestions="true"></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to "true".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions="true"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions="true"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to "true". The User Agent is responsible that writing suggestions are not applied to the element');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input writingsuggestions=""><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input element from "false" to the empty string.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea writingsuggestions=""></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a textarea element from "false" to the empty string.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea></textarea><div writingsuggestions=""></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a div element from "false" to the empty string.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea></textarea><div></div><span writingsuggestions=""></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to the empty string.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions=""><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions=""></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to the empty string. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input writingsuggestions="foo"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input element from "false" to an invalid value.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea writingsuggestions="foo"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a textarea element from "false" to an invalid value.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea></textarea><div writingsuggestions="foo"></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a div element from "false" to an invalid value.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea></textarea><div></div><span writingsuggestions="foo"></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "false" to an invalid value.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input type="color" writingsuggestions="foo"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="false"><body><input><textarea disabled writingsuggestions="foo"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'false');
+ assert_equals(doc.body.writingSuggestions, 'false');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "false" to an invalid value. The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input element from "true" to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input><textarea writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a textarea element from "true" to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input><textarea></textarea><div writingsuggestions="false"></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a div element from "true" to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input><textarea></textarea><div></div><span writingsuggestions="false"></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from "true" to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input type="color" writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><input><textarea disabled writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from "true" to "false". The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input element from the empty string to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input><textarea writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a textarea element from the empty string to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input><textarea></textarea><div writingsuggestions="false"></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a div element from the empty string to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input><textarea></textarea><div></div><span writingsuggestions="false"></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'false');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a span element from the empty string to "false".');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input type="color" writingsuggestions="false"><textarea></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on an input type which the attribute doesn\'t apply from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions=""><body><input><textarea disabled writingsuggestions="false"></textarea><div></div><span></span></body></html>', 'text/html');
+ assert_equals(doc.documentElement.writingSuggestions, 'true');
+ assert_equals(doc.body.writingSuggestions, 'true');
+ assert_equals(doc.querySelector('input').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('textarea').writingSuggestions, 'false');
+ assert_equals(doc.querySelector('div').writingSuggestions, 'true');
+ assert_equals(doc.querySelector('span').writingSuggestions, 'true');
+}, 'Test overriding a non-parent ancestor element\'s `writingsuggestions` attribute on a disabled textarea element from the empty string to "false". The User Agent is responsible that writing suggestions are not applied to the element.');
+
+test(function() {
+ const doc = new DOMParser().parseFromString('<html writingsuggestions="true"><body><div contenteditable="true"><span>Writing suggestions allowed.</span> <span writingsuggestions="false">Writing suggestions not allowed.</span></div></body></html>', 'text/html');
+ const div = doc.querySelector('div');
+ const span1 = doc.querySelector('span');
+ const span2 = doc.querySelector('span:last-child');
+ assert_equals(div.writingSuggestions, 'true');
+ assert_equals(span1.writingSuggestions, 'true');
+ assert_equals(span2.writingSuggestions, 'false');
+}, 'Test that for continuous text on the screen, writing suggestions may be allowed in one part but not another.');
+
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html
new file mode 100644
index 00000000000..eeb05b7b98e
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-far.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #spacer {
+ width: 130px;
+ height: 10000vh;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes do not load when far from viewport."
+ );
+
+ function iframe_onload() {
+ t.unreached_func(
+ "Lazy-loading iframe far from viewport should not load."
+ )();
+ }
+
+ t.step_timeout(() => {
+ t.done();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html
new file mode 100644
index 00000000000..f058b46fbd9
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal-far.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ display: flex;
+ }
+
+ #spacer {
+ width: 10000vw;
+ height: 130px;
+ flex-shrink: 0;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ flex-shrink: 0;
+ }
+</style>
+
+<div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes do not load when far from viewport."
+ );
+
+ function img_onload() {
+ t.unreached_func(
+ "Lazy-loading iframe far from viewport should not load."
+ )();
+ }
+
+ t.step_timeout(() => {
+ t.done();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal.html
new file mode 100644
index 00000000000..80ba0829a9a
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-horizontal.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ display: flex;
+ }
+
+ #spacer {
+ width: 130px;
+ height: 130px;
+ flex-shrink: 0;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ flex-shrink: 0;
+ }
+</style>
+
+<div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/green.png"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html
new file mode 100644
index 00000000000..9eec621c891
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-2.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #scroller2 {
+ width: 110px;
+ height: 110px;
+ overflow: scroll;
+ }
+
+ #spacer {
+ width: 130px;
+ height: 130px;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id=scroller2>
+ <div id="spacer"></div>
+ <div id="scroller">
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+ </div>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-3.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-3.html
new file mode 100644
index 00000000000..aa02bb41516
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-3.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #scroller2 {
+ width: 110px;
+ height: 110px;
+ overflow: scroll;
+ }
+
+ #scroller3 {
+ width: 120px;
+ height: 120px;
+ overflow: scroll;
+ }
+
+ #spacer {
+ width: 130px;
+ height: 130px;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id=scroller3>
+ <div id=scroller2>
+ <div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+ </div>
+ </div>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-4.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-4.html
new file mode 100644
index 00000000000..e15d891fb5b
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-4.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #scroller2 {
+ width: 110px;
+ height: 110px;
+ overflow: scroll;
+ }
+
+ .spacer {
+ width: 130px;
+ height: 130px;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id=scroller2>
+ <div class="spacer"></div>
+ <div id="scroller">
+ <div class="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+ </div>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-5.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-5.html
new file mode 100644
index 00000000000..b36265024d5
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested-5.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ display: flex;
+ }
+
+ #scroller2 {
+ width: 110px;
+ height: 110px;
+ overflow: scroll;
+ }
+
+ .spacer {
+ width: 130px;
+ height: 130px;
+ flex-shrink: 0;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ flex-shrink: 0;
+ }
+</style>
+
+<div id=scroller2>
+ <div class="spacer"></div>
+ <div id="scroller">
+ <div class="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+ </div>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded images load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested.html
new file mode 100644
index 00000000000..50b5e7ee0ad
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller-nested.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #scroller2 {
+ width: 110px;
+ height: 110px;
+ overflow: scroll;
+ }
+
+ #spacer {
+ width: 130px;
+ height: 130px;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id=scroller2>
+ <div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+ </div>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script>
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller.html b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller.html
new file mode 100644
index 00000000000..631710e740d
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-in-scroller.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#lazy-load-root-margin">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ #scroller {
+ width: 100px;
+ height: 100px;
+ overflow: scroll;
+ background-color: gray;
+ }
+
+ #spacer {
+ width: 100px;
+ height: 100px;
+ }
+
+ #target {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<div id="scroller">
+ <div id="spacer"></div>
+ <iframe
+ id="target"
+ src="resources/subframe.html"
+ loading="lazy"
+ onload="iframe_onload();"
+ ></iframe>
+</div>
+
+<script>
+ const t = async_test(
+ "Test that lazy-loaded iframes load when near viewport."
+ );
+
+ function iframe_onload() {
+ t.done();
+ }
+
+ t.step_timeout(() => {
+ t.unreached_func(
+ "Timed out while waiting for iframe to load."
+ )();
+ }, 2000);
+</script> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/forms/the-form-element/form-indexed-element-shadow.html b/tests/wpt/tests/html/semantics/forms/the-form-element/form-indexed-element-shadow.html
new file mode 100644
index 00000000000..a108ce8a93f
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/forms/the-form-element/form-indexed-element-shadow.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>form.elements: indexed access reflects DOM order, not flat tree</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<form id="target">
+ <div id="host">
+ <template shadowrootmode="open">
+ <slot name="first"></slot>
+ <slot name="second"></slot>
+ </template>
+ <input id="first" slot="second">
+ <input id="second" slot="first">
+ </div>
+</form>
+<script>
+test(function() {
+ let target = document.getElementById("target");
+ let host = document.getElementById("host");
+ assert_true(!!host.shadowRoot, "Should have a shadow tree");
+ assert_equals(target.elements[0], first, "form.elements reflects DOM order, not flat tree order");
+ assert_equals(target.elements[1], second);
+});
+</script>
diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css b/tests/wpt/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css
index 726380f940d..a7e9a87cdfa 100644
--- a/tests/wpt/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css
+++ b/tests/wpt/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css
@@ -10,8 +10,8 @@
inset: auto;
min-inline-size: anchor-size(self-inline);
min-block-size: 1lh;
- inset-block-start: anchor(auto);
- inset-inline-start: anchor(auto-same);
+ inset-block-start: anchor(self-end);
+ inset-inline-start: anchor(self-start);
font-family: Arial;
font-size: 13.3333px;
diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/select-attribute-crash.html b/tests/wpt/tests/html/semantics/forms/the-select-element/select-attribute-crash.html
new file mode 100644
index 00000000000..5330411a5dc
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/forms/the-select-element/select-attribute-crash.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html class=test-wait>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://issues.chromium.org/324325525">
+
+<!-- Attempting to slot a child of <select> after initial slot assignment should not crash. -->
+
+<select size=1>
+ <optgroup></optgroup>
+</select>
+<script>
+requestAnimationFrame(() => {
+ document.querySelector('optgroup').setAttribute('slot', 'slot1');
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('test-wait');
+ });
+});
+</script>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute-ref.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute-ref.html
new file mode 100644
index 00000000000..7aadaf51b72
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<head>
+ <title>Shown modal dialog where the popover attribute is removed</title>
+</head>
+<body>
+ <dialog popover style="padding: 2em"></dialog>
+ <script>
+ const d = document.querySelector("dialog");
+ d.showModal();
+ </script>
+</body>
+<html>
+
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute.html
new file mode 100644
index 00000000000..3827e90c5bd
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/top-layer-remove-popover-attribute.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<meta charset="utf-8">
+<meta name="assert" content="Removing the popover attribute of a hidden popover should not remove the dialog from the top layer.">
+<head>
+ <title>Shown modal dialog where the popover attribute is removed</title>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/popover.html#hide-popover-algorithm">
+ <link rel="match" href="top-layer-remove-popover-attribute-ref.html">
+</head>
+<body>
+ <dialog popover style="padding: 2em"></dialog>
+ <script>
+ const d = document.querySelector("dialog");
+ d.showModal();
+ d.popover = null;
+ </script>
+</body>
+<html>
diff --git a/tests/wpt/tests/html/semantics/popovers/popover-open-overflow-display-2.html b/tests/wpt/tests/html/semantics/popovers/popover-open-overflow-display-2.html
new file mode 100644
index 00000000000..f2388b7642e
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/popovers/popover-open-overflow-display-2.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel=help href="https://html.spec.whatwg.org/multipage/popover.html">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/popover-utils.js"></script>
+<script>
+async function checkStatus(p) {
+ p.showPopover();
+ await waitForRender();
+ assert_true(p.matches(":popover-open"));
+ p.hidePopover();
+ await waitForRender();
+}
+</script>
+
+<div id=container style="overflow: hidden; position: absolute;">
+ <div popover="auto" id=p1 style="position: absolute; top: 100px;">Absolute popover inside absolute element</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p1"));
+}, "Absolute popover inside absolute element");
+</script>
+
+<div id=p2 popover="auto" style="overflow: hidden; position: absolute;">
+ <div style="position: absolute; top: 100px;">Absolute element inside absolute popover</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p2"));
+}, "Absolute element inside absolute popover");
+</script>
+
+<div id=container style="overflow: hidden; position: fixed;">
+ <div popover="auto" id=p3 style="position: fixed; top: 100px;">Fixed popover inside fixed element</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p3"));
+}, "Fixed popover inside fixed element");
+</script>
+
+<div id=p4 popover="auto" style="overflow: hidden; position: fixed;">
+ <div style="position: fixed; top: 100px;">Fixed element inside fixed popover</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p4"));
+}, "Fixed element inside fixed popover");
+</script>
+
+<div id=container style="overflow: hidden; position: fixed;">
+ <div popover="auto" id=p5 style="position: absolute; top: 100px;">Absolute popover inside fixed element</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p5"));
+}, "Absolute popover inside fixed element");
+</script>
+
+<div id=p6 popover="auto" style="overflow: hidden; position: absolute;">
+ <div style="position: fixed; top: 100px;">Fixed element inside absolute popover</div>
+</div>
+<script>
+promise_test(async () => {
+ await checkStatus(document.querySelector("#p6"));
+}, "Fixed element inside absolute popover");
+</script>
diff --git a/tests/wpt/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html b/tests/wpt/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html
index 3a9d90c76b3..e658500a4eb 100644
--- a/tests/wpt/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html
+++ b/tests/wpt/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html
@@ -30,13 +30,13 @@
&#x202D; - The LRO (left-to-right override) formatting character.
&#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
In each DIV of the test:
- - the first BDI, having no characters with strong direction, should inherit the parent direction;
+ - the first BDI, having no characters with strong direction, should be LTR by default;
- the second BDI, having an LTR character first, should be LTR by default;
- the third BDI, having an RTL character first, should be RTL by default.
</div>
<div class="test">
<div dir="ltr"><bdi>[:)]</bdi>, <bdi>[+- a &#x05D1;]</bdi>, <bdi>[1 &#x05D2; d]</bdi>...</div>
- <div dir="rtl"><bdi>[(:]</bdi>, <bdi>[+- a &#x05D1;]</bdi>, <bdi>[1 &#x05D2; d]</bdi>...</div>
+ <div dir="rtl"><bdi>[:)]</bdi>, <bdi>[+- a &#x05D1;]</bdi>, <bdi>[1 &#x05D2; d]</bdi>...</div>
</div>
<div class="ref">
<div dir="ltr">&#x202D;[:)], [+- a &#x05D1;], [d &#x05D2; 1]...&#x202C;</div>
diff --git a/tests/wpt/tests/inert/inert-iframe-hittest.html b/tests/wpt/tests/inert/inert-iframe-hittest.html
index 8d7facf1723..d6c3551e996 100644
--- a/tests/wpt/tests/inert/inert-iframe-hittest.html
+++ b/tests/wpt/tests/inert/inert-iframe-hittest.html
@@ -9,7 +9,11 @@
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testdriver-actions.js"></script>
-
+<style>
+body {
+ padding: 5px;
+}
+</style>
<div id="wrapper" style="width: min-content">
<iframe id="iframe" inert></iframe>
</div>
@@ -39,6 +43,10 @@ promise_setup(async () => {
});
async function mouseDownAndGetEvents(test) {
+ await new test_driver.Actions()
+ .pointerMove(1, 1, { origin: document.body })
+ .send();
+
const receivedEvents = {
target: [],
wrapper: [],
diff --git a/tests/wpt/tests/mediacapture-record/MediaRecorder-mimetype.html b/tests/wpt/tests/mediacapture-record/MediaRecorder-mimetype.html
index 30df91c9587..74248d65f46 100644
--- a/tests/wpt/tests/mediacapture-record/MediaRecorder-mimetype.html
+++ b/tests/wpt/tests/mediacapture-record/MediaRecorder-mimetype.html
@@ -20,7 +20,7 @@ const AUDIO_CODECS_MIME_TYPES = [
'audio/ogg; codecs="opus"',
'audio/webm; codecs="vorbis"',
'audio/webm; codecs="opus"',
- 'aduio/mp4: codecs="mp4a.40.2"',
+ 'audio/mp4: codecs="mp4a.40.2"',
];
const VIDEO_ONLY_MIME_TYPES = [
diff --git a/tests/wpt/tests/orientation-event/motion/rounding.https.html b/tests/wpt/tests/orientation-event/motion/rounding.https.html
new file mode 100644
index 00000000000..846da79dfb5
--- /dev/null
+++ b/tests/wpt/tests/orientation-event/motion/rounding.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<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/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+function check_properties_for_coarsening(obj, properties) {
+ assert_not_equals(obj, null, 'Expected event object');
+ for (const prop of properties) {
+ assertValueIsCoarsened(obj[prop]);
+ }
+}
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'devicemotion');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const value = 1.23456789;
+ const motionData = generateMotionData(value, value, value,
+ value, value, value,
+ value, value, value);
+ await helper.setData(motionData);
+
+ const event = await new Promise(resolve => {
+ window.addEventListener('devicemotion', t.step_func(ev => {
+ resolve(ev);
+ }, { once: true }));
+ });
+
+ check_properties_for_coarsening(event.acceleration, ['x', 'y', 'z']);
+ check_properties_for_coarsening(event.accelerationIncludingGravity, ['x', 'y', 'z']);
+ check_properties_for_coarsening(event.rotationRate, ['alpha', 'beta', 'gamma']);
+}, 'Tests that devicemotion values are correctly rounded.');
+</script>
diff --git a/tests/wpt/tests/orientation-event/orientation/null-values.https.html b/tests/wpt/tests/orientation-event/orientation/null-values.https.html
index c54d73da50c..9505e009542 100644
--- a/tests/wpt/tests/orientation-event/orientation/null-values.https.html
+++ b/tests/wpt/tests/orientation-event/orientation/null-values.https.html
@@ -7,21 +7,32 @@
<script>
'use strict';
-promise_test(async (t) => {
- const helper = new SensorTestHelper(t, 'deviceorientation');
- await helper.grantSensorsPermissions();
- await helper.initializeSensors({disabledSensors: ['absolute-orientation', 'relative-orientation']});
+function test_null_orientation_data(eventType) {
+ promise_test(async t => {
+ const helper = new SensorTestHelper(t, eventType);
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors(
+ {disabledSensors : [ 'absolute-orientation', 'relative-orientation' ]});
- const orientationData1 = generateOrientationData(1.1, 2.2, 3.3, false);
- // Currently it is not possible to set individual values to null because the
- // parsing algorithms used by
- // https://w3c.github.io/sensors/#update-virtual-sensor-reading-command
- // always expect numbers.
- const orientationData2 = generateOrientationData(null, null, null, false);
+ const inputData = generateOrientationData(1.1, 2.2, 3.3, false);
+ // Currently it is not possible to set individual values to null because
+ // the parsing algorithms used by
+ // https://w3c.github.io/sensors/#update-virtual-sensor-reading-command
+ // always expect numbers.
+ const expectedData = generateOrientationData(
+ null, null, null,
+ /*absolute=*/ eventType === 'deviceorientationabsolute');
+ const expectedEvent = eventType === 'deviceorientationabsolute'
+ ? getExpectedAbsoluteOrientationEvent
+ : getExpectedOrientationEvent;
- // An example how setting relative-orientation sensor as disabled will output
- // null values. Even if we try to set non null values to sensor.
- await helper.setData(orientationData1);
- await waitForEvent(getExpectedOrientationEvent(orientationData2));
-}, 'Tests using null values for some of the event properties.');
+ // An example how setting the orientation sensors as disabled will always
+ // output null values.
+ await helper.setData(inputData);
+ await waitForEvent(expectedEvent(expectedData));
+ }, `${eventType}: Missing values are set to null or true/false accordingly`);
+}
+
+test_null_orientation_data('deviceorientation');
+test_null_orientation_data('deviceorientationabsolute');
</script>
diff --git a/tests/wpt/tests/orientation-event/orientation/rounding.https.html b/tests/wpt/tests/orientation-event/orientation/rounding.https.html
new file mode 100644
index 00000000000..89bfa1d53c3
--- /dev/null
+++ b/tests/wpt/tests/orientation-event/orientation/rounding.https.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<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/orientation-event-helpers.js"></script>
+<script>
+'use strict';
+
+promise_test(async (t) => {
+ const helper = new SensorTestHelper(t, 'deviceorientation');
+ await helper.grantSensorsPermissions();
+ await helper.initializeSensors();
+
+ const value = 1.23456789;
+ const orientationData = generateOrientationData(value, value, value, false);
+ await helper.setData(orientationData);
+
+ const event = await new Promise(resolve => {
+ window.addEventListener('deviceorientation', t.step_func(ev => {
+ resolve(ev);
+ }, { once: true }));
+ });
+
+ assertValueIsCoarsened(event.alpha);
+ assertValueIsCoarsened(event.beta);
+ assertValueIsCoarsened(event.gamma);
+}, 'Tests that deviceorientation values are correctly rounded.');
+</script>
diff --git a/tests/wpt/tests/orientation-event/resources/orientation-event-helpers.js b/tests/wpt/tests/orientation-event/resources/orientation-event-helpers.js
index 01e91c62aec..dab876fc6a3 100644
--- a/tests/wpt/tests/orientation-event/resources/orientation-event-helpers.js
+++ b/tests/wpt/tests/orientation-event/resources/orientation-event-helpers.js
@@ -203,6 +203,17 @@ function generateOrientationData(alpha, beta, gamma, absolute) {
return orientationData;
}
+function assertValueIsCoarsened(value) {
+ // Checks that the precision of the value is at most 0.1.
+ // https://www.w3.org/TR/orientation-event/ specification defines that all
+ // measurements are required to be coarsened to 0.1 degrees, 0.1 m/s^2 or
+ // 0.1 deg/s.
+ const resolution = 0.1;
+ const coarsenedValue = Math.round(value / resolution) * resolution;
+ assert_approx_equals(value, coarsenedValue, Number.EPSILON,
+ `Expected ${value}'s precision to be at most ${resolution}`);
+}
+
function assertEventEquals(actualEvent, expectedEvent) {
// If two doubles differ by less than this amount, we can consider them
// to be effectively equal.
diff --git a/tests/wpt/tests/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js b/tests/wpt/tests/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js
index 8488dd60ccf..09a73509b8a 100644
--- a/tests/wpt/tests/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js
+++ b/tests/wpt/tests/performance-timeline/not-restored-reasons/abort-block-bfcache.window.js
@@ -14,8 +14,8 @@ async_test(t => {
window.stop();
} else {
const nrr = performance.getEntriesByType('navigation')[0].notRestoredReasons;
+ assert_equals(nrr.reasons[0].reason, "parser-aborted");
assert_equals(nrr.reasons.length, 1);
- assert_equals(nrr.reasons[0], "parser-aborted");
t.done();
}
}, "aborting a parser should block bfcache.");
diff --git a/tests/wpt/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js b/tests/wpt/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js
index 4022e6e59f1..5812ebb2b36 100644
--- a/tests/wpt/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js
+++ b/tests/wpt/tests/performance-timeline/not-restored-reasons/performance-navigation-timing-navigation-failure.tentative.window.js
@@ -22,5 +22,5 @@ promise_test(async t => {
// Check the BFCache result and the reported reasons.
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
- await assertNotRestoredFromBFCache(rc1, ['error-document']);
+ await assertNotRestoredFromBFCache(rc1, ['navigation-failure']);
}); \ No newline at end of file
diff --git a/tests/wpt/tests/pointerevents/META.yml b/tests/wpt/tests/pointerevents/META.yml
index 1962feaf8af..e6dbf9deecf 100644
--- a/tests/wpt/tests/pointerevents/META.yml
+++ b/tests/wpt/tests/pointerevents/META.yml
@@ -1,6 +1,6 @@
spec: https://w3c.github.io/pointerevents/
suggested_reviewers:
- - Steditor
- - plehegar
- - RByers
- - NavidZ
+ - patrickhlauke
+ - flackr
+ - mustaqahmed
+ - smaug----
diff --git a/tests/wpt/tests/preload/prefetch-document.html b/tests/wpt/tests/preload/prefetch-document.html
index bdb12bd58a0..9f9810be46c 100644
--- a/tests/wpt/tests/preload/prefetch-document.html
+++ b/tests/wpt/tests/preload/prefetch-document.html
@@ -10,49 +10,6 @@
<script>
const {ORIGIN, REMOTE_ORIGIN, HTTP_NOTSAMESITE_ORIGIN} = get_host_info();
-const loaders = {
- image: {
- file: 'square.png',
- type: 'image/png',
- load: href => {
- const image = document.createElement('img');
- image.src = href;
- document.body.appendChild(image);
- return new Promise(resolve => image.addEventListener('load', resolve));
- }
- },
- script: {
- file: 'dummy.js',
- type: 'application/javascript',
- load: href => {
- const script = document.createElement('script');
- script.src = href;
- document.body.appendChild(script);
- return new Promise(resolve => script.addEventListener('load', resolve));
- }
- },
- style: {
- file: 'dummy.css',
- type: 'text/css',
- load: href => {
- const link = document.createElement('link');
- link.href = href;
- link.rel = "stylesheet";
- document.body.appendChild(link);
- return new Promise(resolve => link.addEventListener('load', resolve));
- }
- },
- document: {
- file: 'empty.html',
- type: 'text/html',
- load: href => {
- const iframe = document.createElement("iframe");
- iframe.src = href;
- document.body.appendChild(iframe);
- return new Promise(resolve => iframe.addEventListener("load", resolve));
- }
- }
-};
async function prefetch_document_and_count_fetches(options, t) {
const {href, uid} = await prefetch({
@@ -74,8 +31,10 @@ promise_test(async t => {
}, "same origin document prefetch without 'as' should be consumed");
promise_test(async t => {
- assert_equals(await prefetch_document_and_count_fetches({origin: REMOTE_ORIGIN}, t), 1);
-}, "same-site different-origin document prefetch without 'as' should be consumed");
+ // This (pre-)fetch will be blocked by ORB, which will prevent it from
+ // being cached. Thus this prefetch is not consumed.
+ assert_equals(await prefetch_document_and_count_fetches({origin: REMOTE_ORIGIN}, t), 2);
+}, "same-site different-origin document prefetch without 'as' should not be consumed");
promise_test(async t => {
assert_equals(await prefetch_document_and_count_fetches({origin: HTTP_NOTSAMESITE_ORIGIN}, t), 2);
@@ -100,4 +59,4 @@ promise_test(async t => {
assert_equals(results[0].headers.accept, results[1].headers.accept);
}, "Document prefetch should send the exact Accept header as navigation")
</script>
-</body> \ No newline at end of file
+</body>
diff --git a/tests/wpt/tests/selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html b/tests/wpt/tests/selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html
index cb2e44295a9..79fc52ac7db 100644
--- a/tests/wpt/tests/selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html
+++ b/tests/wpt/tests/selection/contenteditable/modifying-selection-with-non-primary-mouse-button.tentative.html
@@ -128,6 +128,11 @@ promise_test(async () => {
resetEditor();
editor.focus();
selection.collapse(span1.firstChild, 2);
+ let contextmenuFired = false;
+ function onContextMenu() {
+ contextmenuFired = true;
+ }
+ document.addEventListener("contextmenu", onContextMenu, {capture: true});
let actions = new test_driver.Actions();
await actions
.pointerMove(0, 0)
@@ -137,13 +142,26 @@ promise_test(async () => {
.pointerUp({button: getButtonType(actions)})
.keyUp("\uE008")
.send();
+ document.removeEventListener("contextmenu", onContextMenu, {capture: true});
- assert_equals(selection.anchorNode, span1.firstChild,
- "Selection#anchorNode should keep in the first <span> element");
- assert_equals(selection.anchorOffset, 2,
- "Selection#anchorNode should keep at 2 of the first <span> element");
- assert_equals(selection.focusNode, span2.firstChild,
- `Selection#focusNode should be in the second <span> element which was clicked by ${button} button`);
+ if (button != "secondary" || contextmenuFired) {
+ assert_equals(selection.anchorNode, span1.firstChild,
+ "Selection#anchorNode should keep in the first <span> element");
+ assert_equals(selection.anchorOffset, 2,
+ "Selection#anchorNode should keep at 2 of the first <span> element");
+ assert_equals(selection.focusNode, span2.firstChild,
+ `Selection#focusNode should be in the second <span> element which was clicked by ${button} button`);
+ } else {
+ // Special case for Firefox. Firefox users can forcibly open context menu
+ // with pressing shift key. In this case, users may want the secondary
+ // button click to work as without Shift key press.
+ assert_true(selection.isCollapsed,
+ `Selection should be collapsed after ${button} button click because contextmenu was not opened with Shift key`);
+ assert_equals(selection.focusNode, span2.firstChild,
+ `Selection should be collapsed in the second <span> element which was clicked by ${
+ button
+ } button because contextmenu was not opened with Shift key`);
+ }
}, `Shift + ${button} click should extend the selection`);
promise_test(async () => {
diff --git a/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-basic.html b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-basic.html
index 8bc6bec5f50..4f174b8e5f7 100644
--- a/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-basic.html
+++ b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-basic.html
@@ -55,6 +55,49 @@ test(() => {
}, 'Shadowrootmode reflection, setter');
test(() => {
+ const t = document.createElement('template');
+ t.setAttribute('shadowrootdelegatesfocus','');
+ assert_equals(t.shadowRootDelegatesFocus,true,'The shadowRootDelegatesFocus IDL should reflect the content attribute');
+ t.setAttribute('shadowrootdelegatesfocus','foobar');
+ assert_equals(t.shadowRootDelegatesFocus,true,'The value doesn\'t matter');
+ t.removeAttribute('shadowrootdelegatesfocus');
+ assert_equals(t.shadowRootDelegatesFocus,false,'No shadowRootDelegatesFocus attribute maps to false');
+}, 'Shadowrootdelegatesfocus reflection');
+
+test(() => {
+ const t = document.createElement('template');
+ assert_equals(t.getAttribute('shadowrootdelegatesfocus'), null);
+ t.shadowRootDelegatesFocus = true;
+ assert_equals(t.getAttribute('shadowrootdelegatesfocus'), '');
+ assert_equals(t.shadowRootDelegatesFocus, true);
+ t.shadowRootDelegatesFocus = false;
+ assert_equals(t.getAttribute('shadowrootdelegatesfocus'), null);
+ assert_equals(t.shadowRootDelegatesFocus, false);
+}, 'Shadowrootdelegatesfocus reflection, setter');
+
+
+test(() => {
+ const t = document.createElement('template');
+ t.setAttribute('shadowrootclonable','');
+ assert_equals(t.shadowRootClonable,true,'The shadowRootClonable IDL should reflect the content attribute');
+ t.setAttribute('shadowrootclonable','foobar');
+ assert_equals(t.shadowRootClonable,true,'The value doesn\'t matter');
+ t.removeAttribute('shadowrootclonable');
+ assert_equals(t.shadowRootClonable,false,'No shadowRootClonable attribute maps to false');
+}, 'Shadowrootclonable reflection');
+
+test(() => {
+ const t = document.createElement('template');
+ assert_equals(t.getAttribute('shadowrootclonable'), null);
+ t.shadowRootClonable = true;
+ assert_equals(t.getAttribute('shadowrootclonable'), '');
+ assert_equals(t.shadowRootClonable, true);
+ t.shadowRootClonable = false;
+ assert_equals(t.getAttribute('shadowrootclonable'), null);
+ assert_equals(t.shadowRootClonable, false);
+}, 'Shadowrootclonable reflection, setter');
+
+test(() => {
const div = document.createElement('div');
div.setHTMLUnsafe(`
<div id="host">
diff --git a/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats-2.html b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats-2.html
new file mode 100644
index 00000000000..74b14b8d8ff
--- /dev/null
+++ b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats-2.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>Duplicate declarative shadow trees</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<div id=multiple1>
+ <template shadowrootmode=open>1</template>
+ <template shadowrootmode=open>2</template>
+ <template shadowrootmode=open>3</template>
+</div>
+
+<div id=multiple2>
+ <template shadowrootmode=closed>1</template>
+ <template shadowrootmode=closed>2</template>
+ <template shadowrootmode=open>3</template>
+</div>
+
+<script>
+test((t) => {
+ t.add_cleanup(() => {
+ multiple1.remove();
+ multiple2.remove();
+ });
+ let shadow = multiple1.shadowRoot;
+ assert_true(!!shadow,'Remaining shadow root should be open');
+ assert_equals(shadow.textContent,"1");
+ assert_equals(multiple1.childElementCount, 2);
+ assert_equals(multiple1.firstElementChild.content.textContent, "2");
+ assert_equals(multiple1.lastElementChild.content.textContent, "3");
+ shadow = multiple2.shadowRoot;
+ assert_false(!!shadow,'Remaining shadow root should be closed');
+ assert_equals(multiple2.childElementCount, 2);
+ assert_equals(multiple2.firstElementChild.content.textContent, "2");
+ assert_equals(multiple2.lastElementChild.content.textContent, "3");
+},'Repeated declarative shadow roots keep only the first');
+</script>
diff --git a/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats.html b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats.html
index 69f5c0f077a..9cee41f2f31 100644
--- a/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats.html
+++ b/tests/wpt/tests/shadow-dom/declarative/declarative-shadow-dom-repeats.html
@@ -22,13 +22,19 @@
<script>
test((t) => {
+ t.add_cleanup(() => {
+ multiple1.remove();
+ multiple2.remove();
+ });
let shadow = multiple1.shadowRoot;
assert_true(!!shadow,'Remaining shadow root should be open');
assert_equals(shadow.textContent,"Open");
+ assert_equals(multiple1.childElementCount, 1);
+ assert_equals(multiple1.firstElementChild.shadowRootMode, "closed");
shadow = multiple2.shadowRoot;
assert_false(!!shadow,'Remaining shadow root should be closed');
- multiple1.remove(); // Cleanup
- multiple2.remove();
+ assert_equals(multiple2.childElementCount, 1);
+ assert_equals(multiple2.firstElementChild.shadowRootMode, "open");
},'Repeated declarative shadow roots keep only the first');
</script>
@@ -40,39 +46,48 @@ test((t) => {
test((t) => {
assert_throws_dom("NotSupportedError",() => {
open1.attachShadow({mode: "closed"});
- },'Mismatched shadow root type should throw');
+ },'Mismatched shadow root mode should throw');
const initialShadow = open1.shadowRoot;
const shadow = open1.attachShadow({mode: "open"}); // Shouldn't throw
assert_equals(shadow,initialShadow,'Same shadow should be returned');
assert_equals(shadow.textContent,'','Shadow should be empty');
-},'Calling attachShadow() on declarative shadow root must match type');
+},'Calling attachShadow() on declarative shadow root must match mode');
</script>
<div id=open2>
- <template shadowrootmode=open shadowrootdelegatesfocus shadowrootclonable>
+ <template shadowrootmode=open shadowrootdelegatesfocus shadowrootclonable serializable>
Open, delegates focus (not the default), clonable (not the default)
- named slot assignment (the default)
+ serializable (not the default), named slot assignment (the default)
</template>
</div>
<script>
test((t) => {
+ t.add_cleanup(() => open2.remove());
+ assert_true(!!open2.shadowRoot);
+ // Changing the mode should throw.
assert_throws_dom("NotSupportedError",() => {
- open2.attachShadow({mode: "closed", delegatesFocus: true, slotAssignment: "named", clonable: true});
- },'Mismatched shadow root type should throw');
+ open2.attachShadow({mode: "closed"});
+ },'Mismatched shadow root mode should throw');
assert_throws_dom("NotSupportedError",() => {
- open2.attachShadow({mode: "open", delegatesFocus: false, slotAssignment: "named", clonable: true});
- },'Mismatched shadow root delegatesFocus should throw');
- assert_throws_dom("NotSupportedError",() => {
- open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "manual", clonable: true});
- },'Mismatched shadow root slotAssignment should throw');
- assert_throws_dom("NotSupportedError",() => {
- open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "named", clonable: false});
- },'Mismatched shadow root clonable should throw');
+ open2.attachShadow({mode: "closed", delegatesFocus: true, slotAssignment: "named", clonable: true, serializable: true});
+ },'Mismatched shadow root mode should throw (explicit args)');
+ // Changing other things should not throw, and should not change the shadow root's settings
const initialShadow = open2.shadowRoot;
- const shadow = open2.attachShadow({mode: "open", delegatesFocus: true, slotAssignment: "named", clonable: true}); // Shouldn't throw
- assert_equals(shadow,initialShadow,'Same shadow should be returned');
- assert_equals(shadow.textContent,'','Shadow should be empty');
+ assert_equals(initialShadow.delegatesFocus,true);
+ assert_equals(initialShadow.slotAssignment,"named");
+ assert_true(initialShadow.clonable);
+ assert_true(initialShadow.serializable);
+ let newShadow = open2.attachShadow({mode: "open", delegatesFocus: false, slotAssignment: "manual", clonable: false, serializable: false});
+ assert_equals(newShadow,initialShadow,'Same shadow should be returned');
+ assert_equals(newShadow.textContent,'','Shadow should be empty');
+ assert_equals(newShadow.delegatesFocus,true);
+ assert_equals(newShadow.slotAssignment,"named");
+ assert_true(newShadow.clonable);
+ assert_true(newShadow.serializable);
+ assert_throws_dom("NotSupportedError",() => {
+ open2.attachShadow({mode: "open"});
+ },'Invoking attachShadow() on a non-declarative shadow root should throw');
},'Calling attachShadow() on declarative shadow root must match all parameters');
</script>
diff --git a/tests/wpt/tests/shared-storage/resources/credentials-test-helper.py b/tests/wpt/tests/shared-storage/resources/credentials-test-helper.py
new file mode 100644
index 00000000000..81a988e3581
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/resources/credentials-test-helper.py
@@ -0,0 +1,22 @@
+def main(request, response):
+ """
+ A handler that does either one of the following based on the provided
+ "action" parameter:
+ 1) action="store-cookie": Stores the provided token and the request cookie
+ to the stash, and returns a regular module script content.
+ 2) action="get-cookie": Retrieves and returns the content stored in the
+ stash at the provided token.
+ """
+ token = request.GET[b"token"]
+ action = request.GET[b"action"]
+
+ response.status = 200
+ response.headers.append(b"Content-Type", b"text/javascript")
+
+ if action == b"store-cookie":
+ cookie = request.headers.get(b"Cookie", b"NO_COOKIE_HEADER")
+ request.server.stash.put(token, cookie)
+ return b""
+ else:
+ assert action == b"get-cookie"
+ return request.server.stash.take(token)
diff --git a/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-include.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-include.tentative.https.sub.html
new file mode 100644
index 00000000000..a9082661a8b
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-include.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ await sharedStorage.worklet.addModule(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "include" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "key0=value0");
+}, 'addModule() with same-origin module script and credentials "include"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-omit.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-omit.tentative.https.sub.html
new file mode 100644
index 00000000000..a5945725c01
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-omit.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ await sharedStorage.worklet.addModule(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "omit" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "NO_COOKIE_HEADER");
+}, 'addModule() with same-origin module script and credentials "omit"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-same-origin.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-same-origin.tentative.https.sub.html
new file mode 100644
index 00000000000..aea76264384
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-add-module-credentials-same-origin.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ await sharedStorage.worklet.addModule(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "same-origin" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "key0=value0");
+}, 'addModule() with same-origin module script and credentials "same-origin"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-include.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-include.tentative.https.sub.html
new file mode 100644
index 00000000000..2e1d9cf7235
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-include.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ const worklet = await sharedStorage.createWorklet(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "include" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "key0=value0");
+}, 'createWorklet() with same-origin module script and credentials "include"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-omit.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-omit.tentative.https.sub.html
new file mode 100644
index 00000000000..ef90c02d643
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-omit.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ const worklet = await sharedStorage.createWorklet(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "omit" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "NO_COOKIE_HEADER");
+}, 'createWorklet() with same-origin module script and credentials "omit"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-same-origin.tentative.https.sub.html b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-same-origin.tentative.https.sub.html
new file mode 100644
index 00000000000..6d9fd7c1362
--- /dev/null
+++ b/tests/wpt/tests/shared-storage/same-origin-create-worklet-credentials-same-origin.tentative.https.sub.html
@@ -0,0 +1,30 @@
+<!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="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async () => {
+ const ancestor_key = token();
+ document.cookie = "key0=value0";
+ const helper_url = `/shared-storage/resources/credentials-test-helper.py`;
+
+ const worklet = await sharedStorage.createWorklet(
+ helper_url + `?action=store-cookie&token=${ancestor_key}`,
+ { credentials: "same-origin" });
+
+ const request_cookie_fetch_response =
+ await fetch(helper_url + `?action=get-cookie&token=${ancestor_key}`);
+
+ const request_cookie_text = await request_cookie_fetch_response.text();
+
+ assert_equals(request_cookie_text, "key0=value0");
+}, 'createWorklet() with same-origin module script and credentials "same-origin"');
+
+</script>
+</body>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/replacestate.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/replacestate.tentative.html
index 42e9a718997..d47b9b65388 100644
--- a/tests/wpt/tests/soft-navigation-heuristics/replacestate.tentative.html
+++ b/tests/wpt/tests/soft-navigation-heuristics/replacestate.tentative.html
@@ -15,14 +15,16 @@
</main>
<script>
const link = document.getElementById("link");
- testSoftNavigation({
- addContent: async () => {
+ testSoftNavigationNotDetected({
+ link: link,
+ eventTarget: link,
+ eventName: "click",
+ eventHandler: async e => {
+ const url = URL + "?" + counter;
+ history.replaceState({}, '', url);
await addImageToMain();
},
- link: link,
- pushState: (url)=>{history.replaceState({}, '', url);},
- test: "Detect soft navigation with replaceState"});
+ testName: "Should not detect soft navigation with just replaceState"});
</script>
</body>
</html>
-
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 f2d766575db..6c3d616e26a 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
@@ -38,6 +38,9 @@
await StartDedicatedWorker(frame);
assert_true(cookieStringHasCookie("cookie", "unpartitioned",
+ await MessageWorker(frame, {command: "load"})),
+ "Worker's load was credentialed.");
+ assert_true(cookieStringHasCookie("cookie", "unpartitioned",
await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies})),
"Worker's fetch is credentialed.");
}, "Workers inherit storage access");
@@ -47,9 +50,14 @@
await SetFirstPartyCookieAndUnsetStorageAccessPermission(altRoot);
const frame = await SetUpResponderFrame(t, altRootResponder);
+ assert_false(await FrameHasStorageAccess(frame), "frame lacks storage access before request.");
+ assert_false(await HasUnpartitionedCookie(frame), "frame lacks access to cookies before request.");
await StartDedicatedWorker(frame);
assert_false(cookieStringHasCookie("cookie", "unpartitioned",
+ await MessageWorker(frame, {command: "load"})),
+ "Worker's load was uncredentialed.");
+ assert_false(cookieStringHasCookie("cookie", "unpartitioned",
await MessageWorker(frame, {command: "fetch", url: altRootEchoCookies})),
"Worker's first fetch is uncredentialed.");
diff --git a/tests/wpt/tests/storage-access-api/resources/bless_cross_site_permissions.html b/tests/wpt/tests/storage-access-api/resources/bless_cross_site_permissions.html
new file mode 100644
index 00000000000..c3c5b6c0b07
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/bless_cross_site_permissions.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<body>
+<script>
+// In order to enable `requestStorageAccess` in a third-party context for some
+// origin we must first act in a window where that same origin is the top-frame
+// due to the following requirements:
+// (1) The origin must be `bless`ed when it's in the top-frame
+// (2) `set_permission` always operates on the top-frame origin
+test_driver.set_test_context(window.opener.top);
+test_driver.bless("fake interaction", () => {}, window);
+test_driver.set_permission({ name: 'storage-access' }, 'granted');
+window.opener.postMessage("blessed", "*");
+</script>
+</body>
diff --git a/tests/wpt/tests/storage-access-api/resources/embedded_responder.js b/tests/wpt/tests/storage-access-api/resources/embedded_responder.js
index bc13c7e7e82..228a262f16e 100644
--- a/tests/wpt/tests/storage-access-api/resources/embedded_responder.js
+++ b/tests/wpt/tests/storage-access-api/resources/embedded_responder.js
@@ -79,7 +79,7 @@ window.addEventListener("message", async (event) => {
reply(await fetch(event.data.url, {mode: 'no-cors', credentials: 'include'}).then((resp) => resp.text()));
break;
case "start_dedicated_worker":
- worker = new Worker("embedded_worker.js");
+ worker = new Worker("embedded_worker.py");
reply(undefined);
break;
case "message_worker": {
diff --git a/tests/wpt/tests/storage-access-api/resources/embedded_worker.js b/tests/wpt/tests/storage-access-api/resources/embedded_worker.js
deleted file mode 100644
index f3a0fb257ad..00000000000
--- a/tests/wpt/tests/storage-access-api/resources/embedded_worker.js
+++ /dev/null
@@ -1,17 +0,0 @@
-"use strict";
-
-self.onmessage = async (message) => {
- function reply(data) {
- self.postMessage({data});
- }
-
- switch (message.data.command) {
- case "fetch": {
- const response = await fetch(message.data.url, {mode: 'cors', credentials: 'include'})
- .then((resp) => resp.text());
- reply(response);
- break;
- }
- default:
- }
-};
diff --git a/tests/wpt/tests/storage-access-api/resources/embedded_worker.py b/tests/wpt/tests/storage-access-api/resources/embedded_worker.py
new file mode 100644
index 00000000000..0aa457657f1
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/embedded_worker.py
@@ -0,0 +1,31 @@
+from cookies.resources.helpers import setNoCacheAndCORSHeaders
+
+# This worker messages how many connections have been made and checks what cookies are available.
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ headers[0] = (b"Content-Type", b"text/javascript")
+ cookie_header = request.headers.get(b"Cookie", b"")
+ document = b"""
+"use strict";
+
+self.onmessage = async (message) => {
+ function reply(data) {
+ self.postMessage({data});
+ }
+
+ switch (message.data.command) {
+ case "fetch": {
+ const response = await fetch(message.data.url, {mode: 'cors', credentials: 'include'})
+ .then((resp) => resp.text());
+ reply(response);
+ break;
+ }
+ case "load": {
+ reply(\"""" + cookie_header + b"""");
+ break;
+ }
+ default:
+ }
+};
+"""
+ return headers, document
diff --git a/tests/wpt/tests/storage-access-api/resources/get_cookies.py b/tests/wpt/tests/storage-access-api/resources/get_cookies.py
new file mode 100644
index 00000000000..07e8c2dae3c
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/get_cookies.py
@@ -0,0 +1,10 @@
+import json
+from cookies.resources.helpers import makeCookieHeader, readCookies, setNoCacheAndCORSHeaders
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ cookies = readCookies(request)
+ decoded_cookies = {isomorphic_decode(key): isomorphic_decode(val) for key, val in cookies.items()}
+ return headers, json.dumps(decoded_cookies) \ No newline at end of file
diff --git a/tests/wpt/tests/storage-access-api/resources/set_cookies.py b/tests/wpt/tests/storage-access-api/resources/set_cookies.py
new file mode 100644
index 00000000000..fe182dd00cb
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/set_cookies.py
@@ -0,0 +1,10 @@
+from cookies.resources.helpers import makeCookieHeader, setNoCacheAndCORSHeaders
+
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ headers[0] = (b"Content-Type", b"text/html; charset=utf-8")
+ headers.append(makeCookieHeader(b"samesite_strict", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ document = b"<!DOCTYPE html>"
+ return headers, document
diff --git a/tests/wpt/tests/storage-access-api/resources/shared-worker-cookies.py b/tests/wpt/tests/storage-access-api/resources/shared-worker-cookies.py
new file mode 100644
index 00000000000..9307c4112c5
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/shared-worker-cookies.py
@@ -0,0 +1,37 @@
+from cookies.resources.helpers import makeCookieHeader, readCookies, setNoCacheAndCORSHeaders
+
+# This worker messages how many connections have been made and checks what cookies are available.
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ headers[0] = (b"Content-Type", b"text/javascript")
+ cookies = readCookies(request)
+ message = b"ReadOnLoad:"
+ if b"samesite_strict" in cookies:
+ message += b"Strict"
+ if b"samesite_lax" in cookies:
+ message += b"Lax"
+ if b"samesite_none" in cookies:
+ message += b"None"
+ document = b"""
+let connection_count = 0;
+self.onconnect = (e) => {
+ connection_count++;
+ fetch("/storage-access-api/resources/get_cookies.py", {credentials: 'include'}).then((resp) => {
+ resp.json().then((cookies) => {
+ let message = \"""" + message + b""",ReadOnFetch:";
+ if (cookies.hasOwnProperty("samesite_strict")) {
+ message += "Strict";
+ }
+ if (cookies.hasOwnProperty("samesite_lax")) {
+ message += "Lax";
+ }
+ if (cookies.hasOwnProperty("samesite_none")) {
+ message += "None";
+ }
+ message += ",ConnectionsMade:" + connection_count;
+ e.ports[0].postMessage(message);
+ });
+ });
+}
+"""
+ return headers, document \ No newline at end of file
diff --git a/tests/wpt/tests/storage-access-api/resources/shared-worker-relay.js b/tests/wpt/tests/storage-access-api/resources/shared-worker-relay.js
new file mode 100644
index 00000000000..c94acefec99
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/resources/shared-worker-relay.js
@@ -0,0 +1,10 @@
+// This worker relays any messages received to the first connection.
+let port;
+self.onconnect = (e) => {
+ if (port == undefined) {
+ port = e.ports[0];
+ }
+ e.ports[0].onmessage = (e) => {
+ port.postMessage(e.data);
+ }
+}
diff --git a/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
index ffb419f7995..2d5e22fa719 100644
--- a/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
+++ b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html
@@ -17,7 +17,7 @@
case "none": {
let couldRequestStorageAccessForNone = true;
try {
- await document.requestStorageAccess({});
+ await test_driver.bless("fake user interaction", () => document.requestStorageAccess({}));
} catch (_) {
couldRequestStorageAccessForNone = false;
}
@@ -26,7 +26,7 @@
}
let couldRequestStorageAccessForAllFalse = true;
try {
- await document.requestStorageAccess({all:false});
+ await test_driver.bless("fake user interaction", () => document.requestStorageAccess({all:false}));
} catch (_) {
couldRequestStorageAccessForAllFalse = false;
}
@@ -44,7 +44,7 @@
if (hasUnpartitionedCookieAccess || document.cookie.includes("test="+id)) {
message = "First-party cookies should not be readable before handle is loaded.";
}
- await document.requestStorageAccess({cookies: true});
+ await test_driver.bless("fake user interaction", () => document.requestStorageAccess({cookies: true}));
hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (!hasUnpartitionedCookieAccess || !document.cookie.includes("test="+id)) {
message = "First-party cookies should be readable if cookies were requested.";
@@ -52,7 +52,7 @@
break;
}
case "sessionStorage": {
- const handle = await document.requestStorageAccess({sessionStorage: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({sessionStorage: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -77,7 +77,7 @@
break;
}
case "localStorage": {
- const handle = await document.requestStorageAccess({localStorage: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({localStorage: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -102,7 +102,7 @@
break;
}
case "indexedDB": {
- const handle = await document.requestStorageAccess({indexedDB: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({indexedDB: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -119,7 +119,7 @@
break;
}
case "locks": {
- const handle = await document.requestStorageAccess({locks: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({locks: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -136,7 +136,7 @@
break;
}
case "caches": {
- const handle = await document.requestStorageAccess({caches: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({caches: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -153,7 +153,7 @@
break;
}
case "getDirectory": {
- const handle = await document.requestStorageAccess({getDirectory: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({getDirectory: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -172,7 +172,7 @@
break;
}
case "estimate": {
- const handle = await document.requestStorageAccess({estimate: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({estimate: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -188,7 +188,7 @@
break;
}
case "blobStorage": {
- const handle = await document.requestStorageAccess({createObjectURL: true, revokeObjectURL: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({createObjectURL: true, revokeObjectURL: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -230,7 +230,7 @@
break;
}
case "BroadcastChannel": {
- const handle = await document.requestStorageAccess({BroadcastChannel: true});
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({BroadcastChannel: true}));
let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
if (hasUnpartitionedCookieAccess) {
message = "First-party cookies should not be readable if not requested.";
@@ -243,6 +243,26 @@
local_channel.close();
break;
}
+ case "SharedWorker": {
+ const local_shared_worker = new SharedWorker("/storage-access-api/resources/shared-worker-relay.js", id);
+ local_shared_worker.port.start();
+ local_shared_worker.port.postMessage("Same-origin local access");
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({SharedWorker: true}));
+ let couldRequestAllCookies = true;
+ try {
+ handle.SharedWorker("/storage-access-api/resources/shared-worker-relay.js", {name: id, sameSiteCookies: 'all'});
+ } catch (_) {
+ couldRequestAllCookies = false;
+ }
+ if (couldRequestAllCookies) {
+ message = "Shared Workers in a third-party context should not be able to request SameSite cookies.";
+ }
+ handle.SharedWorker("/storage-access-api/resources/shared-worker-cookies.py", id).port.start();
+ const handle_shared_worker = handle.SharedWorker("/storage-access-api/resources/shared-worker-relay.js", {name: id, sameSiteCookies: 'none'});
+ handle_shared_worker.port.start();
+ handle_shared_worker.port.postMessage("Same-origin handle access");
+ break;
+ }
default: {
message = "Unexpected type " + type;
break;
@@ -254,6 +274,6 @@
// Step 7 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
await MaybeSetStorageAccess("*", "*", "allowed");
await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
- window.top.postMessage(message, "*");
+ window.top.postMessage({type: "result", message: message}, "*");
})();
</script>
diff --git a/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
index 8c30973416e..a9247a00020 100644
--- a/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
+++ b/tests/wpt/tests/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html
@@ -5,7 +5,10 @@
<script src="/storage-access-api/helpers.js"></script>
<body>
<script>
-(async function() {
+window.addEventListener("message", async (e) => {
+ if (e.data != "blessed") {
+ return;
+ }
test_driver.set_test_context(window.top);
const type = (new URLSearchParams(window.location.search)).get("type");
const id = (new URLSearchParams(window.location.search)).get("id");
@@ -14,14 +17,18 @@
try {
await MaybeSetStorageAccess("*", "*", "blocked");
await test_driver.set_permission({ name: 'storage-access' }, 'granted');
- let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
- if (hasUnpartitionedCookieAccess) {
- message = "First-party cookies should not be readable before handle is loaded.";
+ if (type == "cookies") {
+ let hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should not be readable before handle is loaded.";
+ }
}
- const handle = await document.requestStorageAccess({all: true});
- hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
- if (!hasUnpartitionedCookieAccess) {
- message = "First-party cookies should be readable after handle is loaded.";
+ const handle = await test_driver.bless("fake user interaction", () => document.requestStorageAccess({all: true}));
+ if (type == "cookies") {
+ hasUnpartitionedCookieAccess = await document.hasUnpartitionedCookieAccess();
+ if (!hasUnpartitionedCookieAccess) {
+ message = "First-party cookies should be readable after handle is loaded.";
+ }
}
switch (type) {
case "none": {
@@ -108,6 +115,12 @@
channel.close();
break;
}
+ case "SharedWorker": {
+ const shared_worker = handle.SharedWorker("/storage-access-api/resources/shared-worker-relay.js", id);
+ shared_worker.port.start();
+ shared_worker.port.postMessage("Cross-origin handle access");
+ break;
+ }
default: {
message = "Unexpected type " + type;
break;
@@ -119,13 +132,14 @@
await MaybeSetStorageAccess("*", "*", "allowed");
await test_driver.set_permission({ name: 'storage-access' }, 'prompt');
if (message) {
- window.top.postMessage(message, "*");
+ window.top.postMessage({type: "result", message: message}, "*");
return;
}
// Step 5 (storage-access-api/storage-access-beyond-cookies.{}.tentative.sub.https.html)
let iframe = document.createElement("iframe");
iframe.src = "https://{{hosts[][]}}:{{ports[https][0]}}/storage-access-api/resources/storage-access-beyond-cookies-iframe-iframe.html?type=" + type + "&id=" + id;
document.body.appendChild(iframe);
-})();
+});
+window.open("https://{{hosts[alt][]}}:{{ports[https][0]}}/storage-access-api/resources/bless_cross_site_permissions.html");
</script>
</body>
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js
index d709cdcd10f..feb268b4b81 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.BroadcastChannel.tentative.sub.https.window.js
@@ -17,8 +17,11 @@ async_test(t => {
let broadcasts = [];
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for BroadcastChannel", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for BroadcastChannel", "Storage Access API should be accessible and return first-party data");
assert_array_equals(broadcasts, ["Same-origin handle access"], "Should have only seen same-origin handle broadcasts");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.js
new file mode 100644
index 00000000000..ed4f25517f7
--- /dev/null
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.SharedWorker.tentative.sub.https.window.js
@@ -0,0 +1,48 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+
+'use strict';
+
+// Here's the set-up for this test:
+// Step 1 (top-frame) Set up fallback failure listener for if the handle cannot be used.
+// Step 2 (top-frame) Set up relay worker to expect "Same-origin handle access".
+// Step 3 (top-frame) Set cookies and embed an iframe that's cross-site with top-frame.
+// Step 4 (sub-frame) Try to use storage access API to access shared worker.
+// Step 5 (sub-frame) Embed an iframe that's same-origin with top-frame.
+// Step 6 (sub-sub-frame) Try to use storage access API to access first-party shared worker.
+// Step 7 (sub-sub-frame) Send "HasAccess for SharedWorker" message to top-frame.
+// Step 8 (top-frame) Set up cookie worker to expect it's already opened.
+// TODO(crbug.com/1484966): Verify access to cookies in shared workers.
+
+async_test(t => {
+ // Step 1
+ window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
+ assert_equals(e.data.message, "HasAccess for SharedWorker", "Storage Access API should be accessible and return first-party data");
+ }));
+
+ // Step 2
+ const id = Date.now();
+ const relay_worker = new SharedWorker("/storage-access-api/resources/shared-worker-relay.js", {name: id, sameSiteCookies: 'none'});
+ relay_worker.port.onmessage = t.step_func(e => {
+ assert_equals(e.data, "Same-origin handle access", "Relay worker should divert messages here");
+ // Step 8
+ const cookie_worker = new SharedWorker("/storage-access-api/resources/shared-worker-cookies.py", {name: id, sameSiteCookies: 'none'});
+ cookie_worker.port.onmessage = t.step_func(e => {
+ assert_equals(e.data, "ReadOnLoad:None,ReadOnFetch:None,ConnectionsMade:2", "Worker should already have been opened and only see SameSite=None cookies");
+ test_driver.delete_all_cookies().then(t.step_func(() => {
+ t.done();
+ }));
+ });
+ });
+
+ // Step 3
+ const cookie_set_window = window.open("/storage-access-api/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ let iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/storage-access-api/resources/storage-access-beyond-cookies-iframe.sub.html?type=SharedWorker&id="+id;
+ document.body.appendChild(iframe);
+ });
+}, "Verify StorageAccessAPIBeyondCookies for Shared Worker");
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js
index 6ef0bd08d4d..cc2785b6fac 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.blobStorage.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for blobStorage", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for blobStorage", "Storage Access API should be accessible and return first-party data");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.js
index dda1e545654..7907084e638 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.caches.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for caches", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for caches", "Storage Access API should be accessible and return first-party data");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.js
index c352ab29355..1ff00fa9193 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.cookies.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for cookies", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for cookies", "Storage Access API should be accessible and return first-party data");
test_driver.delete_all_cookies().then(t.step_func(() => {
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.js
index 2e9f6eed127..fb15dfee092 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.estimate.tentative.sub.https.window.js
@@ -18,8 +18,11 @@ async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for estimate", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for estimate", "Storage Access API should be accessible and return first-party data");
caches.delete(id).then(() => {
t.done();
});
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js
index 5038afc969a..b3b8f7e8e23 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.getDirectory.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for getDirectory", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for getDirectory", "Storage Access API should be accessible and return first-party data");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js
index 18c4317bbe9..8e9420da0da 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.indexedDB.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for indexedDB", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for indexedDB", "Storage Access API should be accessible and return first-party data");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js
index 6243cb1fa8c..80021317790 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js
@@ -16,7 +16,10 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
- assert_equals(e.data, "HasAccess for localStorage", "Storage Access API should be accessible and return first-party data");
+ if (e.data.type != "result") {
+ return;
+ }
+ assert_equals(e.data.message, "HasAccess for localStorage", "Storage Access API should be accessible and return first-party data");
window.localStorage.setItem("window_event", id);
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js
index 83aa28c018e..ed7d6ea4847 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.locks.tentative.sub.https.window.js
@@ -16,8 +16,11 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
+ if (e.data.type != "result") {
+ return;
+ }
// Step 8
- assert_equals(e.data, "HasAccess for locks", "Storage Access API should be accessible and return first-party data");
+ assert_equals(e.data.message, "HasAccess for locks", "Storage Access API should be accessible and return first-party data");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.js
index 3715fdf39ed..ba5ea3279df 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.none.tentative.sub.https.window.js
@@ -17,7 +17,10 @@ async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
// Step 8
- assert_equals(e.data, "HasAccess for none", "Storage Access API should not allow access for empty requests.");
+ if (e.data.type != "result") {
+ return;
+ }
+ assert_equals(e.data.message, "HasAccess for none", "Storage Access API should not allow access for empty requests.");
t.done();
}));
diff --git a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js
index 1b12f133b2c..93b243f6c11 100644
--- a/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js
+++ b/tests/wpt/tests/storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js
@@ -16,7 +16,10 @@
async_test(t => {
// Step 1
window.addEventListener("message", t.step_func(e => {
- assert_equals(e.data, "HasAccess for sessionStorage", "Storage Access API should be accessible and return first-party data");
+ if (e.data.type != "result") {
+ return;
+ }
+ assert_equals(e.data.message, "HasAccess for sessionStorage", "Storage Access API should be accessible and return first-party data");
window.sessionStorage.setItem("window_event", id);
}));
diff --git a/tests/wpt/tests/svg/painting/reftests/marker-path-001.svg b/tests/wpt/tests/svg/painting/reftests/marker-path-001.svg
index 7fb4adf4277..75bc5703b7b 100644
--- a/tests/wpt/tests/svg/painting/reftests/marker-path-001.svg
+++ b/tests/wpt/tests/svg/painting/reftests/marker-path-001.svg
@@ -11,6 +11,7 @@
<html:link rel="help"
href="https://www.w3.org/TR/SVG2/painting.html#Markers"/>
<html:link rel="match" href="marker-path-001-ref.svg" />
+ <html:meta name="fuzzy" content="0-8;0-8"/>
</g>
<defs>
diff --git a/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations-ref.svg b/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations-ref.svg
new file mode 100644
index 00000000000..c209d88a77c
--- /dev/null
+++ b/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations-ref.svg
@@ -0,0 +1,66 @@
+<svg viewBox="-10 -10 280 220" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <style>
+ text {
+ text-decoration: underline;
+ }
+ </style>
+ <defs>
+ <marker id="m" refX="5" refY="5" viewBox="0 0 10 10" overflow="visible">
+ <circle cx="5" cy="5" r="3" fill="black" stroke="black" fill-opacity="0.5"/>
+ </marker>
+ <svg id="poly" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke="lime" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m)">test</text>
+ </svg>
+ <svg id="poly-f-m-s" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m); text-decoration: underline">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke="lime" stroke-width="10" stroke-opacity="0.5">test</text>
+ </svg>
+ <svg id="poly-m-f-s" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m)">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke-width="10" stroke-opacity="0.5">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke="lime" stroke-width="10" stroke-opacity="0.5">test</text>
+ </svg>
+ <svg id="poly-s-m-f" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke="lime" stroke-width="10" stroke-opacity="0.5">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m)">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke-width="10" stroke-opacity="0.5">test</text>
+ </svg>
+ <svg id="poly-s-f-m" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke="lime" stroke-width="10" stroke-opacity="0.5">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke-width="10" stroke-opacity="0.5">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m)">test</text>
+ </svg>
+ <svg id="poly-m-s-f" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m)">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="none" stroke="lime" stroke-width="10" stroke-opacity="0.5">test</text>
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke-width="10" stroke-opacity="0.5">test</text>
+ </svg>
+ </defs>
+
+ <use xlink:href="#poly" width="50" height="50"/>
+ <use xlink:href="#poly" width="50" height="50" x="50"/>
+
+ <g transform="translate(0,50)">
+ <use xlink:href="#poly" width="50" height="50" x="0"/>
+ <use xlink:href="#poly" width="50" height="50" x="50"/>
+ <use xlink:href="#poly" width="50" height="50" x="100"/>
+ <use xlink:href="#poly-f-m-s" width="50" height="50" x="150"/>
+ <use xlink:href="#poly-f-m-s" width="50" height="50" x="200" />
+ </g>
+
+ <g transform="translate(0,100)">
+ <use xlink:href="#poly-s-f-m" width="50" height="50" x="0"/>
+ <use xlink:href="#poly-s-f-m" width="50" height="50" x="50"/>
+ <use xlink:href="#poly-s-f-m" width="50" height="50" x="100"/>
+ <use xlink:href="#poly-s-m-f" width="50" height="50" x="150"/>
+ <use xlink:href="#poly-s-m-f" width="50" height="50" x="200"/>
+ </g>
+
+ <g transform="translate(0,150)">
+ <use xlink:href="#poly-m-f-s" width="50" height="50" x="0"/>
+ <use xlink:href="#poly-m-s-f" width="50" height="50" x="50"/>
+ <use xlink:href="#poly-m-s-f" width="50" height="50" x="100"/>
+ <use xlink:href="#poly-m-f-s" width="50" height="50" x="150"/>
+ <use xlink:href="#poly-m-f-s" width="50" height="50" x="200"/>
+ </g>
+</svg>
diff --git a/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations.svg b/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations.svg
new file mode 100644
index 00000000000..5b313220bd3
--- /dev/null
+++ b/tests/wpt/tests/svg/painting/reftests/paintorder-text-decorations.svg
@@ -0,0 +1,38 @@
+<svg viewBox="-10 -10 280 220" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:html="http://www.w3.org/1999/xhtml">
+ <html:link rel="match" href="paintorder-text-decorations-ref.svg"/>
+ <defs>
+ <marker id="m" refX="5" refY="5" viewBox="0 0 10 10" overflow="visible">
+ <circle cx="5" cy="5" r="3" fill="black" stroke="black" fill-opacity="0.5"/>
+ </marker>
+ <svg id="poly" viewBox="-10 -10 420 420">
+ <text y="300" font-family="sans-serif" font-size="200" fill="blue" stroke="lime" stroke-width="10" stroke-opacity="0.5" style="marker: url(#m); text-decoration: underline">test</text>
+ </svg>
+ </defs>
+
+ <use xlink:href="#poly" width="50" height="50"/>
+ <use xlink:href="#poly" style="paint-order: normal" width="50" height="50" x="50"/>
+
+ <g transform="translate(0,50)">
+ <use xlink:href="#poly" style="paint-order: fill" width="50" height="50" x="0"/>
+ <use xlink:href="#poly" style="paint-order: fill stroke" width="50" height="50" x="50"/>
+ <use xlink:href="#poly" style="paint-order: fill stroke markers" width="50" height="50" x="100"/>
+ <use xlink:href="#poly" style="paint-order: fill markers" width="50" height="50" x="150"/>
+ <use xlink:href="#poly" style="paint-order: fill markers stroke" width="50" height="50" x="200" />
+ </g>
+
+ <g transform="translate(0,100)">
+ <use xlink:href="#poly" style="paint-order: stroke" width="50" height="50" x="0"/>
+ <use xlink:href="#poly" style="paint-order: stroke fill" width="50" height="50" x="50"/>
+ <use xlink:href="#poly" style="paint-order: stroke fill markers" width="50" height="50" x="100"/>
+ <use xlink:href="#poly" style="paint-order: stroke markers" width="50" height="50" x="150"/>
+ <use xlink:href="#poly" style="paint-order: stroke markers fill" width="50" height="50" x="200"/>
+ </g>
+
+ <g transform="translate(0,150)">
+ <use xlink:href="#poly" style="paint-order: markers" width="50" height="50" x="0"/>
+ <use xlink:href="#poly" style="paint-order: markers stroke" width="50" height="50" x="50"/>
+ <use xlink:href="#poly" style="paint-order: markers stroke fill" width="50" height="50" x="100"/>
+ <use xlink:href="#poly" style="paint-order: markers fill" width="50" height="50" x="150"/>
+ <use xlink:href="#poly" style="paint-order: markers fill stroke" width="50" height="50" x="200"/>
+ </g>
+</svg>
diff --git a/tests/wpt/tests/svg/pservers/reftests/gradient-transform-03.svg b/tests/wpt/tests/svg/pservers/reftests/gradient-transform-03.svg
new file mode 100644
index 00000000000..25e304614db
--- /dev/null
+++ b/tests/wpt/tests/svg/pservers/reftests/gradient-transform-03.svg
@@ -0,0 +1,22 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait">
+ <title>Gradient with 'transform' property added dynamically</title>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/single-page.html#pservers-LinearGradientElementGradientTransformAttribute"/>
+ <h:link rel="help" href="https://drafts.csswg.org/css-transforms/#transform-attribute-specificity"/>
+ <h:link rel="match" href="reference/green-100x100.svg"/>
+ <h:script src="/common/reftest-wait.js"/>
+ <h:script src="/common/rendering-utils.js"/>
+
+ <linearGradient id="lg">
+ <stop offset="0" stop-color="green"/>
+ <stop offset="0.5" stop-color="green"/>
+ <stop offset="1" stop-color="red"/>
+ </linearGradient>
+ <rect width="100" height="100" fill="url(#lg)"/>
+ <script>
+ waitForAtLeastOneFrame().then(() => {
+ const gradient = document.getElementById('lg');
+ gradient.style.transform = 'scale(2)';
+ takeScreenshot();
+ });
+ </script>
+</svg>
diff --git a/tests/wpt/tests/svg/pservers/reftests/pattern-transform-03.svg b/tests/wpt/tests/svg/pservers/reftests/pattern-transform-03.svg
new file mode 100644
index 00000000000..b2e0e7aaa2e
--- /dev/null
+++ b/tests/wpt/tests/svg/pservers/reftests/pattern-transform-03.svg
@@ -0,0 +1,21 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" class="reftest-wait">
+ <title>Pattern with 'transform' property added dynamically</title>
+ <h:link rel="help" href="https://svgwg.org/svg2-draft/single-page.html#pservers-PatternElementPatternTransformAttribute"/>
+ <h:link rel="help" href="https://drafts.csswg.org/css-transforms/#transform-attribute-specificity"/>
+ <h:link rel="match" href="reference/green-100x100.svg"/>
+ <h:script src="/common/reftest-wait.js"/>
+ <h:script src="/common/rendering-utils.js"/>
+
+ <pattern id="pat" width="100" height="100">
+ <rect x="25" y="25" width="75" height="75" fill="red"/>
+ <rect width="75" height="75" fill="green"/>
+ </pattern>
+ <rect width="100" height="100" fill="url(#pat)"/>
+ <script>
+ waitForAtLeastOneFrame().then(() => {
+ const pattern = document.getElementById('pat');
+ pattern.style.transform = 'translate(-25px, -25px) scale(2)';
+ takeScreenshot();
+ });
+ </script>
+</svg>
diff --git a/tests/wpt/tests/tools/ci/tc/tasks/test.yml b/tests/wpt/tests/tools/ci/tc/tasks/test.yml
index ea9c7f9daea..d62312737c8 100644
--- a/tests/wpt/tests/tools/ci/tc/tasks/test.yml
+++ b/tests/wpt/tests/tools/ci/tc/tasks/test.yml
@@ -4,7 +4,7 @@ components:
workerType: ci
schedulerId: taskcluster-github
deadline: "24 hours"
- image: webplatformtests/wpt:0.56
+ image: webplatformtests/wpt:0.57
maxRunTime: 7200
artifacts:
public/results:
diff --git a/tests/wpt/tests/tools/docker/Dockerfile b/tests/wpt/tests/tools/docker/Dockerfile
index a9162559ab8..e1ff6b90205 100644
--- a/tests/wpt/tests/tools/docker/Dockerfile
+++ b/tests/wpt/tests/tools/docker/Dockerfile
@@ -20,6 +20,7 @@ RUN apt-get -qqy update \
glib-networking-services \
gstreamer1.0-plugins-bad \
gstreamer1.0-gl \
+ libegl1-mesa-dev \
libosmesa6-dev \
libproxy1-plugin-webkit \
libvirt-daemon-system \
diff --git a/tests/wpt/tests/tools/webdriver/webdriver/bidi/modules/storage.py b/tests/wpt/tests/tools/webdriver/webdriver/bidi/modules/storage.py
index 4dfc82695e3..882306ea72b 100644
--- a/tests/wpt/tests/tools/webdriver/webdriver/bidi/modules/storage.py
+++ b/tests/wpt/tests/tools/webdriver/webdriver/bidi/modules/storage.py
@@ -46,12 +46,50 @@ class PartialCookie(Dict[str, Any]):
PartitionDescriptor = Union[StorageKeyPartitionDescriptor, BrowsingContextPartitionDescriptor]
-class Storage(BidiModule):
+class CookieFilter(Dict[str, Any]):
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ value: Optional[NetworkBytesValue] = None,
+ domain: Optional[str] = None,
+ path: Optional[str] = None,
+ http_only: Optional[bool] = None,
+ secure: Optional[bool] = None,
+ same_site: Optional[str] = None,
+ size: Optional[int] = None,
+ expiry: Optional[int] = None,
+ ):
+ if name is not None:
+ self["name"] = name
+ if value is not None:
+ self["value"] = value
+ if domain is not None:
+ self["domain"] = domain
+ if path is not None:
+ self["path"] = path
+ if http_only is not None:
+ self["httpOnly"] = http_only
+ if secure is not None:
+ self["secure"] = secure
+ if same_site is not None:
+ self["sameSite"] = same_site
+ if size is not None:
+ self["size"] = size
+ if expiry is not None:
+ self["expiry"] = expiry
- # TODO: extend with `filter`.
+
+class Storage(BidiModule):
@command
- def get_cookies(self, partition: Optional[PartitionDescriptor] = None) -> Mapping[str, Any]:
+ def get_cookies(
+ self,
+ filter: Optional[CookieFilter] = None,
+ partition: Optional[PartitionDescriptor] = None,
+ ) -> Mapping[str, Any]:
params: MutableMapping[str, Any] = {}
+
+ if filter is not None:
+ params["filter"] = filter
if partition is not None:
params["partition"] = partition
return params
diff --git a/tests/wpt/tests/tools/wpt/browser.py b/tests/wpt/tests/tools/wpt/browser.py
index c8998fee4aa..c7f67d334e1 100644
--- a/tests/wpt/tests/tools/wpt/browser.py
+++ b/tests/wpt/tests/tools/wpt/browser.py
@@ -1856,65 +1856,6 @@ class EdgeChromium(Browser):
return m.group(1)
-class Edge(Browser):
- """Edge-specific interface."""
-
- product = "edge"
- requirements = "requirements_edge.txt"
-
- def download(self, dest=None, channel=None, rename=None):
- raise NotImplementedError
-
- def install(self, dest=None, channel=None):
- raise NotImplementedError
-
- def find_binary(self, venv_path=None, channel=None):
- raise NotImplementedError
-
- def find_webdriver(self, venv_path=None, channel=None):
- return which("MicrosoftWebDriver")
-
- def install_webdriver(self, dest=None, channel=None, browser_binary=None):
- raise NotImplementedError
-
- def version(self, binary=None, webdriver_binary=None):
- command = "(Get-AppxPackage Microsoft.MicrosoftEdge).Version"
- try:
- return call("powershell.exe", command).strip()
- except (subprocess.CalledProcessError, OSError):
- self.logger.warning("Failed to call %s in PowerShell" % command)
- return None
-
-
-class EdgeWebDriver(Edge):
- product = "edge_webdriver"
-
-
-class InternetExplorer(Browser):
- """Internet Explorer-specific interface."""
-
- product = "ie"
- requirements = "requirements_ie.txt"
-
- def download(self, dest=None, channel=None, rename=None):
- raise NotImplementedError
-
- def install(self, dest=None, channel=None):
- raise NotImplementedError
-
- def find_binary(self, venv_path=None, channel=None):
- raise NotImplementedError
-
- def find_webdriver(self, venv_path=None, channel=None):
- return which("IEDriverServer.exe")
-
- def install_webdriver(self, dest=None, channel=None, browser_binary=None):
- raise NotImplementedError
-
- def version(self, binary=None, webdriver_binary=None):
- return None
-
-
class Safari(Browser):
"""Safari-specific interface.
diff --git a/tests/wpt/tests/tools/wpt/run.py b/tests/wpt/tests/tools/wpt/run.py
index dcf721ef39f..fd5382b45c3 100644
--- a/tests/wpt/tests/tools/wpt/run.py
+++ b/tests/wpt/tests/tools/wpt/run.py
@@ -503,6 +503,9 @@ class Chrome(BrowserSetup):
kwargs["webdriver_binary"] = webdriver_binary
else:
raise WptrunError("Unable to locate or install matching ChromeDriver binary")
+ if kwargs["headless"] is None and not kwargs["debug_test"]:
+ kwargs["headless"] = True
+ logger.info("Running in headless mode, pass --no-headless to disable")
if browser_channel in self.experimental_channels:
# HACK(Hexcles): work around https://github.com/web-platform-tests/wpt/issues/16448
kwargs["webdriver_args"].append("--disable-build-check")
@@ -726,53 +729,6 @@ class EdgeChromium(BrowserSetup):
kwargs["binary_args"].append("--no-sandbox")
-class Edge(BrowserSetup):
- name = "edge"
- browser_cls = browser.Edge
-
- def install(self, channel=None):
- raise NotImplementedError
-
- def setup_kwargs(self, kwargs):
- if kwargs["webdriver_binary"] is None:
- webdriver_binary = self.browser.find_webdriver()
-
- if webdriver_binary is None:
- raise WptrunError("""Unable to find WebDriver and we aren't yet clever enough to work out which
-version to download. Please go to the following URL and install the correct
-version for your Edge/Windows release somewhere on the %PATH%:
-
-https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
-""")
- kwargs["webdriver_binary"] = webdriver_binary
-
-
-class EdgeWebDriver(Edge):
- name = "edge_webdriver"
- browser_cls = browser.EdgeWebDriver
-
-
-class InternetExplorer(BrowserSetup):
- name = "ie"
- browser_cls = browser.InternetExplorer
-
- def install(self, channel=None):
- raise NotImplementedError
-
- def setup_kwargs(self, kwargs):
- if kwargs["webdriver_binary"] is None:
- webdriver_binary = self.browser.find_webdriver()
-
- if webdriver_binary is None:
- raise WptrunError("""Unable to find WebDriver and we aren't yet clever enough to work out which
-version to download. Please go to the following URL and install the driver for Internet Explorer
-somewhere on the %PATH%:
-
-https://selenium-release.storage.googleapis.com/index.html
-""")
- kwargs["webdriver_binary"] = webdriver_binary
-
-
class Safari(BrowserSetup):
name = "safari"
browser_cls = browser.Safari
@@ -924,9 +880,6 @@ product_setup = {
"chromium": Chromium,
"content_shell": ContentShell,
"edgechromium": EdgeChromium,
- "edge": Edge,
- "edge_webdriver": EdgeWebDriver,
- "ie": InternetExplorer,
"safari": Safari,
"servo": Servo,
"servodriver": ServoWebDriver,
diff --git a/tests/wpt/tests/tools/wptrunner/requirements_edge.txt b/tests/wpt/tests/tools/wptrunner/requirements_edge.txt
deleted file mode 100644
index 30b14b692fd..00000000000
--- a/tests/wpt/tests/tools/wptrunner/requirements_edge.txt
+++ /dev/null
@@ -1 +0,0 @@
-selenium==4.14.0
diff --git a/tests/wpt/tests/tools/wptrunner/requirements_ie.txt b/tests/wpt/tests/tools/wptrunner/requirements_ie.txt
deleted file mode 100644
index 4ff0fedd321..00000000000
--- a/tests/wpt/tests/tools/wptrunner/requirements_ie.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-mozprocess==1.3.1
-selenium==4.14.0
diff --git a/tests/wpt/tests/tools/wptrunner/tox.ini b/tests/wpt/tests/tools/wptrunner/tox.ini
index 2a3f2bdf109..82d3ac6f555 100644
--- a/tests/wpt/tests/tools/wptrunner/tox.ini
+++ b/tests/wpt/tests/tools/wptrunner/tox.ini
@@ -2,7 +2,7 @@
xfail_strict=true
[tox]
-envlist = py311-{base,chrome,edge,firefox,ie,opera,safari,sauce,servo,webkit,webkitgtk_minibrowser,epiphany},{py37,py38,py39,py310}-base
+envlist = py311-{base,chrome,firefox,opera,safari,sauce,servo,webkit,webkitgtk_minibrowser,epiphany},{py37,py38,py39,py310}-base
skip_missing_interpreters = False
[testenv]
@@ -10,9 +10,7 @@ deps =
-r{toxinidir}/../requirements_pytest.txt
-r{toxinidir}/requirements.txt
chrome: -r{toxinidir}/requirements_chromium.txt
- edge: -r{toxinidir}/requirements_edge.txt
firefox: -r{toxinidir}/requirements_firefox.txt
- ie: -r{toxinidir}/requirements_ie.txt
opera: -r{toxinidir}/requirements_opera.txt
safari: -r{toxinidir}/requirements_safari.txt
sauce: -r{toxinidir}/requirements_sauce.txt
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/__init__.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/__init__.py
index 4d10457699d..81dc549d730 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/__init__.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/__init__.py
@@ -30,11 +30,8 @@ product_list = ["android_weblayer",
"chromium",
"content_shell",
"edgechromium",
- "edge",
- "edge_webdriver",
"firefox",
"firefox_android",
- "ie",
"safari",
"sauce",
"servo",
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge.py
deleted file mode 100644
index 5b49545a38a..00000000000
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# mypy: allow-untyped-defs
-
-import time
-import subprocess
-from .base import require_arg
-from .base import WebDriverBrowser
-from ..executors import executor_kwargs as base_executor_kwargs
-from ..executors.base import WdspecExecutor # noqa: F401
-from ..executors.executorselenium import (SeleniumTestharnessExecutor, # noqa: F401
- SeleniumRefTestExecutor) # noqa: F401
-
-__wptrunner__ = {"product": "edge",
- "check_args": "check_args",
- "browser": "EdgeBrowser",
- "executor": {"testharness": "SeleniumTestharnessExecutor",
- "reftest": "SeleniumRefTestExecutor",
- "wdspec": "WdspecExecutor"},
- "browser_kwargs": "browser_kwargs",
- "executor_kwargs": "executor_kwargs",
- "env_extras": "env_extras",
- "env_options": "env_options",
- "run_info_extras": "run_info_extras",
- "timeout_multiplier": "get_timeout_multiplier"}
-
-
-def get_timeout_multiplier(test_type, run_info_data, **kwargs):
- if kwargs["timeout_multiplier"] is not None:
- return kwargs["timeout_multiplier"]
- if test_type == "wdspec":
- return 10
- return 1
-
-
-def check_args(**kwargs):
- require_arg(kwargs, "webdriver_binary")
-
-
-def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
- return {"webdriver_binary": kwargs["webdriver_binary"],
- "webdriver_args": kwargs.get("webdriver_args"),
- "timeout_multiplier": get_timeout_multiplier(test_type,
- run_info_data,
- **kwargs)}
-
-
-def executor_kwargs(logger, test_type, test_environment, run_info_data,
- **kwargs):
- executor_kwargs = base_executor_kwargs(test_type, test_environment, run_info_data, **kwargs)
- executor_kwargs["close_after_done"] = True
- executor_kwargs["timeout_multiplier"] = get_timeout_multiplier(test_type,
- run_info_data,
- **kwargs)
- executor_kwargs["capabilities"] = {}
- if test_type == "testharness":
- executor_kwargs["capabilities"]["pageLoadStrategy"] = "eager"
- return executor_kwargs
-
-
-def env_extras(**kwargs):
- return []
-
-
-def env_options():
- return {"supports_debugger": False}
-
-
-class EdgeBrowser(WebDriverBrowser):
- init_timeout = 60
-
- def __init__(self, logger, binary, webdriver_binary, webdriver_args=None,
- host="localhost", port=None, base_path="/", env=None, **kwargs):
- super().__init__(logger, binary, webdriver_binary, webdriver_args=webdriver_args,
- host=host, port=port, base_path=base_path, env=env, **kwargs)
- self.host = "localhost"
-
- def stop(self, force=False):
- super(self).stop(force)
- # Wait for Edge browser process to exit if driver process is found
- edge_proc_name = 'MicrosoftEdge.exe'
- for i in range(0, 5):
- procs = subprocess.check_output(['tasklist', '/fi', 'ImageName eq ' + edge_proc_name])
- if b'MicrosoftWebDriver.exe' not in procs:
- # Edge driver process already exited, don't wait for browser process to exit
- break
- elif edge_proc_name.encode() in procs:
- time.sleep(0.5)
- else:
- break
-
- if edge_proc_name.encode() in procs:
- # close Edge process if it is still running
- subprocess.call(['taskkill.exe', '/f', '/im', 'microsoftedge*'])
-
- def make_command(self):
- return [self.webdriver_binary, f"--port={self.port}"] + self.webdriver_args
-
-
-def run_info_extras(logger, **kwargs):
- osReleaseCommand = r"(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion').ReleaseId"
- osBuildCommand = r"(Get-ItemProperty 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion').BuildLabEx"
- try:
- os_release = subprocess.check_output(["powershell.exe", osReleaseCommand]).strip()
- os_build = subprocess.check_output(["powershell.exe", osBuildCommand]).strip()
- except (subprocess.CalledProcessError, OSError):
- return {}
-
- rv = {"os_build": os_build,
- "os_release": os_release}
- return rv
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py
deleted file mode 100644
index e985361e412..00000000000
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/edge_webdriver.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from .base import NullBrowser # noqa: F401
-from .edge import (EdgeBrowser, # noqa: F401
- check_args, # noqa: F401
- browser_kwargs, # noqa: F401
- executor_kwargs, # noqa: F401
- env_extras, # noqa: F401
- env_options, # noqa: F401
- run_info_extras, # noqa: F401
- get_timeout_multiplier) # noqa: F401
-
-from ..executors.base import WdspecExecutor # noqa: F401
-from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
- WebDriverRefTestExecutor) # noqa: F401
-
-
-__wptrunner__ = {"product": "edge_webdriver",
- "check_args": "check_args",
- "browser": "EdgeBrowser",
- "executor": {"testharness": "WebDriverTestharnessExecutor",
- "reftest": "WebDriverRefTestExecutor",
- "wdspec": "WdspecExecutor"},
- "browser_kwargs": "browser_kwargs",
- "executor_kwargs": "executor_kwargs",
- "env_extras": "env_extras",
- "env_options": "env_options",
- "run_info_extras": "run_info_extras",
- "timeout_multiplier": "get_timeout_multiplier"}
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
index aa9cf633232..3ce3b11d1f2 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
@@ -161,6 +161,10 @@ class ProfileCreator(FirefoxProfileCreator):
"dom.send_after_paint_to_content": True,
})
+ if self.package_name == "org.mozilla.geckoview.test_runner":
+ # Bug 1879324: The TestRunner doesn't support "beforeunload" prompts yet
+ profile.set_preferences({"dom.disable_beforeunload": True})
+
if self.test_type == "reftest":
self.logger.info("Setting android reftest preferences")
profile.set_preferences({
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/ie.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/ie.py
deleted file mode 100644
index 87b989c028b..00000000000
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/ie.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# mypy: allow-untyped-defs
-
-from .base import require_arg, WebDriverBrowser
-from .base import get_timeout_multiplier # noqa: F401
-from ..executors import executor_kwargs as base_executor_kwargs
-from ..executors.base import WdspecExecutor # noqa: F401
-
-__wptrunner__ = {"product": "ie",
- "check_args": "check_args",
- "browser": "WebDriverBrowser",
- "executor": {"wdspec": "WdspecExecutor"},
- "browser_kwargs": "browser_kwargs",
- "executor_kwargs": "executor_kwargs",
- "env_extras": "env_extras",
- "env_options": "env_options",
- "timeout_multiplier": "get_timeout_multiplier"}
-
-
-def check_args(**kwargs):
- require_arg(kwargs, "webdriver_binary")
-
-
-def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
- return {"webdriver_binary": kwargs["webdriver_binary"],
- "webdriver_args": kwargs.get("webdriver_args")}
-
-
-def executor_kwargs(logger, test_type, test_environment, run_info_data,
- **kwargs):
- options = {}
- options["requireWindowFocus"] = True
- capabilities = {}
- capabilities["se:ieOptions"] = options
- executor_kwargs = base_executor_kwargs(test_type, test_environment, run_info_data, **kwargs)
- executor_kwargs["close_after_done"] = True
- executor_kwargs["capabilities"] = capabilities
- return executor_kwargs
-
-
-def env_extras(**kwargs):
- return []
-
-
-def env_options():
- return {"supports_debugger": False}
-
-
-class InternetExplorerBrowser(WebDriverBrowser):
- def make_command(self):
- return [self.binary, f"--port={self.port}"] + self.webdriver_args
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce.py
index 0f7651638dc..0f21afd38f2 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce.py
@@ -44,10 +44,6 @@ def get_capabilities(**kwargs):
tags = kwargs["sauce_tags"]
tunnel_id = kwargs["sauce_tunnel_id"]
prerun_script = {
- "MicrosoftEdge": {
- "executable": "sauce-storage:edge-prerun.bat",
- "background": False,
- },
"safari": {
"executable": "sauce-storage:safari-prerun.sh",
"background": False,
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce_setup/edge-prerun.bat b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce_setup/edge-prerun.bat
deleted file mode 100755
index 1a3e6fee309..00000000000
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/sauce_setup/edge-prerun.bat
+++ /dev/null
@@ -1,9 +0,0 @@
-@echo off
-reg add "HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Storage\microsoft.microsoftedge_8wekyb3d8bbwe\MicrosoftEdge\New Windows" /v "PopupMgr" /t REG_SZ /d no
-
-
-REM Download and install the Ahem font
-REM - https://wiki.saucelabs.com/display/DOCS/Downloading+Files+to+a+Sauce+Labs+Virtual+Machine+Prior+to+Testing
-REM - https://superuser.com/questions/201896/how-do-i-install-a-font-from-the-windows-command-prompt
-bitsadmin.exe /transfer "JobName" https://github.com/web-platform-tests/wpt/raw/master/fonts/Ahem.ttf "%WINDIR%\Fonts\Ahem.ttf"
-reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "Ahem (TrueType)" /t REG_SZ /d Ahem.ttf /f
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/tests/base.py b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/base.py
index 176eef6a423..8e71aba812d 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/tests/base.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/tests/base.py
@@ -20,7 +20,6 @@ if "CURRENT_TOX_ENV" in os.environ:
tox_env_extra_browsers = {
"chrome": {"chrome_android"},
- "edge": {"edge_webdriver"},
"servo": {"servodriver"},
}
diff --git a/tests/wpt/tests/trusted-types/trusted-types-from-literal.html b/tests/wpt/tests/trusted-types/trusted-types-from-literal.tentative.html
index a7d5659e16a..a7d5659e16a 100644
--- a/tests/wpt/tests/trusted-types/trusted-types-from-literal.html
+++ b/tests/wpt/tests/trusted-types/trusted-types-from-literal.tentative.html
diff --git a/tests/wpt/tests/url/resources/urltestdata.json b/tests/wpt/tests/url/resources/urltestdata.json
index 69767a20db9..9f1be0449c6 100644
--- a/tests/wpt/tests/url/resources/urltestdata.json
+++ b/tests/wpt/tests/url/resources/urltestdata.json
@@ -735,6 +735,36 @@
"hash": ""
},
{
+ "input": "http://a:b@c\\",
+ "base": null,
+ "href": "http://a:b@c/",
+ "origin": "http://c",
+ "protocol": "http:",
+ "username": "a",
+ "password": "b",
+ "host": "c",
+ "hostname": "c",
+ "port": "",
+ "pathname": "/",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "ws://a@b\\c",
+ "base": null,
+ "href": "ws://a@b/c",
+ "origin": "ws://b",
+ "protocol": "ws:",
+ "username": "a",
+ "password": "",
+ "host": "b",
+ "hostname": "b",
+ "port": "",
+ "pathname": "/c",
+ "search": "",
+ "hash": ""
+ },
+ {
"input": "foo:/",
"base": "http://example.org/foo/bar",
"href": "foo:/",
diff --git a/tests/wpt/tests/webaudio/the-audio-api/the-oscillatornode-interface/osc-basic-waveform.html b/tests/wpt/tests/webaudio/the-audio-api/the-oscillatornode-interface/osc-basic-waveform.html
index abd1ff8d0e5..ce6e262fa9f 100644
--- a/tests/wpt/tests/webaudio/the-audio-api/the-oscillatornode-interface/osc-basic-waveform.html
+++ b/tests/wpt/tests/webaudio/the-audio-api/the-oscillatornode-interface/osc-basic-waveform.html
@@ -159,7 +159,7 @@
b1: 1,
prefix: 'Custom',
threshold: 5.1e-5,
- snrThreshold: 112.78
+ snrThreshold: 112.6
});
task.done();
});
diff --git a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/fragment_navigated/fragment_navigated.py b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/fragment_navigated/fragment_navigated.py
index a4bd012588d..fb690807f21 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/browsing_context/fragment_navigated/fragment_navigated.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/browsing_context/fragment_navigated/fragment_navigated.py
@@ -57,7 +57,7 @@ async def test_subscribe(bidi_session, subscribe_events, url, new_tab, wait_for_
assert_navigation_info(event, {"context": new_tab["context"], "url": target_url})
-async def test_timestamp(bidi_session, current_time, subscribe_events, url, new_tab, wait_for_event):
+async def test_timestamp(bidi_session, current_time, subscribe_events, url, new_tab, wait_for_event, wait_for_future_safe):
await bidi_session.browsing_context.navigate(
context=new_tab["context"], url=url(EMPTY_PAGE), wait="complete"
)
diff --git a/tests/wpt/tests/webdriver/tests/bidi/integration/navigation.py b/tests/wpt/tests/webdriver/tests/bidi/integration/navigation.py
new file mode 100644
index 00000000000..23615040c78
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/integration/navigation.py
@@ -0,0 +1,67 @@
+import pytest
+
+from webdriver.error import TimeoutException
+from webdriver.bidi.error import UnknownErrorException
+from webdriver.bidi.modules.script import ContextTarget
+
+
+pytestmark = pytest.mark.asyncio
+
+NAVIGATION_STARTED_EVENT = "browsingContext.navigationStarted"
+FRAGMENT_NAVIGATED_EVENT = "browsingContext.fragmentNavigated"
+BEFORE_REQUEST_SENT_EVENT = "network.beforeRequestSent"
+
+async def test_navigate_history_replacestate_beforeunload(
+ bidi_session, inline, new_tab, subscribe_events
+):
+ url = inline("""
+ <script>
+ window.addEventListener(
+ 'beforeunload',
+ () => {
+ return history.replaceState(null, 'initial', window.location.href);
+ },
+ false
+ );
+ </script>""")
+
+ result = await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=url, wait="complete"
+ )
+
+ events = []
+
+ async def on_event(method, data):
+ events.append(method)
+
+ remove_navigation_started_listener = bidi_session.add_event_listener(
+ NAVIGATION_STARTED_EVENT, on_event
+ )
+
+ remove_fragment_navigated_listener = bidi_session.add_event_listener(
+ FRAGMENT_NAVIGATED_EVENT, on_event
+ )
+
+ remove_before_request_sent_listener = bidi_session.add_event_listener(
+ BEFORE_REQUEST_SENT_EVENT, on_event
+ )
+
+ await subscribe_events([NAVIGATION_STARTED_EVENT, FRAGMENT_NAVIGATED_EVENT, BEFORE_REQUEST_SENT_EVENT])
+
+ result = await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=url, wait="interactive"
+ )
+
+ # Navigation caused by browsing_context.navigate call should happen first:
+ # https://html.spec.whatwg.org/#beginning-navigation
+ # network.beforeRequestSent should arrive before the page becomes
+ # interactive.
+ assert events == [
+ NAVIGATION_STARTED_EVENT,
+ FRAGMENT_NAVIGATED_EVENT,
+ BEFORE_REQUEST_SENT_EVENT
+ ]
+
+ remove_navigation_started_listener()
+ remove_fragment_navigated_listener()
+ remove_before_request_sent_listener()
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/__init__.py b/tests/wpt/tests/webdriver/tests/bidi/storage/__init__.py
index 763e0054f1d..0d7cea96bce 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/storage/__init__.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/__init__.py
@@ -1,3 +1,4 @@
+from datetime import datetime, timedelta, timezone
from typing import Optional
from webdriver.bidi.modules.network import NetworkBytesValue, NetworkStringValue
from webdriver.bidi.modules.storage import PartialCookie, PartitionDescriptor
@@ -73,3 +74,17 @@ def create_cookie(
secure=secure,
same_site=same_site,
expiry=expiry)
+
+
+def generate_expiry_date(day_diff=1):
+ return (
+ (datetime.utcnow() + timedelta(days=day_diff))
+ .replace(microsecond=0)
+ .replace(tzinfo=timezone.utc)
+ )
+
+
+def format_expiry_string(date):
+ # same formatting as Date.toUTCString() in javascript
+ utc_string_format = "%a, %d %b %Y %H:%M:%S GMT"
+ return date.strftime(utc_string_format)
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/conftest.py b/tests/wpt/tests/webdriver/tests/bidi/storage/conftest.py
index 31b2c3f3e6b..0941411fab8 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/storage/conftest.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/conftest.py
@@ -1,7 +1,7 @@
-import pytest
-
from urllib.parse import urlunsplit
+import pytest
+
@pytest.fixture
def origin(server_config, domain_value):
@@ -9,11 +9,3 @@ def origin(server_config, domain_value):
return urlunsplit((protocol, domain_value(domain, subdomain), "", "", ""))
return origin
-
-
-@pytest.fixture
-def domain_value(server_config):
- def domain_value(domain="", subdomain=""):
- return server_config["domains"][domain][subdomain]
-
- return domain_value
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/__init__.py b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/__init__.py
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/filter.py b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/filter.py
new file mode 100644
index 00000000000..b244ef86ac2
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/filter.py
@@ -0,0 +1,559 @@
+import pytest
+from webdriver.bidi.modules.network import NetworkBase64Value, NetworkStringValue
+from webdriver.bidi.modules.storage import CookieFilter
+
+from .. import create_cookie, format_expiry_string, generate_expiry_date
+from ... import recursive_compare
+
+pytestmark = pytest.mark.asyncio
+
+
+@pytest.mark.parametrize(
+ "filter",
+ [
+ {"size": 6},
+ {"value": NetworkStringValue("bar")},
+ {"value": NetworkBase64Value("YmFy")},
+ ],
+)
+async def test_filter(
+ bidi_session, new_tab, test_page, domain_value, add_cookie, filter
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+ value_1 = "bar"
+
+ cookie1_name = "baz"
+ await add_cookie(new_tab["context"], cookie1_name, value_1)
+
+ cookie2_name = "foo"
+ await add_cookie(new_tab["context"], cookie2_name, value_1)
+
+ cookie3_name = "foo_3"
+ await add_cookie(new_tab["context"], cookie3_name, "bar_3")
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=filter,
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": value_1},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": value_1},
+ },
+ cookie_2,
+ )
+
+
+async def test_filter_domain(
+ bidi_session,
+ top_context,
+ new_tab,
+ test_page,
+ test_page_cross_origin,
+ domain_value,
+ add_cookie,
+):
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=test_page, wait="complete"
+ )
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page_cross_origin, wait="complete"
+ )
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await add_cookie(top_context["context"], cookie1_name, cookie1_value)
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await add_cookie(top_context["context"], cookie2_name, cookie2_value)
+
+ cookie3_name = "foo_2"
+ cookie3_value = "bar_2"
+ await add_cookie(new_tab["context"], cookie3_name, cookie3_value)
+ domain = domain_value()
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(domain=domain),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
+
+
+@pytest.mark.parametrize(
+ "expiry_diff_1, expiry_diff_2",
+ [
+ (1, 2),
+ (1, None),
+ ],
+)
+async def test_filter_expiry(
+ bidi_session,
+ new_tab,
+ test_page,
+ domain_value,
+ add_cookie,
+ expiry_diff_1,
+ expiry_diff_2,
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_expiry_date = generate_expiry_date(expiry_diff_1)
+ cookie1_expiry = int(cookie1_expiry_date.timestamp())
+ cookie1_date_string = format_expiry_string(cookie1_expiry_date)
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await add_cookie(
+ context=new_tab["context"],
+ name=cookie1_name,
+ value=cookie1_value,
+ expiry=cookie1_date_string,
+ )
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await add_cookie(
+ context=new_tab["context"],
+ name=cookie2_name,
+ value=cookie2_value,
+ expiry=cookie1_date_string,
+ )
+
+ cookie3_name = "foo_3"
+ if expiry_diff_2 is None:
+ cookie2_date_string = None
+ else:
+ cookie2_expiry_date = generate_expiry_date(expiry_diff_2)
+ cookie2_date_string = format_expiry_string(cookie2_expiry_date)
+
+ await add_cookie(
+ new_tab["context"], cookie3_name, "bar_3", expiry=cookie2_date_string
+ )
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(expiry=cookie1_expiry),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "expiry": cookie1_expiry,
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "expiry": cookie1_expiry,
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
+
+
+async def test_filter_name(bidi_session, new_tab, test_page, domain_value, add_cookie):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "foo"
+ cookie1_value = "bar"
+ await add_cookie(new_tab["context"], cookie1_name, cookie1_value)
+
+ cookie2_name = "foo_2"
+ await add_cookie(new_tab["context"], cookie2_name, "bar_2")
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter={"name": "foo"},
+ )
+
+ recursive_compare(
+ {
+ "cookies": [
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ }
+ ],
+ "partitionKey": {},
+ },
+ cookies,
+ )
+
+
+@pytest.mark.parametrize(
+ "same_site_1, same_site_2",
+ [
+ ("none", "strict"),
+ ("lax", "none"),
+ ("strict", "none"),
+ ("lax", "strict"),
+ ("strict", "lax"),
+ ],
+)
+async def test_filter_same_site(
+ bidi_session, new_tab, test_page, domain_value, same_site_1, same_site_2, add_cookie
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await add_cookie(
+ new_tab["context"],
+ cookie1_name,
+ cookie1_value,
+ same_site=same_site_1,
+ )
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await add_cookie(
+ new_tab["context"],
+ cookie2_name,
+ cookie2_value,
+ same_site=same_site_1,
+ )
+
+ cookie3_name = "foo_3"
+ await add_cookie(new_tab["context"], cookie3_name, "bar_3", same_site=same_site_2)
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(same_site=same_site_1),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": same_site_1,
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": same_site_1,
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
+
+
+@pytest.mark.parametrize(
+ "secure_1, secure_2",
+ [(True, False), (False, True)],
+)
+async def test_filter_secure(
+ bidi_session, new_tab, test_page, domain_value, add_cookie, secure_1, secure_2
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await add_cookie(
+ new_tab["context"],
+ cookie1_name,
+ cookie1_value,
+ secure=secure_1,
+ )
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await add_cookie(
+ new_tab["context"],
+ cookie2_name,
+ cookie2_value,
+ secure=secure_1,
+ )
+
+ cookie3_name = "foo_3"
+ await add_cookie(new_tab["context"], cookie3_name, "bar_3", secure=secure_2)
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(secure=secure_1),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": secure_1,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": secure_1,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
+
+
+@pytest.mark.parametrize(
+ "path_1, path_2",
+ [
+ ("/webdriver/tests/support", "/"),
+ ("/", None),
+ ("/webdriver", "/webdriver/tests"),
+ ],
+)
+async def test_filter_path(
+ bidi_session,
+ new_tab,
+ test_page,
+ domain_value,
+ add_cookie,
+ path_1,
+ path_2,
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await add_cookie(
+ new_tab["context"],
+ cookie1_name,
+ cookie1_value,
+ path=path_1,
+ )
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await add_cookie(
+ new_tab["context"],
+ cookie2_name,
+ cookie2_value,
+ path=path_1,
+ )
+
+ cookie3_name = "foo_3"
+ await add_cookie(new_tab["context"], cookie3_name, "bar_3", path=path_2)
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(path=path_1),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": path_1,
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": path_1,
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
+
+
+@pytest.mark.parametrize(
+ "http_only_1, http_only_2",
+ [(True, False), (False, True)],
+)
+async def test_filter_http_only(
+ bidi_session, new_tab, test_page, domain_value, set_cookie, http_only_1, http_only_2
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "bar"
+ cookie1_value = "foo"
+ await set_cookie(
+ cookie=create_cookie(
+ domain=domain_value(),
+ name=cookie1_name,
+ value=NetworkStringValue(cookie1_value),
+ http_only=http_only_1,
+ )
+ )
+
+ cookie2_name = "foo"
+ cookie2_value = "bar"
+ await set_cookie(
+ cookie=create_cookie(
+ domain=domain_value(),
+ name=cookie2_name,
+ value=NetworkStringValue(cookie2_value),
+ http_only=http_only_1,
+ )
+ )
+
+ cookie3_name = "foo_2"
+ cookie3_value = "bar_2"
+ await set_cookie(
+ cookie=create_cookie(
+ domain=domain_value(),
+ name=cookie3_name,
+ value=NetworkStringValue(cookie3_value),
+ http_only=http_only_2,
+ )
+ )
+
+ cookies = await bidi_session.storage.get_cookies(
+ filter=CookieFilter(http_only=http_only_1),
+ )
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["name"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": http_only_1,
+ "name": cookie1_name,
+ "path": "/",
+ "sameSite": "none",
+ "secure": True,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_1,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": http_only_1,
+ "name": cookie2_name,
+ "path": "/",
+ "sameSite": "none",
+ "secure": True,
+ "size": 6,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_2,
+ )
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/invalid.py b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/invalid.py
new file mode 100644
index 00000000000..fbd5647f303
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/invalid.py
@@ -0,0 +1,155 @@
+import pytest
+import webdriver.bidi.error as error
+from webdriver.bidi.modules.network import NetworkBase64Value, NetworkStringValue
+from webdriver.bidi.modules.storage import (
+ BrowsingContextPartitionDescriptor,
+ CookieFilter,
+ StorageKeyPartitionDescriptor,
+)
+
+pytestmark = pytest.mark.asyncio
+
+
+@pytest.mark.parametrize("value", [False, 42, "foo", []])
+async def test_params_filter_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=value)
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_filter_domain_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(domain=value))
+
+
+@pytest.mark.parametrize("value", [False, "foo", {}, [], -1, 0.5])
+async def test_params_filter_expiry_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(expiry=value))
+
+
+@pytest.mark.parametrize("value", ["foo", {}, [], 42])
+async def test_params_filter_http_only_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(http_only=value))
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_filter_name_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(name=value))
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_filter_path_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(path=value))
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_filter_same_site_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(same_site=value))
+
+
+@pytest.mark.parametrize("value", ["", "INVALID_SAME_SITE_STATE"])
+async def test_params_filter_same_site_invalid_value(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(same_site=value))
+
+
+@pytest.mark.parametrize("value", ["foo", {}, [], 42])
+async def test_params_filter_secure_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(secure=value))
+
+
+@pytest.mark.parametrize("value", [False, "foo", {}, [], -1, 0.5])
+async def test_params_filter_size_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(size=value))
+
+
+@pytest.mark.parametrize("value", [False, 42, "foo", []])
+async def test_params_filter_value_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(filter=CookieFilter(value=value))
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_filter_value_type_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ filter=CookieFilter(value={"type": value})
+ )
+
+
+async def test_params_filter_value_type_invalid_value(bidi_session):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ filter=CookieFilter(value={"type": "foo"})
+ )
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_filter_value_base64_type_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ filter=CookieFilter(value=NetworkBase64Value(value))
+ )
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_filter_value_string_type_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ filter=CookieFilter(value=NetworkStringValue(value))
+ )
+
+
+@pytest.mark.parametrize("value", [False, 42, "foo", []])
+async def test_params_partition_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(partition=value)
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_partition_type_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(partition={"type": value})
+
+
+async def test_params_partition_type_invalid_value(bidi_session):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(partition={"type": "foo"})
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_partition_context_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ partition=BrowsingContextPartitionDescriptor(context=value)
+ )
+
+
+async def test_partition_invalid_context(bidi_session):
+ with pytest.raises(error.NoSuchFrameException):
+ await bidi_session.storage.get_cookies(
+ partition=BrowsingContextPartitionDescriptor("foo")
+ )
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_partition_source_origin_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ partition=StorageKeyPartitionDescriptor(source_origin=value)
+ )
+
+
+@pytest.mark.parametrize("value", [False, 42, {}, []])
+async def test_params_partition_user_context_invalid_type(bidi_session, value):
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.storage.get_cookies(
+ partition=StorageKeyPartitionDescriptor(user_context=value)
+ )
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/partition.py b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/partition.py
new file mode 100644
index 00000000000..a1c26503525
--- /dev/null
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/get_cookies/partition.py
@@ -0,0 +1,258 @@
+import pytest
+
+from webdriver.bidi.modules.network import NetworkStringValue
+from webdriver.bidi.modules.storage import (
+ BrowsingContextPartitionDescriptor,
+ StorageKeyPartitionDescriptor,
+)
+
+from .. import create_cookie
+from ... import recursive_compare
+
+pytestmark = pytest.mark.asyncio
+
+
+async def test_default_partition(
+ bidi_session,
+ top_context,
+ new_tab,
+ test_page,
+ test_page_cross_origin,
+ domain_value,
+ add_cookie,
+):
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=test_page_cross_origin, wait="complete"
+ )
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ cookie1_name = "foo"
+ cookie1_value = "bar"
+ await add_cookie(new_tab["context"], cookie1_name, cookie1_value)
+
+ cookie2_name = "foo_2"
+ cookie2_value = "bar_2"
+ await add_cookie(top_context["context"], cookie2_name, cookie2_value)
+
+ cookies = await bidi_session.storage.get_cookies()
+
+ assert cookies["partitionKey"] == {}
+ assert len(cookies["cookies"]) == 2
+ # Provide consistent cookies order.
+ (cookie_1, cookie_2) = sorted(cookies["cookies"], key=lambda c: c["domain"])
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie1_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie1_value},
+ },
+ cookie_2,
+ )
+ recursive_compare(
+ {
+ "domain": domain_value("alt"),
+ "httpOnly": False,
+ "name": cookie2_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 10,
+ "value": {"type": "string", "value": cookie2_value},
+ },
+ cookie_1,
+ )
+
+
+async def test_partition_context(
+ bidi_session,
+ new_tab,
+ test_page,
+ domain_value,
+ add_cookie,
+ create_user_context,
+ test_page_cross_origin,
+):
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=test_page, wait="complete"
+ )
+
+ user_context = await create_user_context()
+ # Create a new browsing context in another user context.
+ new_context = await bidi_session.browsing_context.create(
+ user_context=user_context, type_hint="tab"
+ )
+ await bidi_session.browsing_context.navigate(
+ context=new_context["context"], url=test_page_cross_origin, wait="complete"
+ )
+
+ cookie_name = "foo"
+ cookie_value = "bar"
+ await add_cookie(new_tab["context"], cookie_name, cookie_value)
+
+ # Check that added cookies are present on the right context.
+ cookies = await bidi_session.storage.get_cookies(
+ partition=BrowsingContextPartitionDescriptor(new_tab["context"])
+ )
+
+ # `partitionKey` here might contain `sourceOrigin` for certain browser implementation,
+ # so use `recursive_compare` to allow additional fields to be present.
+ recursive_compare({"partitionKey": {}}, cookies)
+
+ assert len(cookies["cookies"]) == 1
+ recursive_compare(
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie_name,
+ "path": "/webdriver/tests/support",
+ "sameSite": "none",
+ "secure": False,
+ "size": 6,
+ "value": {"type": "string", "value": cookie_value},
+ },
+ cookies["cookies"][0],
+ )
+
+ # Check that added cookies are not present on the context in the other user context.
+ cookies = await bidi_session.storage.get_cookies(
+ partition=BrowsingContextPartitionDescriptor(new_context["context"])
+ )
+
+ # `partitionKey` here might contain `sourceOrigin` for certain browser implementation,
+ # so use `recursive_compare` to allow additional fields to be present.
+ recursive_compare({"partitionKey": {}}, cookies)
+ assert len(cookies["cookies"]) == 0
+
+
+@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
+async def test_partition_context_iframe(
+ bidi_session, new_tab, inline, domain_value, domain, set_cookie
+):
+ iframe_url = inline("<div id='in-iframe'>foo</div>", domain=domain)
+ page_url = inline(f"<iframe src='{iframe_url}'></iframe>")
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=page_url, wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=new_tab["context"])
+ iframe_context = contexts[0]["children"][0]
+
+ cookie_name = "foo"
+ cookie_value = "bar"
+ await set_cookie(
+ cookie=create_cookie(
+ domain=domain_value(domain),
+ name=cookie_name,
+ value=NetworkStringValue(cookie_value),
+ ),
+ partition=BrowsingContextPartitionDescriptor(iframe_context["context"]),
+ )
+
+ # Check that added cookies are present on the right context
+ cookies = await bidi_session.storage.get_cookies(
+ partition=BrowsingContextPartitionDescriptor(iframe_context["context"])
+ )
+
+ recursive_compare(
+ {
+ "cookies": [
+ {
+ "domain": domain_value(domain=domain),
+ "httpOnly": False,
+ "name": cookie_name,
+ "path": "/",
+ "sameSite": "none",
+ "secure": True,
+ "size": 6,
+ "value": {"type": "string", "value": cookie_value},
+ }
+ ],
+ "partitionKey": {},
+ },
+ cookies,
+ )
+
+
+@pytest.mark.parametrize(
+ "protocol",
+ [
+ "http",
+ "https",
+ ],
+)
+async def test_partition_source_origin(
+ bidi_session,
+ new_tab,
+ top_context,
+ inline,
+ test_page_cross_origin,
+ domain_value,
+ origin,
+ set_cookie,
+ protocol,
+):
+ url = inline("<div>bar</div>", protocol=protocol)
+ await bidi_session.browsing_context.navigate(
+ context=new_tab["context"], url=url, wait="complete"
+ )
+ source_origin_1 = origin(protocol)
+
+ cookie_name = "foo"
+ cookie_value = "bar"
+ await set_cookie(
+ cookie=create_cookie(
+ domain=domain_value(),
+ name=cookie_name,
+ value=NetworkStringValue(cookie_value),
+ ),
+ partition=StorageKeyPartitionDescriptor(source_origin=source_origin_1),
+ )
+
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=test_page_cross_origin, wait="complete"
+ )
+ source_origin_2 = origin(domain="alt")
+
+ # Check that added cookies are present on the right origin
+ cookies = await bidi_session.storage.get_cookies(
+ partition=StorageKeyPartitionDescriptor(source_origin=source_origin_1)
+ )
+
+ recursive_compare(
+ {
+ "cookies": [
+ {
+ "domain": domain_value(),
+ "httpOnly": False,
+ "name": cookie_name,
+ "path": "/",
+ "sameSite": "none",
+ "secure": True,
+ "size": 6,
+ "value": {"type": "string", "value": cookie_value},
+ }
+ ],
+ "partitionKey": {"sourceOrigin": source_origin_1},
+ },
+ cookies,
+ )
+
+ # Check that added cookies are present on the other origin.
+ cookies = await bidi_session.storage.get_cookies(
+ partition=StorageKeyPartitionDescriptor(source_origin=source_origin_2)
+ )
+
+ recursive_compare(
+ {
+ "cookies": [],
+ "partitionKey": {"sourceOrigin": source_origin_2},
+ },
+ cookies,
+ )
diff --git a/tests/wpt/tests/webdriver/tests/bidi/storage/set_cookie/invalid.py b/tests/wpt/tests/webdriver/tests/bidi/storage/set_cookie/invalid.py
index 24f6153402d..53d2573575b 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/storage/set_cookie/invalid.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/storage/set_cookie/invalid.py
@@ -1,12 +1,18 @@
import pytest
from .. import create_cookie
import webdriver.bidi.error as error
-from webdriver.bidi.modules.network import NetworkStringValue
+from webdriver.bidi.modules.network import NetworkBase64Value, NetworkStringValue
from webdriver.bidi.modules.storage import BrowsingContextPartitionDescriptor, StorageKeyPartitionDescriptor
pytestmark = pytest.mark.asyncio
+@pytest.mark.parametrize("cookie", [None, False, 42, "foo", []])
+async def test_cookie_invalid_type(set_cookie, cookie):
+ with pytest.raises(error.InvalidArgumentException):
+ await set_cookie(cookie=cookie)
+
+
@pytest.mark.parametrize("domain", [None, False, 42, {}, []])
async def test_cookie_domain_invalid_type(set_cookie, test_page, domain):
with pytest.raises(error.InvalidArgumentException):
@@ -70,6 +76,14 @@ async def test_cookie_value_string_invalid_type(set_cookie, test_page, domain_va
await set_cookie(cookie=create_cookie(domain=domain_value(), value=value))
+@pytest.mark.parametrize("base64", [None, False, 42, {}, []])
+async def test_cookie_value_base64_invalid_type(set_cookie, domain_value, base64):
+ value = NetworkBase64Value(base64)
+
+ with pytest.raises(error.InvalidArgumentException):
+ await set_cookie(cookie=create_cookie(domain=domain_value(), value=value))
+
+
@pytest.mark.parametrize("partition", [42, False, "SOME_STRING_VALUE", {}, {"type": "SOME_INVALID_TYPE"}, []])
async def test_partition_invalid_type(set_cookie, test_page, domain_value, partition):
with pytest.raises(error.InvalidArgumentException):
@@ -108,9 +122,5 @@ async def test_partition_storage_key_user_context_invalid_type(set_cookie, test_
with pytest.raises(error.InvalidArgumentException):
await set_cookie(cookie=create_cookie(domain=domain_value()), partition=partition)
-# TODO: test `test_cookie_domain_invalid_value`.
# TODO: test `test_partition_storage_key_user_context_unknown`.
# TODO: test `test_partition_storage_key_user_context_invalid_type`.
-# TODO: test `test_cookie_value_missing`.
-# TODO: test `test_cookie_value_base64_invalid_type`.
-# TODO: test `test_cookie_value_base64_invalid_value`.
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 547152b2a72..924a4e8d797 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
@@ -108,7 +108,7 @@ def test_read_element_text(session, inline):
("cheese", "<slot><span style=\"display: none\">foo</span>bar</slot>", "cheese"),
("", "<slot><span>foo</span>bar</slot>", "foobar"),
("", "<slot><span>foo</span></slot>bar", "foobar"),
- ("", "<slot><span style=\"display: none\">foo</span>bar</slot>", "bar"),
+ ("", "<slot><span style='display: none'>foo</span>bar</slot>", "bar"),
], ids=[
"custom visible",
"custom outside",
diff --git a/tests/wpt/tests/webdriver/tests/support/fixtures_bidi.py b/tests/wpt/tests/webdriver/tests/support/fixtures_bidi.py
index 177bdda160e..9566e6ebd19 100644
--- a/tests/wpt/tests/webdriver/tests/support/fixtures_bidi.py
+++ b/tests/wpt/tests/webdriver/tests/support/fixtures_bidi.py
@@ -461,3 +461,70 @@ async def create_user_context(bidi_session):
# Ignore exceptions in case a specific user context was already
# removed during the test.
pass
+
+
+@pytest_asyncio.fixture
+async def add_cookie(bidi_session):
+ """
+ Add a cookie with `document.cookie` and remove them after the test is finished.
+ """
+ cookies = []
+
+ async def add_cookie(
+ context,
+ name,
+ value,
+ domain=None,
+ expiry=None,
+ path=None,
+ same_site="none",
+ secure=False,
+ ):
+ cookie_string = f"{name}={value}"
+ cookie = {"name": name, "context": context}
+
+ if domain is not None:
+ cookie_string += f";domain={domain}"
+
+ if expiry is not None:
+ cookie_string += f";expires={expiry}"
+
+ if path is not None:
+ cookie_string += f";path={path}"
+ cookie["path"] = path
+
+ if same_site != "none":
+ cookie_string += f";SameSite={same_site}"
+
+ if secure is True:
+ cookie_string += ";Secure"
+
+ await bidi_session.script.evaluate(
+ expression=f"document.cookie = '{cookie_string}'",
+ target=ContextTarget(context),
+ await_promise=True,
+ )
+
+ cookies.append(cookie)
+
+ yield add_cookie
+
+ for cookie in reversed(cookies):
+ cookie_string = f"""{cookie["name"]}="""
+
+ if "path" in cookie:
+ cookie_string += f""";path={cookie["path"]}"""
+
+ await bidi_session.script.evaluate(
+ expression=f"""document.cookie = '{cookie_string};Max-Age=0'""",
+ target=ContextTarget(cookie["context"]),
+ await_promise=True,
+ )
+
+
+@pytest.fixture
+def domain_value(server_config):
+ def domain_value(domain="", subdomain=""):
+ return server_config["domains"][domain][subdomain]
+
+ return domain_value
diff --git a/tests/wpt/tests/webdriver/tests/support/helpers.py b/tests/wpt/tests/webdriver/tests/support/helpers.py
index 9870643b3d9..678733e951f 100644
--- a/tests/wpt/tests/webdriver/tests/support/helpers.py
+++ b/tests/wpt/tests/webdriver/tests/support/helpers.py
@@ -1,6 +1,7 @@
import collections
import math
import sys
+from urllib.parse import urlparse
import webdriver
@@ -252,6 +253,11 @@ def filter_supported_key_events(all_events, expected):
return (events, expected)
+def get_origin_from_url(url):
+ parsed_uri = urlparse(url)
+ return '{uri.scheme}://{uri.netloc}'.format(uri=parsed_uri)
+
+
def wait_for_new_handle(session, handles_before):
def find_new_handle(session):
new_handles = list(set(session.handles) - set(handles_before))
diff --git a/tests/wpt/tests/webhid/resources/automation.js b/tests/wpt/tests/webhid/resources/automation.js
deleted file mode 100644
index f7477d1eccf..00000000000
--- a/tests/wpt/tests/webhid/resources/automation.js
+++ /dev/null
@@ -1,42 +0,0 @@
-'use strict';
-
-let fakeHidService = undefined;
-
-function hid_test(func, name, properties) {
- promise_test(async (test) => {
- assert_implements(navigator.hid, 'missing navigator.hid');
- if (fakeHidService === undefined) {
- // Try loading a polyfill for the fake hid service.
- if (isChromiumBased) {
- const fakes = await import('/resources/chromium/fake-hid.js');
- fakeHidService = fakes.fakeHidService;
- }
- }
- assert_implements(
- fakeHidService, 'missing fakeHidService after initialization');
-
- fakeHidService.start();
- try {
- await func(test, fakeHidService);
- } finally {
- fakeHidService.stop();
- fakeHidService.reset();
- }
- }, name, properties);
-}
-
-function trustedClick() {
- return new Promise(resolve => {
- let button = document.createElement('button');
- button.textContent = 'click to continue test';
- button.style.display = 'block';
- button.style.fontSize = '20px';
- button.style.padding = '10px';
- button.onclick = () => {
- document.body.removeChild(button);
- resolve();
- };
- document.body.appendChild(button);
- test_driver.click(button);
- });
-}
diff --git a/tests/wpt/tests/webrtc-extensions/RTCRtpParameters-codec.html b/tests/wpt/tests/webrtc-extensions/RTCRtpParameters-codec.html
index cce2c1661f7..5fc1401badf 100644
--- a/tests/wpt/tests/webrtc-extensions/RTCRtpParameters-codec.html
+++ b/tests/wpt/tests/webrtc-extensions/RTCRtpParameters-codec.html
@@ -1,6 +1,7 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>RTCRtpEncodingParameters codec property</title>
+<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../webrtc/RTCPeerConnection-helper.js"></script>
@@ -24,11 +25,11 @@
}
function findFirstCodec(name) {
- return RTCRtpSender.getCapabilities(name.split('/')[0]).codecs.filter(c => c.mimeType.localeCompare(name, undefined, { sensitivity: 'base' }) === 0)[0];
+ return RTCRtpReceiver.getCapabilities(name.split('/')[0]).codecs.filter(c => c.mimeType.localeCompare(name, undefined, { sensitivity: 'base' }) === 0)[0];
}
function codecsNotMatching(mimeType) {
- return RTCRtpSender.getCapabilities(mimeType.split('/')[0]).codecs.filter(c => c.mimeType.localeCompare(mimeType, undefined, {sensitivity: 'base'}) !== 0);
+ return RTCRtpReceiver.getCapabilities(mimeType.split('/')[0]).codecs.filter(c => c.mimeType.localeCompare(mimeType, undefined, {sensitivity: 'base'}) !== 0);
}
function assertCodecEquals(a, b) {
@@ -284,17 +285,22 @@
}, `Setting a non-existing codec on a video sender with setParameters should throw InvalidModificationError`);
promise_test(async t => {
- const pc = new RTCPeerConnection();
- t.add_cleanup(() => pc.close());
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
+ t.add_cleanup(() => pc2.close());
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonOpus);
+ };
- const transceiver = pc.addTransceiver('audio');
- const sender = transceiver.sender;
-
- transceiver.setCodecPreferences(nonOpus);
+ const transceiver = pc1.addTransceiver('audio');
+ exchangeIceCandidates(pc1, pc2);
+ await exchangeOfferAnswer(pc1, pc2);
+ const sender = transceiver.sender;
let param = sender.getParameters();
let encoding = param.encodings[0];
@@ -303,17 +309,22 @@
}, `Setting a non-preferred codec on an audio sender with setParameters should throw InvalidModificationError`);
promise_test(async t => {
- const pc = new RTCPeerConnection();
- t.add_cleanup(() => pc.close());
+ const pc1 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection();
+ t.add_cleanup(() => pc2.close());
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonVP8);
+ };
- const transceiver = pc.addTransceiver('video');
- const sender = transceiver.sender;
-
- transceiver.setCodecPreferences(nonVP8);
+ const transceiver = pc1.addTransceiver('video');
+ exchangeIceCandidates(pc1, pc2);
+ await exchangeOfferAnswer(pc1, pc2);
+ const sender = transceiver.sender;
let param = sender.getParameters();
let encoding = param.encodings[0];
@@ -329,15 +340,16 @@
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonOpus);
+ };
const transceiver = pc1.addTransceiver('audio');
- const sender = transceiver.sender;
-
- transceiver.setCodecPreferences(nonOpus);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
+ const sender = transceiver.sender;
let param = sender.getParameters();
let encoding = param.encodings[0];
@@ -353,15 +365,15 @@
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonVP8);
+ };
const transceiver = pc1.addTransceiver('video');
- const sender = transceiver.sender;
-
- transceiver.setCodecPreferences(nonVP8);
-
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
+ const sender = transceiver.sender;
let param = sender.getParameters();
let encoding = param.encodings[0];
@@ -391,7 +403,7 @@
assertCodecEquals(opus, encoding.codec);
- transceiver.setCodecPreferences(nonOpus);
+ pc2.getTransceivers()[0].setCodecPreferences(nonOpus);
await exchangeOfferAnswer(pc1, pc2);
param = sender.getParameters();
@@ -399,7 +411,6 @@
assert_equals(encoding.codec, undefined);
}, `Codec should be undefined after negotiating away the currently set codec on an audio sender`);
-
promise_test(async (t) => {
const pc1 = new RTCPeerConnection();
const pc2 = new RTCPeerConnection();
@@ -422,7 +433,7 @@
assertCodecEquals(vp8, encoding.codec);
- transceiver.setCodecPreferences(nonVP8);
+ pc2.getTransceivers()[0].setCodecPreferences(nonVP8);
await exchangeOfferAnswer(pc1, pc2);
param = sender.getParameters();
@@ -441,12 +452,13 @@
const opus = findFirstCodec('audio/opus');
const nonOpus = codecsNotMatching(opus.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonOpus.concat([opus]));
+ };
const transceiver = pc1.addTransceiver(stream.getTracks()[0]);
const sender = transceiver.sender;
- transceiver.setCodecPreferences(nonOpus.concat([opus]));
-
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
@@ -478,12 +490,13 @@
const vp8 = findFirstCodec('video/VP8');
const nonVP8 = codecsNotMatching(vp8.mimeType);
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences(nonVP8.concat([vp8]));
+ };
const transceiver = pc1.addTransceiver(stream.getTracks()[0]);
const sender = transceiver.sender;
- transceiver.setCodecPreferences(nonVP8.concat([vp8]));
-
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
@@ -514,15 +527,15 @@
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
const vp8 = findFirstCodec('video/VP8');
- const nonVP8 = codecsNotMatching(vp8.mimeType);
-
+ const h264 = findFirstCodec('video/H264');
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences([h264, vp8]);
+ };
const transceiver = pc1.addTransceiver(stream.getTracks()[0], {
sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}],
});
const sender = transceiver.sender;
- transceiver.setCodecPreferences(nonVP8.concat([vp8]));
-
exchangeIceCandidates(pc1, pc2);
await doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
@@ -559,15 +572,16 @@
t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
const vp8 = findFirstCodec('video/VP8');
- const nonVP8 = codecsNotMatching(vp8.mimeType);
+ const h264 = findFirstCodec('video/H264');
+ pc2.ontrack = e => {
+ e.transceiver.setCodecPreferences([h264, vp8]);
+ };
const transceiver = pc1.addTransceiver(stream.getTracks()[0], {
sendEncodings: [{rid: '0'}, {rid: '1'}, {rid: '2'}],
});
const sender = transceiver.sender;
- transceiver.setCodecPreferences(nonVP8.concat([vp8]));
-
exchangeIceCandidates(pc1, pc2);
await doOfferToSendSimulcastAndAnswer(pc1, pc2, ['0', '1', '2']);
diff --git a/tests/wpt/tests/webrtc-svc/RTCRtpParameters-scalability.html b/tests/wpt/tests/webrtc-svc/RTCRtpParameters-scalability.html
index ff28c2b5e95..134a28bd5e1 100644
--- a/tests/wpt/tests/webrtc-svc/RTCRtpParameters-scalability.html
+++ b/tests/wpt/tests/webrtc-svc/RTCRtpParameters-scalability.html
@@ -78,13 +78,17 @@
const param = transceiver.sender.getParameters();
const encoding = param.encodings[0];
assert_true('scalabilityMode' in encoding);
+
// If L3T3 is not supported at all, abort test.
assert_implements_optional(encoding.scalabilityMode === 'L3T3');
- // Pick a codec known to not have L3T3 support
- const capabilities = RTCRtpSender.getCapabilities('video');
- const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8');
- assert_true(codec !== undefined);
- transceiver.setCodecPreferences([codec]);
+
+ pc2.ontrack = e => {
+ // Pick a codec known to not have L3T3 support.
+ const capabilities = RTCRtpReceiver.getCapabilities('video');
+ const codec = capabilities.codecs.find(c => c.mimeType === 'video/VP8');
+ assert_true(codec !== undefined);
+ e.transceiver.setCodecPreferences([codec]);
+ }
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
const sendParams = pc1.getSenders()[0].getParameters();
diff --git a/tests/wpt/tests/webrtc-svc/svc-helper.js b/tests/wpt/tests/webrtc-svc/svc-helper.js
index e73ccfa7502..6a357f085bc 100644
--- a/tests/wpt/tests/webrtc-svc/svc-helper.js
+++ b/tests/wpt/tests/webrtc-svc/svc-helper.js
@@ -36,7 +36,9 @@ function createScalabilityTest(mimeType, scalabilityModes) {
const transceiver = pc1.addTransceiver(track1, {
sendEncodings: [{ scalabilityMode: scalabilityMode }],
});
- transceiver.setCodecPreferences(RTCRtpSender.getCapabilities('video').codecs.filter(c => c.mimeType == mimeType));
+ pc2.addEventListener('track', e => {
+ e.transceiver.setCodecPreferences(RTCRtpReceiver.getCapabilities('video').codecs.filter(c => c.mimeType == mimeType));
+ });
const haveTrackEvent = new Promise(r => pc2.ontrack = r);
exchangeIceCandidates(pc1, pc2);
await exchangeOfferAnswer(pc1, pc2);
diff --git a/tests/wpt/tests/webrtc/RTCDTMFSender-helper.js b/tests/wpt/tests/webrtc/RTCDTMFSender-helper.js
index 4316c3804a2..23465603f4d 100644
--- a/tests/wpt/tests/webrtc/RTCDTMFSender-helper.js
+++ b/tests/wpt/tests/webrtc/RTCDTMFSender-helper.js
@@ -117,10 +117,12 @@ function test_tone_change_events(testFunc, toneChanges, desc) {
assert_equals(dtmfSender.toneBuffer, expectedToneBuffer,
`Expect dtmfSender.toneBuffer to be updated to ${expectedToneBuffer}`);
- // We check that the cumulative delay is at least the expected one, but
- // system load may cause random delays, so we do not put any
- // realistic upper bound on the timing of the events.
- assert_between_inclusive(Date.now() - start, expectedTime,
+ // We check that the cumulative delay is at least the expected one.
+ // Note that as a UA optimization events can fire a bit (<1ms) early,
+ // and system load may cause random delays. We therefore allow events
+ // to be 1ms early and do not put any realistic expectation on the upper
+ // bound of their timing.
+ assert_between_inclusive(Date.now() - start, Math.max(0, expectedTime - 1),
expectedTime + 4000,
`Expect tonechange event for "${tone}" to be fired approximately after ${expectedTime} milliseconds`);
if (cumulativeToneChanges.length === 0) {
diff --git a/tests/wpt/tests/webrtc/RTCPeerConnection-helper.js b/tests/wpt/tests/webrtc/RTCPeerConnection-helper.js
index 5d188328e80..92e4ccfa43a 100644
--- a/tests/wpt/tests/webrtc/RTCPeerConnection-helper.js
+++ b/tests/wpt/tests/webrtc/RTCPeerConnection-helper.js
@@ -236,6 +236,11 @@ async function waitForIceGatheringState(pc, wantedStates) {
}
}
+async function waitForTrackUnmuted(track) {
+ if (track.muted === false) return true;
+ return waitUntilEvent(track, 'unmute');
+}
+
// Resolves when RTP packets have been received.
async function listenForSSRCs(t, receiver) {
while (true) {
@@ -646,7 +651,7 @@ function findTransceiverForSender(pc, sender) {
}
function preferCodec(transceiver, mimeType, sdpFmtpLine) {
- const {codecs} = RTCRtpSender.getCapabilities(transceiver.receiver.track.kind);
+ const {codecs} = RTCRtpReceiver.getCapabilities(transceiver.receiver.track.kind);
// sdpFmtpLine is optional, pick the first partial match if not given.
const selectedCodecIndex = codecs.findIndex(c => {
return c.mimeType === mimeType && (c.sdpFmtpLine === sdpFmtpLine || !sdpFmtpLine);
diff --git a/tests/wpt/tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html b/tests/wpt/tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
index d5acb7e1c93..9da03fe7a15 100644
--- a/tests/wpt/tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
+++ b/tests/wpt/tests/webrtc/RTCPeerConnection-setRemoteDescription-offer.html
@@ -4,6 +4,7 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
+<script src="/webrtc/third_party/sdp/sdp.js"></script>
<script>
'use strict';
@@ -303,8 +304,20 @@
t.add_cleanup(() => pc1.close());
t.add_cleanup(() => pc2.close());
await pc1.setLocalDescription(await pc1.createOffer());
+ const statePromise = new Promise(r => pc1.onsignalingstatechange = r);
+ // SRD with invalid SDP causes rollback.
const p = pc1.setRemoteDescription({type: 'offer', sdp: 'Invalid SDP'});
- await new Promise(r => pc1.onsignalingstatechange = r);
+ // Ensure that p is eventually awaited for
+ t.add_cleanup(async () => Promise.allSettled([p]));
+ // Ensure that the test will fail rather than timing out if state
+ // does not change.
+ const timeoutPromise = new Promise(
+ (resolve, reject) => t.step_timeout(reject, 1000));
+ try {
+ await Promise.any(statePromise, timeoutPromise);
+ } catch (error) {
+ assert_unreached('State should have changed');
+ }
assert_equals(pc1.signalingState, 'stable');
assert_equals(pc1.pendingLocalDescription, null);
assert_equals(pc1.pendingRemoteDescription, null);
@@ -353,4 +366,19 @@
assert_equals(pc2.getTransceivers().length, 1);
}, 'Transceivers added by sRD(offer) should not show up until sRD resolves');
+ promise_test(async t => {
+ const pc1 = new RTCPeerConnection();
+ const pc2 = new RTCPeerConnection();
+ t.add_cleanup(() => pc1.close());
+ t.add_cleanup(() => pc2.close());
+ pc1.addTransceiver('video');
+ const description = await pc1.createOffer();
+ const sections = SDPUtils.splitSections(description.sdp);
+ // Compose SDP with a duplicated media section (equal MSID lines)
+ // This is not permitted according to RFC 8830 section 2.
+ const sdp = sections[0] + sections[1] + sections[1].replace('a=mid:', 'a=mid:unique');
+ const p = pc2.setRemoteDescription({type: 'offer', sdp: sdp});
+ await promise_rejects_dom(t, 'OperationError', p);
+ }, 'setRemoteDescription(section with duplicate msid) rejects');
+
</script>
diff --git a/tests/wpt/tests/webrtc/RTCRtpReceiver-getStats.https.html b/tests/wpt/tests/webrtc/RTCRtpReceiver-getStats.https.html
index d9344b176e3..2fcf33dc2e4 100644
--- a/tests/wpt/tests/webrtc/RTCRtpReceiver-getStats.https.html
+++ b/tests/wpt/tests/webrtc/RTCRtpReceiver-getStats.https.html
@@ -24,6 +24,7 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await receiver.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'inbound-rtp'));
}, 'receiver.getStats() via addTransceiver should return stats report containing inbound-rtp stats');
@@ -40,8 +41,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(callee);
const receiver = callee.getReceivers()[0];
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await receiver.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'inbound-rtp'));
}, 'receiver.getStats() via addTrack should return stats report containing inbound-rtp stats');
@@ -58,8 +60,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(callee);
const [receiver] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const [transceiver] = callee.getTransceivers();
const statsPromiseFirst = receiver.getStats();
transceiver.stop();
@@ -81,8 +84,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(callee);
const [receiver] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReportFirst = await receiver.getStats();
callee.close();
const statsReportSecond = await receiver.getStats();
@@ -102,8 +106,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(callee);
const receiver = callee.getReceivers()[0];
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await receiver.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'candidate-pair'));
assert_true(!![...statsReport.values()].find(({type}) => type === 'local-candidate'));
diff --git a/tests/wpt/tests/webrtc/RTCRtpSender-getStats.https.html b/tests/wpt/tests/webrtc/RTCRtpSender-getStats.https.html
index 797365e9f4e..6aeed650e58 100644
--- a/tests/wpt/tests/webrtc/RTCRtpSender-getStats.https.html
+++ b/tests/wpt/tests/webrtc/RTCRtpSender-getStats.https.html
@@ -21,7 +21,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(caller);
+ const [ receiver ] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await sender.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
}, 'sender.getStats() via addTransceiver should return stats report containing outbound-rtp stats');
@@ -38,7 +40,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(caller);
+ const [ receiver ] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await sender.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
}, 'sender.getStats() via addTrack should return stats report containing outbound-rtp stats');
@@ -55,7 +59,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(caller);
+ const [ receiver ] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const [sender] = caller.getSenders();
const [transceiver] = caller.getTransceivers();
@@ -78,7 +84,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
+ const [ receiver ] = callee.getReceivers();
await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const [sender] = caller.getSenders();
const statsReportFirst = await sender.getStats();
caller.close();
@@ -99,7 +107,9 @@
exchangeIceCandidates(caller, callee);
await exchangeOfferAnswer(caller, callee);
- await listenToConnected(caller);
+ const [ receiver ] = callee.getReceivers();
+ await listenToConnected(callee);
+ await waitForTrackUnmuted(receiver.track);
const statsReport = await sender.getStats();
assert_true(!![...statsReport.values()].find(({type}) => type === 'candidate-pair'));
assert_true(!![...statsReport.values()].find(({type}) => type === 'local-candidate'));
diff --git a/tests/wpt/tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html b/tests/wpt/tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html
index f779f5a94ca..120b28527fb 100644
--- a/tests/wpt/tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html
+++ b/tests/wpt/tests/webrtc/RTCRtpTransceiver-setCodecPreferences.html
@@ -7,41 +7,13 @@
<script>
'use strict';
- // Test is based on the following editor draft:
- // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
-
- /*
- 5.4. RTCRtpTransceiver Interface
- interface RTCRtpTransceiver {
- ...
- void setCodecPreferences(sequence<RTCRtpCodecCapability> codecs);
- };
-
- setCodecPreferences
- - Setting codecs to an empty sequence resets codec preferences to any
- default value.
-
- - The codecs sequence passed into setCodecPreferences can only contain
- codecs that are returned by RTCRtpSender.getCapabilities(kind) or
- RTCRtpReceiver.getCapabilities(kind), where kind is the kind of the
- RTCRtpTransceiver on which the method is called. Additionally, the
- RTCRtpCodecParameters dictionary members cannot be modified. If
- codecs does not fulfill these requirements, the user agent MUST throw
- an InvalidModificationError.
- */
- /*
- * Chromium note: this requires build bots with H264 support. See
- * https://bugs.chromium.org/p/chromium/issues/detail?id=840659
- * for details on how to enable support.
- */
-
test((t) => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
transceiver.setCodecPreferences(capabilities.codecs);
- }, `setCodecPreferences() on audio transceiver with codecs returned from RTCRtpSender.getCapabilities('audio') should succeed`);
+ }, `setCodecPreferences() on audio transceiver with codecs returned from RTCRtpReceiver.getCapabilities('audio') should succeed`);
test((t) => {
const pc = new RTCPeerConnection();
@@ -55,15 +27,6 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities1 = RTCRtpSender.getCapabilities('audio');
- const capabilities2 = RTCRtpReceiver.getCapabilities('audio');
- transceiver.setCodecPreferences([...capabilities1.codecs, ... capabilities2.codecs]);
- }, `setCodecPreferences() with both sender receiver codecs combined should succeed`);
-
- test((t) => {
- const pc = new RTCPeerConnection();
- t.add_cleanup(() => pc.close());
- const transceiver = pc.addTransceiver('audio');
transceiver.setCodecPreferences([]);
}, `setCodecPreferences([]) should succeed`);
@@ -87,74 +50,64 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('video');
- const capabilities = RTCRtpSender.getCapabilities('video');
+ const capabilities = RTCRtpReceiver.getCapabilities('video');
const { codecs } = capabilities;
// This test verifies that the mandatory VP8 codec is present
- // and can be set.
- let tried = false;
- codecs.forEach(codec => {
- if (codec.mimeType.toLowerCase() === 'video/vp8') {
- transceiver.setCodecPreferences([codecs[0]]);
- tried = true;
- }
- });
- assert_true(tried, 'VP8 video codec was found and tried');
+ // and can be preferred.
+ const codec = codecs.find(c => c.mimeType === 'video/VP8');
+ assert_true(!!codec, 'VP8 video codec was found');
+ transceiver.setCodecPreferences([codec]);
}, `setCodecPreferences() with only VP8 should succeed`);
test(() => {
const pc = new RTCPeerConnection();
const transceiver = pc.addTransceiver('video');
- const capabilities = RTCRtpSender.getCapabilities('video');
+ const capabilities = RTCRtpReceiver.getCapabilities('video');
const { codecs } = capabilities;
// This test verifies that the mandatory H264 codec is present
- // and can be set.
- let tried = false;
- codecs.forEach(codec => {
- if (codec.mimeType.toLowerCase() === 'video/h264') {
- transceiver.setCodecPreferences([codecs[0]]);
- tried = true;
- }
- });
- assert_true(tried, 'H264 video codec was found and tried');
+ // and can be preferred.
+ const codec = codecs.find(c => c.mimeType === 'video/H264');
+ assert_true(!!codec, 'H264 video codec was found');
+ transceiver.setCodecPreferences([codec]);
}, `setCodecPreferences() with only H264 should succeed`);
async function getRTPMapLinesWithCodecAsFirst(firstCodec)
{
- const capabilities = RTCRtpSender.getCapabilities('video').codecs;
- capabilities.forEach((codec, idx) => {
+ const codecs = RTCRtpReceiver.getCapabilities('video').codecs;
+ codecs.forEach((codec, idx) => {
if (codec.mimeType === firstCodec) {
- capabilities.splice(idx, 1);
- capabilities.unshift(codec);
+ codecs.splice(idx, 1);
+ codecs.unshift(codec);
}
});
const pc = new RTCPeerConnection();
const transceiver = pc.addTransceiver('video');
- transceiver.setCodecPreferences(capabilities);
+ transceiver.setCodecPreferences(codecs);
const offer = await pc.createOffer();
- return offer.sdp.split('\r\n').filter(line => line.indexOf("a=rtpmap") === 0);
+ return offer.sdp.split('\r\n').filter(line => line.startsWith('a=rtpmap:'));
}
promise_test(async () => {
const lines = await getRTPMapLinesWithCodecAsFirst('video/H264');
assert_greater_than(lines.length, 1);
- assert_true(lines[0].indexOf("H264") !== -1, "H264 should be the first codec");
+ assert_true(lines[0].indexOf('H264') !== -1, 'H264 should be the first codec');
}, `setCodecPreferences() should allow setting H264 as first codec`);
promise_test(async () => {
const lines = await getRTPMapLinesWithCodecAsFirst('video/VP8');
assert_greater_than(lines.length, 1);
- assert_true(lines[0].indexOf("VP8") !== -1, "VP8 should be the first codec");
+ assert_true(lines[0].indexOf('VP8') !== -1, 'VP8 should be the first codec');
}, `setCodecPreferences() should allow setting VP8 as first codec`);
test((t) => {
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('video');
+ const capabilities = RTCRtpReceiver.getCapabilities('video');
assert_throws_dom('InvalidModificationError', () => transceiver.setCodecPreferences(capabilities.codecs));
}, `setCodecPreferences() on audio transceiver with codecs returned from getCapabilities('video') should throw InvalidModificationError`);
@@ -190,7 +143,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
const codecs = [
...capabilities.codecs,
{
@@ -207,7 +160,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
const codecs = [capabilities.codecs[0]];
codecs[0].clockRate = codecs[0].clockRate / 2;
@@ -218,7 +171,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
const codecs = [capabilities.codecs[0]];
codecs[0].channels = codecs[0].channels + 11;
@@ -229,7 +182,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
const codecs = [capabilities.codecs[0]];
codecs[0].sdpFmtpLine = "modifiedparameter=1";
@@ -240,7 +193,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const capabilities = RTCRtpSender.getCapabilities('audio');
+ const capabilities = RTCRtpReceiver.getCapabilities('audio');
const { codecs } = capabilities;
assert_greater_than(codecs.length, 0,
@@ -257,7 +210,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('audio');
- const {codecs} = RTCRtpSender.getCapabilities('audio');
+ const {codecs} = RTCRtpReceiver.getCapabilities('audio');
// Reorder codecs, put PCMU/PCMA first.
let firstCodec;
let i;
@@ -283,7 +236,7 @@
const pc = new RTCPeerConnection();
t.add_cleanup(() => pc.close());
const transceiver = pc.addTransceiver('video');
- const {codecs} = RTCRtpSender.getCapabilities('video');
+ const {codecs} = RTCRtpReceiver.getCapabilities('video');
// Reorder codecs, swap H264 and VP8.
let vp8 = -1;
let h264 = -1;
diff --git a/tests/wpt/tests/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js b/tests/wpt/tests/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js
index a516aa4c799..5cc3b745b3b 100644
--- a/tests/wpt/tests/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js
+++ b/tests/wpt/tests/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js
@@ -16,5 +16,5 @@ promise_test(async t => {
await openWebRTC(rc1);
// The page should not be eligible for BFCache because of open WebRTC connection and live MediaStreamTrack.
await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false);
- await assertNotRestoredFromBFCache(rc1, ['WebRTC', 'LiveMediaStreamTrack']);
+ await assertNotRestoredFromBFCache(rc1, ['webrtc', 'media-stream']);
});
diff --git a/tests/wpt/tests/webrtc/resources/webrtc-test-helpers.sub.js b/tests/wpt/tests/webrtc/resources/webrtc-test-helpers.sub.js
index 48882b30ccc..8a46302668a 100644
--- a/tests/wpt/tests/webrtc/resources/webrtc-test-helpers.sub.js
+++ b/tests/wpt/tests/webrtc/resources/webrtc-test-helpers.sub.js
@@ -62,18 +62,18 @@ const candidate = {
// Opens a new WebRTC connection.
async function openWebRTC(remoteContextHelper) {
await remoteContextHelper.executeScript(async (sessionDesc, candidate) => {
- const testRTCPeerConnection = new RTCPeerConnection();
- await testRTCPeerConnection.setRemoteDescription(sessionDesc);
- await testRTCPeerConnection.addIceCandidate(candidate);
+ window.testRTCPeerConnection = new RTCPeerConnection();
+ await window.testRTCPeerConnection.setRemoteDescription(sessionDesc);
+ await window.testRTCPeerConnection.addIceCandidate(candidate);
}, [sessionDesc, candidate]);
}
// Opens a new WebRTC connection and then close it.
async function openThenCloseWebRTC(remoteContextHelper) {
await remoteContextHelper.executeScript(async (sessionDesc, candidate) => {
- const testRTCPeerConnection = new RTCPeerConnection();
- await testRTCPeerConnection.setRemoteDescription(sessionDesc);
- await testRTCPeerConnection.addIceCandidate(candidate);
- testRTCPeerConnection.close();
+ window.testRTCPeerConnection = new RTCPeerConnection();
+ await window.testRTCPeerConnection.setRemoteDescription(sessionDesc);
+ await window.testRTCPeerConnection.addIceCandidate(candidate);
+ window.testRTCPeerConnection.close();
}, [sessionDesc, candidate]);
}
diff --git a/tests/wpt/tests/workers/same-site-cookies/first-party.all.tentative.https.window.js b/tests/wpt/tests/workers/same-site-cookies/first-party.all.tentative.https.window.js
index d7e5f2ee42c..ac6030e6540 100644
--- a/tests/wpt/tests/workers/same-site-cookies/first-party.all.tentative.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/first-party.all.tentative.https.window.js
@@ -1,19 +1,29 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (window) Set up listener for "DidStart" message and start worker.
-// Step 2 (worker) Send "DidStart" message to window.
-// Step 3 (window) Receive "DidStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (window) Set up listener for cookie message and start worker.
+// Step 3 (redirect) Redirect to worker script.
+// Step 4 (worker) Send cookie message to window.
+// Step 5 (window) Receive cookie message and cleanup.
async_test(t => {
// Step 1
- const worker = new SharedWorker("/workers/same-site-cookies/resources/worker.js", {sameSiteCookies: "all"});
- worker.port.onmessage = t.step_func(e => {
- // Step 3
- assert_equals(e.data, "DidStart", "Worker should have started");
- t.done();
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py", {sameSiteCookies: "all"});
+ worker.port.onmessage = t.step_func(e => {
+ // Step 5
+ getCookieNames().then(t.step_func((cookies) => {
+ assert_equals(e.data + cookies, "ReadOnLoad:StrictLaxNone,ReadOnFetch:StrictLaxNone,SetOnRedirectLoad:StrictLaxNone,SetOnLoad:StrictLaxNone,SetOnRedirectFetch:StrictLaxNone,SetOnFetch:StrictLaxNone", "Worker should get/set all cookies");
+ cookie_set_window.close();
+ t.done();
+ }));
+ });
});
}, "Check SharedWorker sameSiteCookies option all for first-party");
diff --git a/tests/wpt/tests/workers/same-site-cookies/first-party.default.tentative.https.window.js b/tests/wpt/tests/workers/same-site-cookies/first-party.default.tentative.https.window.js
index b120014c1a8..2c64ff628f5 100644
--- a/tests/wpt/tests/workers/same-site-cookies/first-party.default.tentative.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/first-party.default.tentative.https.window.js
@@ -1,19 +1,29 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (window) Set up listener for "DidStart" message and start worker.
-// Step 2 (worker) Send "DidStart" message to window.
-// Step 3 (window) Receive "DidStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (window) Set up listener for cookie message and start worker.
+// Step 3 (redirect) Redirect to worker script.
+// Step 4 (worker) Send cookie message to window.
+// Step 5 (window) Receive cookie message and cleanup.
async_test(t => {
// Step 1
- const worker = new SharedWorker("/workers/same-site-cookies/resources/worker.js");
- worker.port.onmessage = t.step_func(e => {
- // Step 3
- assert_equals(e.data, "DidStart", "Worker should have started");
- t.done();
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py");
+ worker.port.onmessage = t.step_func(e => {
+ // Step 5
+ getCookieNames().then(t.step_func((cookies) => {
+ assert_equals(e.data + cookies, "ReadOnLoad:StrictLaxNone,ReadOnFetch:StrictLaxNone,SetOnRedirectLoad:StrictLaxNone,SetOnLoad:StrictLaxNone,SetOnRedirectFetch:StrictLaxNone,SetOnFetch:StrictLaxNone", "Worker should get/set all cookies");
+ cookie_set_window.close();
+ t.done();
+ }));
+ });
});
}, "Check SharedWorker sameSiteCookies option default for first-party");
diff --git a/tests/wpt/tests/workers/same-site-cookies/first-party.none.tentative.https.window.js b/tests/wpt/tests/workers/same-site-cookies/first-party.none.tentative.https.window.js
index 762d924eb92..76a8b1d8bcb 100644
--- a/tests/wpt/tests/workers/same-site-cookies/first-party.none.tentative.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/first-party.none.tentative.https.window.js
@@ -1,19 +1,29 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (window) Set up listener for "DidStart" message and start worker.
-// Step 2 (worker) Send "DidStart" message to window.
-// Step 3 (window) Receive "DidStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (window) Set up listener for cookie message and start worker.
+// Step 3 (redirect) Redirect to worker script.
+// Step 4 (worker) Send cookie message to window.
+// Step 5 (window) Receive cookie message and cleanup.
async_test(t => {
// Step 1
- const worker = new SharedWorker("/workers/same-site-cookies/resources/worker.js", {sameSiteCookies: "none"});
- worker.port.onmessage = t.step_func(e => {
- // Step 3
- assert_equals(e.data, "DidStart", "Worker should have started");
- t.done();
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py", {sameSiteCookies: "none"});
+ worker.port.onmessage = t.step_func(e => {
+ // Step 5
+ getCookieNames().then(t.step_func((cookies) => {
+ assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only");
+ cookie_set_window.close();
+ t.done();
+ }));
+ });
});
}, "Check SharedWorker sameSiteCookies option none for first-party");
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies.py b/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies.py
new file mode 100644
index 00000000000..61b138321d0
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies.py
@@ -0,0 +1,13 @@
+import json
+from cookies.resources.helpers import makeCookieHeader, readCookies, setNoCacheAndCORSHeaders
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ cookies = readCookies(request)
+ headers.append(makeCookieHeader(b"samesite_strict_set_on_fetch", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax_set_on_fetch", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none_set_on_fetch", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ decoded_cookies = {isomorphic_decode(key): isomorphic_decode(val) for key, val in cookies.items()}
+ return headers, json.dumps(decoded_cookies)
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies_redirect.py b/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies_redirect.py
new file mode 100644
index 00000000000..0f3a647a2b8
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/get_cookies_redirect.py
@@ -0,0 +1,9 @@
+from cookies.resources.helpers import makeCookieHeader
+
+# Step 3/5 (workers/same-site-cookies/{})
+def main(request, response):
+ headers = [(b"Location", b"/workers/same-site-cookies/resources/get_cookies.py")]
+ headers.append(makeCookieHeader(b"samesite_strict_set_on_redirect_fetch", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax_set_on_redirect_fetch", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none_set_on_redirect_fetch", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ return 302, headers, b""
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/iframe-iframe.html b/tests/wpt/tests/workers/same-site-cookies/resources/iframe-iframe.html
index 0c5582176d4..efd4f3a6546 100644
--- a/tests/wpt/tests/workers/same-site-cookies/resources/iframe-iframe.html
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/iframe-iframe.html
@@ -4,7 +4,7 @@
<script src="/resources/testdriver-vendor.js"></script>
<body>
<script>
-// Step 3 (workers/same-site-cookies/third-party.{})
+// Step 4 (workers/same-site-cookies/third-party.{})
test_driver.set_test_context(window.top);
const type = (new URLSearchParams(window.location.search)).get("type");
let options = {};
@@ -18,9 +18,9 @@ switch (type) {
options.sameSiteCookies = "none";
break;
}
-// Step 5 (workers/same-site-cookies/third-party.{})
+// Step 7 (workers/same-site-cookies/third-party.{})
try {
- const worker = new SharedWorker("/workers/same-site-cookies/resources/worker.js", options);
+ const worker = new SharedWorker("/workers/same-site-cookies/resources/worker_redirect.py", options);
worker.port.onmessage = (e) => {
window.top.postMessage(e.data, "*");
};
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/iframe.sub.html b/tests/wpt/tests/workers/same-site-cookies/resources/iframe.sub.html
index 2531f3d6203..c4724d01d2f 100644
--- a/tests/wpt/tests/workers/same-site-cookies/resources/iframe.sub.html
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/iframe.sub.html
@@ -4,7 +4,7 @@
<script src="/resources/testdriver-vendor.js"></script>
<body>
<script>
-// Step 2 (workers/same-site-cookies/third-party.{})
+// Step 3 (workers/same-site-cookies/third-party.{})
test_driver.set_test_context(window.top);
const type = (new URLSearchParams(window.location.search)).get("type");
let iframe = document.createElement("iframe");
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/set_cookies.py b/tests/wpt/tests/workers/same-site-cookies/resources/set_cookies.py
new file mode 100644
index 00000000000..c721cc51f72
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/set_cookies.py
@@ -0,0 +1,10 @@
+from cookies.resources.helpers import makeCookieHeader, setNoCacheAndCORSHeaders
+
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ headers[0] = (b"Content-Type", b"text/html; charset=utf-8")
+ headers.append(makeCookieHeader(b"samesite_strict_set_before_load", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax_set_before_load", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none_set_before_load", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ document = b"<!DOCTYPE html>"
+ return headers, document \ No newline at end of file
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/util.js b/tests/wpt/tests/workers/same-site-cookies/resources/util.js
new file mode 100644
index 00000000000..67d9ee5c06b
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/util.js
@@ -0,0 +1,46 @@
+async function getCookieNames() {
+ const cookies = await test_driver.get_all_cookies();
+ const cookie_names = {};
+ cookies.forEach((element) => cookie_names[element["name"]] = true);
+ let message = ",SetOnRedirectLoad:";
+ if (cookie_names.hasOwnProperty("samesite_strict_set_on_redirect_load")) {
+ message += "Strict";
+ }
+ if (cookie_names.hasOwnProperty("samesite_lax_set_on_redirect_load")) {
+ message += "Lax";
+ }
+ if (cookie_names.hasOwnProperty("samesite_none_set_on_redirect_load")) {
+ message += "None";
+ }
+ message += ",SetOnLoad:";
+ if (cookie_names.hasOwnProperty("samesite_strict_set_on_load")) {
+ message += "Strict";
+ }
+ if (cookie_names.hasOwnProperty("samesite_lax_set_on_load")) {
+ message += "Lax";
+ }
+ if (cookie_names.hasOwnProperty("samesite_none_set_on_load")) {
+ message += "None";
+ }
+ message += ",SetOnRedirectFetch:";
+ if (cookie_names.hasOwnProperty("samesite_strict_set_on_redirect_fetch")) {
+ message += "Strict";
+ }
+ if (cookie_names.hasOwnProperty("samesite_lax_set_on_redirect_fetch")) {
+ message += "Lax";
+ }
+ if (cookie_names.hasOwnProperty("samesite_none_set_on_redirect_fetch")) {
+ message += "None";
+ }
+ message += ",SetOnFetch:";
+ if (cookie_names.hasOwnProperty("samesite_strict_set_on_fetch")) {
+ message += "Strict";
+ }
+ if (cookie_names.hasOwnProperty("samesite_lax_set_on_fetch")) {
+ message += "Lax";
+ }
+ if (cookie_names.hasOwnProperty("samesite_none_set_on_fetch")) {
+ message += "None";
+ }
+ return message;
+}
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/worker.js b/tests/wpt/tests/workers/same-site-cookies/resources/worker.js
deleted file mode 100644
index 658f499e92a..00000000000
--- a/tests/wpt/tests/workers/same-site-cookies/resources/worker.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Step 2/4 (workers/same-site-cookies/{})
-self.onconnect = (e) => {
- e.ports[0].postMessage("DidStart");
- self.close();
-}
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/worker.py b/tests/wpt/tests/workers/same-site-cookies/resources/worker.py
new file mode 100644
index 00000000000..8440c2d70ea
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/worker.py
@@ -0,0 +1,38 @@
+from cookies.resources.helpers import makeCookieHeader, readCookies, setNoCacheAndCORSHeaders
+
+# Step 4/6 (workers/same-site-cookies/{})
+def main(request, response):
+ headers = setNoCacheAndCORSHeaders(request, response)
+ headers[0] = (b"Content-Type", b"text/javascript")
+ headers.append(makeCookieHeader(b"samesite_strict_set_on_load", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax_set_on_load", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none_set_on_load", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ cookies = readCookies(request)
+ message = b"ReadOnLoad:"
+ if b"samesite_strict_set_before_load" in cookies:
+ message += b"Strict"
+ if b"samesite_lax_set_before_load" in cookies:
+ message += b"Lax"
+ if b"samesite_none_set_before_load" in cookies:
+ message += b"None"
+ document = b"""
+self.onconnect = (e) => {
+ fetch("/workers/same-site-cookies/resources/get_cookies_redirect.py", {credentials: 'include'}).then((resp) => {
+ resp.json().then((cookies) => {
+ let message = \"""" + message + b""",ReadOnFetch:";
+ if (cookies.hasOwnProperty("samesite_strict_set_before_load")) {
+ message += "Strict";
+ }
+ if (cookies.hasOwnProperty("samesite_lax_set_before_load")) {
+ message += "Lax";
+ }
+ if (cookies.hasOwnProperty("samesite_none_set_before_load")) {
+ message += "None";
+ }
+ e.ports[0].postMessage(message);
+ self.close();
+ });
+ });
+}
+"""
+ return headers, document
diff --git a/tests/wpt/tests/workers/same-site-cookies/resources/worker_redirect.py b/tests/wpt/tests/workers/same-site-cookies/resources/worker_redirect.py
new file mode 100644
index 00000000000..633a3ae67ef
--- /dev/null
+++ b/tests/wpt/tests/workers/same-site-cookies/resources/worker_redirect.py
@@ -0,0 +1,9 @@
+from cookies.resources.helpers import makeCookieHeader
+
+# Step 3/5 (workers/same-site-cookies/{})
+def main(request, response):
+ headers = [(b"Location", b"/workers/same-site-cookies/resources/worker.py")]
+ headers.append(makeCookieHeader(b"samesite_strict_set_on_redirect_load", b"test", {b"SameSite":b"Strict", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_lax_set_on_redirect_load", b"test", {b"SameSite":b"Lax", b"path":b"/", b"Secure":b""}))
+ headers.append(makeCookieHeader(b"samesite_none_set_on_redirect_load", b"test", {b"SameSite":b"None", b"path":b"/", b"Secure":b""}))
+ return 302, headers, b""
diff --git a/tests/wpt/tests/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js b/tests/wpt/tests/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js
index 51ad1d3b025..21b53819d93 100644
--- a/tests/wpt/tests/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/third-party.all.tentative.sub.https.window.js
@@ -1,24 +1,32 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (top-frame) Set up listener for "DidNotStart" message and open cross-site iframe.
-// Step 2 (sub-frame) Open iframe same-site to top-frame.
-// Step 3 (sub-sub-frame) Set up listener for message and start worker.
-// Step 4 (worker) Skipped.
-// Step 5 (sub-sub-frame) Worker failed to start and window messages "DidNotStart".
-// Step 6 (top-frame) Receive "DidNotStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (top-frame) Set up listener for "DidNotStart" message and open cross-site iframe.
+// Step 3 (sub-frame) Open iframe same-site to top-frame.
+// Step 4 (sub-sub-frame) Set up listener for message and start worker.
+// Step 5 (redirect) Skipped.
+// Step 6 (worker) Skipped.
+// Step 7 (sub-sub-frame) Worker failed to start and window messages "DidNotStart".
+// Step 8 (top-frame) Receive "DidNotStart" message and cleanup.
async_test(t => {
// Step 1
- window.addEventListener("message", t.step_func(e => {
- // Step 6
- assert_equals(e.data, "DidNotStart", "Worker should not have started");
- t.done();
- }));
- let iframe = document.createElement("iframe");
- iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=all";
- document.body.appendChild(iframe);
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ assert_equals(e.data, "DidNotStart", "Worker should not have started");
+ cookie_set_window.close();
+ t.done();
+ }));
+ let iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=all";
+ document.body.appendChild(iframe);
+ });
}, "Check SharedWorker sameSiteCookies option all for third-party");
diff --git a/tests/wpt/tests/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js b/tests/wpt/tests/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js
index 194df38390e..bf499c1992c 100644
--- a/tests/wpt/tests/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/third-party.default.tentative.sub.https.window.js
@@ -1,24 +1,34 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (top-frame) Set up listener for "DidStart" message and open cross-site iframe.
-// Step 2 (sub-frame) Open iframe same-site to top-frame.
-// Step 3 (sub-sub-frame) Set up listener for message and start worker.
-// Step 4 (worker) Send "DidStart" message to iframe.
-// Step 5 (sub-sub-frame) Receive message and pass on to window.
-// Step 6 (top-frame) Receive "DidStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (top-frame) Set up listener for cookie message and open cross-site iframe.
+// Step 3 (sub-frame) Open iframe same-site to top-frame.
+// Step 4 (sub-sub-frame) Set up listener for message and start worker.
+// Step 5 (redirect) Redirect to worker script.
+// Step 6 (worker) Send cookie message to iframe.
+// Step 7 (sub-sub-frame) Receive message and pass on to window.
+// Step 8 (top-frame) Receive cookie message and cleanup.
async_test(t => {
// Step 1
- window.addEventListener("message", t.step_func(e => {
- // Step 6
- assert_equals(e.data, "DidStart", "Worker should have started");
- t.done();
- }));
- let iframe = document.createElement("iframe");
- iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=default";
- document.body.appendChild(iframe);
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ getCookieNames().then(t.step_func((cookies) => {
+ assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only");
+ cookie_set_window.close();
+ t.done();
+ }));
+ }));
+ let iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=default";
+ document.body.appendChild(iframe);
+ });
}, "Check SharedWorker sameSiteCookies option default for third-party");
diff --git a/tests/wpt/tests/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js b/tests/wpt/tests/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js
index b91b9d7ab27..f00e585f778 100644
--- a/tests/wpt/tests/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js
+++ b/tests/wpt/tests/workers/same-site-cookies/third-party.none.tentative.sub.https.window.js
@@ -1,24 +1,34 @@
// META: script=/resources/testdriver.js
// META: script=/resources/testdriver-vendor.js
+// META: script=/workers/same-site-cookies/resources/util.js
'use strict';
// Here's the set-up for this test:
-// Step 1 (top-frame) Set up listener for "DidStart" message and open cross-site iframe.
-// Step 2 (sub-frame) Open iframe same-site to top-frame.
-// Step 3 (sub-sub-frame) Set up listener for message and start worker.
-// Step 4 (worker) Send "DidStart" message to iframe.
-// Step 5 (sub-sub-frame) Receive message and pass on to window.
-// Step 6 (top-frame) Receive "DidStart" message and cleanup.
+// Step 1 (window) Set cookies.
+// Step 2 (top-frame) Set up listener for cookie message and open cross-site iframe.
+// Step 3 (sub-frame) Open iframe same-site to top-frame.
+// Step 4 (sub-sub-frame) Set up listener for message and start worker.
+// Step 5 (redirect) Redirect to worker script.
+// Step 6 (worker) Send cookie message to iframe.
+// Step 7 (sub-sub-frame) Receive message and pass on to window.
+// Step 8 (top-frame) Receive cookie message and cleanup.
async_test(t => {
// Step 1
- window.addEventListener("message", t.step_func(e => {
- // Step 6
- assert_equals(e.data, "DidStart", "Worker should have started");
- t.done();
- }));
- let iframe = document.createElement("iframe");
- iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=none";
- document.body.appendChild(iframe);
+ const cookie_set_window = window.open("/workers/same-site-cookies/resources/set_cookies.py");
+ cookie_set_window.onload = t.step_func(_ => {
+ // Step 2
+ window.addEventListener("message", t.step_func(e => {
+ // Step 8
+ getCookieNames().then(t.step_func((cookies) => {
+ assert_equals(e.data + cookies, "ReadOnLoad:None,ReadOnFetch:None,SetOnRedirectLoad:None,SetOnLoad:None,SetOnRedirectFetch:None,SetOnFetch:None", "Worker should get/set SameSite=None cookies only");
+ cookie_set_window.close();
+ t.done();
+ }));
+ }));
+ let iframe = document.createElement("iframe");
+ iframe.src = "https://{{hosts[alt][]}}:{{ports[https][0]}}/workers/same-site-cookies/resources/iframe.sub.html?type=none";
+ document.body.appendChild(iframe);
+ });
}, "Check SharedWorker sameSiteCookies option none for third-party");